2011-01-08 129 views
1

在非常非常有限的場景中,我需要從未知類型(在編譯時)轉到爲該類型註冊的對象實例。Castle Windsor Weak Typed Factory

在大多數情況下,我使用類型的工廠和我知道我想要在編譯時間解決這些類型...所以我注入Func<IMyType>成構造

...但是這限制了場景數,爲了避免直接調用容器(因此必須從庫中引用Windsor,這是我想避免的反模式),我需要注入一個Func<Type,object> ...我想在內部container.Resolve(type)爲Func的Type參數。

有沒有人有最簡單/最直接的方式來設置這個建議?

我嘗試以下,但這種設置,我最終完全繞過普通TypedFactoryFacility這絕對不是我想要的:事先的任何援助

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

感謝。

回答

3

如果你還記得,你可以註冊很簡單溫莎代表作爲正常組件:

container.Register(Component.For<Func<Type,object>>() 
    .Instance(t=>container.Resolve(t))); 

你也可以做到這一點通過類型化的工廠(這是推薦的方法,如果你打算通過這個工廠來解決短暫的組件,輸入工廠給你劃定範圍)和custom selector

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

我決定注入一個簡單的IServiceProvider實例,它需要一個Func 。有什麼擔憂嗎? – Jeff 2011-01-09 06:18:53

0

我認爲你可以使用這個http://commonservicelocator.codeplex.com/的公共服務定位器,我認爲Ayende寫了支持溫莎堡爲http://ayende.com/blog/archive/2008/10/02/the-common-service-locator-library.aspx。它基本上提供了一種解決依賴的方法,而不依賴於特定的容器(例如Windsor/Ninject等)。您最終會依賴於您正在解決的級別上的公共服務定位器,但至少您可以將其替換爲Windsor在應用程序級別注入Ninject,因此可用於不同的項目。

初始化:

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

其中_container是你IWindsorContainer,然後解決依賴關係:

ServiceLocator.Current.GetInstance<MyType>(); 

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

我真的不希望另一個DLL依賴添加到我的項目......並且使用了服務定位器通常被認爲是一個壞主意,因爲它沒有證明組件使用(恕我直言)表現。 – Jeff 2011-01-09 02:32:16