1

Wir versuchen, LightCore als Standard Service Locator in unser Metadaten-/ORM-Framework zu integrieren. Daher möchten wir einige Standard-Registrierungen innerhalb des Frameworks, die ein Framework-Benutzer (= Application Developer) mit seinen eigenen Implementierungen "überstimmen" kann (wenn er das überhaupt möchte). Wie sollte das mit den LightCore IoC-Containern oder anderen IoC-Containern gemacht werden?LightCore ServiceLocator mit Mehrfachregistrierung zum selben Vertrag

Was wir versuchen:

var builder = new ContainerBuilder(); 
builder.Register<Foo>().ControlledBy<SingletonLifecycle>(); 
builder.Register<Foo, Foo2>().ControlledBy<SingletonLifecycle>(); 

var container = builder.Build(); 

var foo = container.Resolve<Foo>(); 

Ich registrierte zwei Klassen als Vertrag für Foo. Mit dem obigen Code erhalten wir immer die ersten (Instanzen von Foo) zurückgegeben. Also kein Überreden hier. Übrigens: Wir mögen es, eine Instanz von Foo2 zu bekommen.

Wir änderten sie verwenden konkreten Klassen zu Schnittstellen:

var builder = new ContainerBuilder(); 
builder.Register<IFoo, Foo>().ControlledBy<SingletonLifecycle>(); 
builder.Register<IFoo, Foo2>().ControlledBy<SingletonLifecycle>(); 

var container = builder.Build(); 

var foo = container.Resolve<IFoo>(); 

In diesem Ort, den wir einen Entschluss exceptionn in Resolve <>() sagen erhalten, dass keine Registrierung gefunden werden konnte. Wenn wir die zweite "Register()" - Anweisung entfernen, funktioniert das so, wie wir eine Instanz von Foo bekommen.

Wir sind nicht sicher, ob wir einige allgemeine Konzepte verpasst haben. Funktioniert das mit anderen IoCs genauso? Was ist die empfohlene Vorgehensweise, um Registrierungen zu überschreiben/zu überschreiben?

Jede Hilfe zu diesem Thema wäre großartig - nicht nur für LightCore.

Aktualisierung: Ich habe einige Tests für das obige Szenario mit dem SimpleInjector IoC-Container eingerichtet. Mit diesem Container muss AllowOverridingRegistration = true im Konstruktor angegeben werden und es wird wie erwartet funktionieren. Es sieht also so aus, als ob LightCore diesen Anwendungsfall nicht korrekt unterstützt, andere jedoch.

Update: Wir haben eine schnelle Antwort vom Schöpfer Lightcore sagte, dass LigtCore nicht zwingende Registrierungen überhaupt nicht unterstützt. Es scheint also keine Möglichkeit zu geben, diese Szenarioregistrierung mit LightCore zu umgehen, weshalb wir von LightCore zu SimpleInjector wechselten.

Die folgende SimpleInjector Konfiguration entspricht unsere vier aktuellen Anforderungen:

// Register concrete class for FooFoo 
    container.RegisterSingle<FooFoo>(); 

    // Register concrete classes for Foo - Final registration should return FooFoo, not Foo 
    container.RegisterSingle<Foo>(); 
    container.RegisterSingle<Foo, FooFoo>(); 

    // Register interfaces for IFoo - Final registration should return FooFoo, not Foo 
    container.RegisterSingle<IFoo, Foo>(); 
    container.RegisterSingle<IFoo, FooFoo>(); 

    // Register list of Plugs 
    container.RegisterAll(new IPlug[] { new PlugA(), new PlugB() }); 

Cheers, Marc

Antwort

1

AFAIK all große DI-Frameworks (Autofac, Einheitlichkeit, Schloss Windsor, StructureMap, Ninject) verfügt über Funktionen für das Überschreiben Registrierungen. Die meisten von ihnen erlauben dies, indem sie mehrere Registrierungen für den gleichen Servicetyp vornehmen und eine der Registrierungen als Standard auswählen. Welche Instanz sie auswählen, unterscheidet sich je nach Framework. Während einige Frameworks die erste von mehreren Registrierungen auswählen, wählen andere die letzte Registrierung. Zu wissen, wie der Rahmen der Wahl ist, ist dies wichtig, da dies bestimmt, ob Sie die "übergeordnete" Instanz vor oder nach allen anderen registrieren sollten.

Da alle diese Frameworks eine andere Überladungsauflösung haben, entschied ich mich, den Simple Injector standardmäßig nicht überschreiben zu lassen (obwohl es konfigurierbar ist, wie Sie bereits bemerkt haben). Dies erleichtert die Migration zu einem anderen Framework, was eines der Entwurfsziele des Simple Injectors war. Zulassen, dass Registrierungen standardmäßig überschrieben werden, kann jedoch auch eine Quelle von Konfigurationsfehlern sein, die zeitraubend sein können.Da Simple Injector einfach zu starten sein sollte, war es sinnvoll, das Überschreiben zu verbieten (standardmäßig).

Mit Simple Injector, wenn AllowOverridingRegistration aktiviert ist, ersetzt eine neue Registrierung wirklich eine frühere Registrierung für den gleichen Typ. Dies unterscheidet sich von den anderen Containern, die normalerweise die anderen Registrierungen behalten, und ermöglicht es Ihnen, alle Registrierungen als eine einzige Sammlung aufzulösen. Mit Simple Injector muss eine Sammlung von Dingen separat registriert und separat überschrieben werden.

Über alle anderen Behälter neben dem einfachen Injektor und den großen kann ich nicht viel sagen. Ich denke jedoch, dass das Übersteuern mit den meisten von ihnen schwer zu tun sein wird.

+1

Wir haben den Standard-Container LightCore durch SimpleInjector ersetzt und es scheint unsere Bedürfnisse zu erfüllen. ;) – Marc

+0

Werfen Sie einen Blick auf diese Frage: http://stackoverflow.com/questions/9852407/how-to-write-libraries-without-forcing-users-to-use-the-librarys-ioc-container. Und schauen Sie sich an, wie die Enterprise Library das macht. Standardmäßig verwendet es Unity, aber der Container kann ausgetauscht werden. – Steven