2016-04-28 8 views
0

Ich habe eine Schnittstelle, die von einer anderenWie Instanz von Basis Schnittstelle mit einfachen Injektor lösen

public interface ISpecificHandler : IHandler 

mit einfachem Injector erbt registriere ich meine Art und Implementierung

container.RegisterSingleton<ISpecificHandler, SpecificHandlerImpl>(); 

Aber wie kann ich nur auflösen IHandler anstelle von ISpecificHandler?

//Expect SpecificHandlerImpl as handler 
IHandler handler = ServiceLocator.GetInstance<IHandler>(); //error 

Dies wirft ein InvalidOperationException, dass der IHandler Typ registriert ist nicht

+0

Warum möchten Sie das tun? Wie viele IHandler-Implementierungen haben Sie? – Steven

+0

Dies ist nur ein Beispielszenario. Wie auch immer, ich könnte mehrere Implementierungen haben. Wenn ich einen 'SpecificHandlerImpl' nach' IHandler' umwandeln kann, warum löse ich sie auch nicht durch einen IOC Container !? – mamuesstack

+0

"Warum nicht auch durch einen IOC-Container lösen !?". Denn das führt leicht zu Mehrdeutigkeit in Code und Design. Ohne genauer zu sein, kann Ihnen niemand wirklich sagen, wie Sie das am besten lösen können. Also schlage ich vor, die vollständigen 'IHandler'- und' ISpecificHandler'-Definitionen zu veröffentlichen, zu beschreiben, wie viele andere Implementierungen Sie haben und ein Beispiel zu zeigen, wie Sie diesen 'IHandler' erwarten. – Steven

Antwort

3

Es gibt mehrere Lösungen, aber es hängt wirklich davon ab, was Ihre Anwendung wirklich braucht. Hier sind ein paar Vorschläge.

Sie registrieren nur die Implementierung zweimal:

container.Register<IHandler, SpecificHandlerImpl>(Lifestyle.Scoped); 
container.Register<ISpecificHandler, SpecificHandlerImpl>(Lifestyle.Scoped); 

Aber vielleicht wollen Sie mehrere Handler zu lösen, wobei in diesem Fall haben Sie wahrscheinlich wird sie als eine Sammlung registrieren:

var reg1 = Lifestyle.Singleton.CreateRegistration<SpecificHandlerImpl>(); 
var reg2 = Lifestyle.Singleton.CreateRegistration<AnotherHandlerImpl>(); 

container.RegisterCollection<IHandler>(new[] { reg1, reg2 }); 

Das könnte dir Bei der Verwendung einer nicht generischen Schnittstelle IHandler treten jedoch Schwierigkeiten auf, da Sie normalerweise eine bestimmte Implementierung haben, die in einem bestimmten Szenario ausgeführt werden sollte (mit anderen Worten, Sie könnten die Liskov Substitution Principle verletzen). Daher wäre es oft besser, eine generische IHandler<T> Abstraktion zu verwenden, wobei T ein Parameterobjekt ist, das die Werte des Handlers enthält. In diesem Fall gibt es immer eine Eins-zu-Eins-Zuordnung zwischen einem geschlossenen IHandler<T> und einer Implementierung. This article gibt eine gute Erklärung der Vorteile eines solchen Designs.

Aber ohne das Problem zu kennen, das Sie zu lösen versuchen, ist es schwer zu sagen, was die richtige Lösung für Sie wäre.

+0

Danke Steven, jetzt bin ich neu in IOC Container und SimpleInjector. Der bereitgestellte Code ist nur ein Teil eines Testprojekts, um die SimpleInjector-Besonderheiten kennenzulernen. Aber jetzt erkannte ich, dass dieses Verhalten nicht umsetzungsspezifisch ist, sondern um Unsicherheit zu vermeiden – mamuesstack