Mit der Erweiterungsmethode RegisterWithContext
registrieren Sie ein Prädikat, mit dem Sie eine Instanz anhand der Informationen über die konsumierende Komponente erstellen können. Diese Information wird dem Prädikat durch die Erweiterungsmethode geliefert.
Da dies bedeutet, dass Sie eine völlig andere Instanz pro konsumierenden Typ aufbauen können, was die Registrierung alles andere als flüchtig macht, könnte zu sehr merkwürdigem Verhalten führen. Stellen Sie sich zum Beispiel die Registrierung eines ILogger
Abstraktion, wo Sie eine Logger<T>
Implementierung schaffen, in dem die T
die Art der verbrauchenden Komponente ist:
container.RegisterWithContext(c =>
(ILogger).container.GetInstance(
typeof(Logger<>).MakeGenericType(c.ImplementationType)));
Wenn Sie diese Registrierung Singleton machen würde, dies zu Problemen führen würde, auch wenn die verzehr Komponenten sind Singleton, weil dieselbe Instanz in jeden Verbraucher injiziert wird; während jeder Verbraucher ihre eigene Instanz benötigen würde, weil sie ihre eigene geschlossene generische Version benötigen, nämlich: Logger<Consumer1>
, Logger<Consumer2>
, Logger<Consumer3>
usw. Stattdessen würde sehr Verbraucher dieselbe Instanz erhalten; die Instanz, die für den ersten aufgelösten Verbraucher erstellt wurde. Das ist offensichtlich schrecklich.
Das gleiche Problem wird auch bei der Verwendung von Scoped-Instanzen bestehen; Sie erhalten dieselbe Instanz für die Dauer des Bereichs, was normalerweise nicht Ihren Vorstellungen entspricht. Die Instanz sollte kontextabhängig sein.
Dies ist eine schwerwiegende Einschränkung der Erweiterungsmethode RegisterWithContext
, die mit der Dokumentation zu Simple Injector v2 geliefert wurde. Da dies zu einschränkend war, enthält Simple Injector v3 jetzt eine integrierte RegisterConditional
-Methode, die die Erweiterungsmethode RegisterWithContext
ersetzt. Die v3-Dokumente beziehen sich nie mehr auf RegisterWithContext
und wir empfehlen stattdessen RegisterWithContext
zu verwenden.
Die Dokumentation describes wie die RegisterConditional
und zeigt das folgende Beispiel zu verwenden:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
Da das Prädikat dieser Anmeldung true
zurückgibt, die Registrierung nicht wirklich bedingt ist, sondern einfach kontextuelle.
Mit diesem Code können Sie eine spezifische Logger<T>
für die konsumierende Komponente zurückgeben, aber immer noch sicherstellen, dass es höchstens eine Instanz von jedem geschlossenen Logger<T>
Typ gibt; also ein Singleton.
Der Hauptunterschied zwischen dem neuen RegisterConditional
und dem alten RegisterWithContext
besteht darin, dass Sie keinen Factory-Delegaten zum Erstellen von Instanzen bereitstellen können. Mit RegisterConditional
hat Simple Injector die Kontrolle über die Erstellung von Instanzen (anstelle Ihres Stellvertreters). Dies ermöglicht die Erstellung von Typen, die vollständig in die Pipeline integriert werden, und Simple Injector kann die registrierte Komponente und ihre Abhängigkeiten überprüfen und diagnostizieren.
Vielen Dank. Es ist sehr hilfreich. –