2016-04-12 12 views
4

Ich habe IServiceHandler und ein ISalesHandler und beide erben von IhandlerSchnittstelle Vererbung gibt

IHandler.cs

public interface IHandler 
{ 
    Task AddAsync(IEnumerable<IDictionary<string, object>> toAdd, int dataFileId); 
    Task AddAuditAsync(IEnumerable<IDictionary<string, object>> toAdd, int dataFileId); 
} 

IServiceHandler.cs

public interface IServiceHandler : IHandler 
{ 
    Task<IEnumerable<ACService>> GetAsync(); 
    Task<IEnumerable<ACServiceAudit>> GetAuditAsync(); 
} 

ISalesHandler.cs

public interface ISalesHandler : IHandler 
{ 
    Task<IEnumerable<ACSale>> GetAsync(); 
    Task<IEnumerable<ACSaleAudit>> GetAuditAsync(); 
} 

Dann habe ich eine Methode, die entweder die Verkäufe oder Service gibt, aber das Problem ist, ich es als IHandler

private IHandler CreateHandler(FileType type) 
{ 
    switch (type) 
    { 
     case FileType.Sales: 
      return _container.GetExportedValue<ISalesHandler>("Sales"); 
     case FileType.Service: 
      return _container.GetExportedValue<IServiceHandler>("Service"); 
     case FileType.None: 
      return null; 
    } 
    return null; 
} 

die nur bewirkt, dass ich kehre zurück Zugriff auf die Methoden in der IHandler und nicht in IServiceHandler oder ISalesHandler.

Wie kann ich die Schnittstellen so strukturieren, dass ich auf alle Methoden zugreifen kann? Ich würde lieber die CreateHandler Methode beibehalten.

+0

Wie würden Sie die Compiler erwarten wissen, welche Art zurückgeführt werden würde? Wenn ich 'CreateHandler (FileType.Sales)' nenne, wird der Compiler nicht durch den Methodenkörper schauen und wissen, dass das einen 'ISalesHandler' zurückgibt, und deshalb' GetAsync' einen 'Task >' zurückgibt .Grundsätzlich müssen Sie zwischen Informationen zur Kompilierzeit und Informationen zur Ausführungszeit unterscheiden. Der Wert des Parameters für CreateHandler ist die Ausführungszeitinformation und kann daher die Informationen zur Kompilierungszeit nicht beeinflussen. –

+0

Wahrscheinlich besser, wenn Sie sowohl die Schnittstelle und CreateHandler-Methoden generisch machen. Dann können Sie zurück, was Sie wollen, ohne eine Switch-Anweisung. – Baldrick

+0

Pass Typ Parameter zu Ihrer Createhandler Methode oder einfach (IHandler als IServiceHandler) –

Antwort

4

Tatsächlich geben Sie eine IHandler zurück, so dass die dort definierten Methoden ohne Casting zugänglich sind.

Ich denke, es ist möglich, all dies zu umgehen, indem Sie Generika verwenden, da es ein Muster in den herleitenden Handlern zu geben scheint.

Würde dies für Sie tun?

IHandler.cs:

public interface IHandler // I usually split the generic and non-generic methods 
{ 
    Task AddAsync(IEnumerable<IDictionary<string, object>> toAdd, int dataFileId); 
    Task AddAuditAsync(IEnumerable<IDictionary<string, object>> toAdd, int dataFileId); 
} 

public interface IHandler<TService, TServiceAudit> : IHandler 
{ 
    Task<IEnumerable<TService>> GetAsync(); 
    Task<IEnumerable<TServiceAudit>> GetAuditAsync(); 
} 

IServiceHandler.cs:

public interface IServiceHandler : IHandler<ACService, ACServiceAudit> 
{ } 

ISalesHandler.cs:

public interface ISalesHandler : IHandler<ACSale, ACSaleAudit> 
{ } 
+0

Vielen Dank für Ihre Antwort, krank schnell einen Blick, schnelle Frage also, wenn ich die Schnittstelle ändern, um wie Ihre aussehen, mache ich immer noch, rufen Sie es auf die gleiche Weise Ich hatte es in der CreateHandler-Methode. weil ich denke, wenn ich Ihandler zurückgebe, hätte ich das gleiche Problem? – R4nc1d

3

Was über die Verwendung einer generischen Schnittstelle?

public interface IServiceHandler<TSale, TAudit> : IHandler 
{ 
    Task<IEnumerable<TSale>> GetSaleAsync(); 
    Task<IEnumerable<TAudit>> GetAuditAsync(); 
} 

ich nur benennen Sie Ihre GetAsync() zu GetSaleAsync() deutlicher zu sein, aber es ist, wie Sie es wünschen. So kann Ihr Factory könnte die folgende Signatur haben:

private IServiceHandler<TSale, TAudit>CreateHandler(FileType type) 
Verwandte Themen