2016-06-21 6 views
0

Ich habe ein Szenario, wo ich zwei Klassen haben, nennen wir sie SingletonWorker und ScopedWorker, registriert mit Singleton und Scoped Lebensstile jeweils. Beide sind in ihrem Konstruktor auf IMetricSubmitter angewiesen. Die Mitarbeiter senden Metriken als Teil ihrer Logik unter Verwendung der IMetricSubmitter. Es gibt eine Singleton-Implementierung für IMetricSubmitter genannt DefaultMetricSubmitter, die ich mit EnrichMetricsDecorator zum Zweck der ScopedWorker Abhängigkeit dekorieren möchte, so dass SingletonWorker mit DefaultMetricSubmitter enden wird und ScopedWorker wird am Ende mit EnrichMetricsDecoratorDefaultMetricSubmitter Dekoration. Gibt es eine Möglichkeit, solche Registrierungen mit SimpleInjector heute zu erstellen?Wie können Dekoratoren mit dem Simple Injector konditionell basierend auf dem Lebensstil des Kunden registriert werden?

Die Objektgraphen wie folgt aussehen grundsätzlich sollte:

var singleton = new SingletonWorker(
    new DefaultMetricSubmitter()); 

var scoped = new ScopedWorker(
    new EnrichMetricsDecorator(
     new DefaultMetricSubmitter())); 

Für mich sieht es aus wie die RegisterConditional Kombination, die ein Prädikat hat, die über den Verbraucher weiß, mit RegisterDecorator, die die Art und Weise Dekorateure zu registrieren ist, aber Ich kenne keine Möglichkeit, die beiden zu kombinieren. Im Idealfall möchte ich den Decorator mit einer Bedingung registrieren, die darauf basiert, ob ein aktiver Bereich vorhanden ist, wenn dieser als Abhängigkeit für einen konsumierenden Konstruktor angefordert wird, und in diesem Fall die Dekoratorinstanz für diesen aktiven Bereich erstellt. Zum Zweck der Debatte kann der Geltungsbereich als LifetimeScope angenommen werden.

Antwort

1

Was Sie tun möchten, ist nicht möglich mit den RegisterDecorator Methoden. Stattdessen müssen Sie die Methoden RegisterConditional verwenden. Unter Berücksichtigung Ihrer gegebenen Objektgraphen, sollten diese Eintragungen in etwa so aussehen:

container.Register<ScopedWorker>(Lifestyle.Scoped); 
container.Register<SingletonWorker>(Lifestyle.Singleton); 

container.RegisterConditional<IMetricSubmitter, EnrichMetricsDecorator>(
    Lifestyle.Scoped, 
    c => c.Consumer.ImplementationType == typeof(ScopedWorker)); 

container.RegisterConditional<IMetricSubmitter, DefaultMetricSubmitter>(
    Lifestyle.Singleton, 
    c => c.Consumer.ImplementationType == typeof(EnrichMetricsDecorator)); 

Diese Praxis here in der Dokumentation beschrieben ist.

UPDATE

Mit Ihrem aktualisierten Objektgraph (das schließt einen zusätzlichen Singleton Dekorateur), kann die Registrierung wie folgt aussehen:

// Useful helper method 
static bool InjectedInto<TConsumer>(PredicateContext c) => 
    c.Consumer.ImplementationType == typeof(TConsumer); 

container.Register<ScopedWorker>(Lifestyle.Scoped); 
container.Register<SingletonWorker>(Lifestyle.Singleton); 

container.RegisterConditional<IMetricSubmitter, DefaultMetricSubmitter>(
    Lifestyle.Singleton, 
    InjectedInto<CachingMetricSubmitterDecorator>); 

container.RegisterConditional<IMetricSubmitter, CachingMetricSubmitterDecorator>(
    Lifestyle.Singleton, 
    c=> !InjectedInto<ScopedWorker>(c)&&!InjectedInto<CachingMetricSubmitterDecorator>(c)); 

container.RegisterConditional<IMetricSubmitter, EnrichMetricsDecorator>(
    Lifestyle.Scoped, 
    InjectedInto<ScopedWorker>); 
+0

Gemäß der Dokumentation dieser Registrierung wird nicht das haben ' EnrichMetricsDecorator 'schmücken den Singleton' DefaultMetricsSubmitter', liege ich falsch? – Eldar

+0

Entschuldigung, ich habe es nicht gut gelesen. Sieht genau aus, was ich brauche, wird es überprüfen. Danke :) – Eldar

+0

Hallo Steven, Ihr Vorschlag funktioniert, aber ich habe ein bisschen komplizierter Objektgraph, wo es scheitert. Wenn Sie das obige Beispiel fortsetzen, sollte der 'DefaultMetricSubmitter' immer mit Singleton' CachingMetricSubmitterDecorator' dekoriert sein, und der 'CachingMetricSubmitterDecorator' sollte mit 'EnrichMetricsDecorator' dekoriert sein, basierend auf der Bedingung, dass der Consumer' Scoped' Lifestyle hat. So sollte der 'SingletonWorker' einen' CachingMetricSubmitterDecorator' erhalten, der einen 'DefaultMetricsSubmitter' schmückt. Wie soll ich das angehen? – Eldar

Verwandte Themen