2011-01-08 5 views
1

In einer sehr sehr begrenzten Anzahl von Szenarien muss ich von einem unbekannten Typ (zur Kompilierzeit) auf eine Instanz des für diesen Typ registrierten Objekts gehen.Castle Windsor Schwach Typ Factory

Zum größten Teil, ich benutze Fabriken getippt und ich kenne den Typen I bei der Kompilierung lösen will ... so spritze ich ein Func<IMyType> in einen Konstruktor

... aber in dieser begrenzten Anzahl von Szenarien Um einen direkten Aufruf des Containers zu vermeiden (und somit Windsor aus der Bibliothek zu referenzieren, was ein Anti-Pattern ist, das ich vermeiden möchte), muss ich eine Func<Type,object> ... injizieren, die ich intern haben möchte container.Resolve (type) für den Type-Parameter des Func.

Hat jemand einige Vorschläge für den einfachsten/einfachsten Weg, dies einzurichten?

habe ich versucht, die folgenden, aber mit diesem Setup, ich am Ende ganz die regelmäßigen TypedFactoryFacility Umgehung auf die definitiv nicht das, was ich will:

Kernel.Register(Component.For(typeof (Func<Type, object>)).LifeStyle.Singleton.UsingFactoryMethod(
        (kernel, componentModel, creationContext) => 
         kernel.Resolve(/* not sure what to put here... */))); 

Vielen Dank im Voraus für jede Hilfe.

Antwort

3

, das einfach, wenn Sie, dass Sie sich daran erinnern registrieren Delegierte in Windsor als normale Komponenten:

Sie können dies auch über eine typisierte Fabrik (was der empfohlene Ansatz ist, wenn Sie transiente Komponenten über diese Fabrik auflösen möchten, wie die typisierte Fabrik das Scoping vorgibt) und eine custom selector tun.

container.Register(
     Component.For<YourSelector>(), 
     Component.For<Func<Type,object>>().Lifestyle.Transient 
      .AsFactory(x=>x.SelectedWith<YourSelector>()); 
+0

Ich entschied mich, eine Instanz eines einfachen IServiceProvider zu injizieren, der eine Func übernimmt. Gibt es irgendwelche Bedenken? – Jeff

+0

Wie unterscheidet sich das von der direkten Verwendung der Funktion? Bedenken beziehen sich auf das Leben. Denken Sie darüber nach, wann die Objekte, die Sie ziehen, freigegeben werden und wenn Sie keine Speicherlecks einführen. Das ist alles –

+0

Nicht anders, du hast Recht. – Jeff

0

Ich denke, Sie können die gemeinsame Service Locator für diese http://commonservicelocator.codeplex.com/ verwenden, die ich denke, Ayende schrieb die Unterstützung für Castle Windsor für http://ayende.com/blog/archive/2008/10/02/the-common-service-locator-library.aspx. Es bietet grundsätzlich eine Möglichkeit, eine Abhängigkeit zu lösen, ohne eine Abhängigkeit von dem bestimmten Container zu haben (z. B. Windsor/Ninject usw.). Sie haben am Ende eine Abhängigkeit vom gemeinsamen Service-Locator auf der Ebene, für die Sie auflösen, aber zumindest können Sie z. Windsor to Ninject auf Anwendungsebene, so dass es in verschiedenen Projekten verwendet werden kann.

zu initialisieren:

ServiceLocator.SetLocatorProvider(() => { return new WindsorServiceLocator(_container); }); 

wo _container Ihre IWindsorContainer ist, und dann Abhängigkeiten zu lösen:

ServiceLocator.Current.GetInstance<MyType>(); 

oder

ServiceLocator.Current.GetAllInstances<MyType>(); 
+2

Ich will nicht wirklich eine andere dll Abhängigkeit zu meinen Projekten hinzuzufügen ... und den Service Locator verwendet, ist generell eine schlechte Idee angesehen, da es nicht Ausdruckskraft zeigen sich in der Komponente Verwendung (IMHO). – Jeff