2014-07-21 81 views
0

我想我得到了關於依賴倒置和使用IoC容器的大部分內容,但有一點仍然不明顯。如何使用autofac自動執行下列工廠:什麼是使用autofac創建需要參數的對象的正確方法?

public class WidgetFactory 
{ 
    public static IWidget Create(int foo, double bar) 
    { 
     return new Widget(foo, bar); 
    } 
} 

public class Widget 
{ 
    private readonly int foo; 
    private readonly double bar; 

    public Widget(int foo, double bar) 
    { 
     this.foo = foo; 
     this.bar = bar; 
    } 
} 

別處......

public class FoobarUser 
{ 
    public void Method() 
    { 
     var widget = WidgetFactory.Create(3, 4.863); 
     // Do something with my widget 
     // Possibly add it to a widget collection 
    } 
} 

基本上,我需要成千上萬的小部件的創建和我不知道的最好的方式這樣做。我將如何使用autofac創建窗口部件工廠,以及如何在Method中使用該窗口工具,並記住該方法不包含對IContainer的引用?

回答

3

解決這個問題的方法是以下:

更改WidgetFactory以定義crea委託小部件:

public class WidgetFactory 
{ 
    public delegate IWidget Create(int firstParam, double secondParam); 
} 

在您的autofac模塊中,使用RegisterGeneratedFactory方法連接工廠。這會自動創建您的工廠你:

public class TestClassModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     base.Load(builder); 

     builder.RegisterType<Widget>().As<IWidget>(); 
     builder.RegisterGeneratedFactory<WidgetFactory.Create>(new TypedService(typeof(IWidget))); 

     builder.RegisterType<FoobarUser>(); 
    } 
} 

注入廠發展成爲FoobarUser:

public class FoobarUser 
{ 

    private readonly WidgetFactory.Create factory; 

    public FoobarUser(WidgetFactory.Create factory) 
    { 
     this.factory = factory; 
    } 

    public void Method() 
    { 
     var widget = this.factory(3, 4.836); 
     // Do something with my widget 
     // Possibly add it to a widget collection 
    } 
} 
0

您可以使用構造函數或屬性注入將依賴關係注入到工廠中,而不是將參數注入方法。如果您需要將特定值作爲參數注入到服務的構造函數中,則可以在註冊過程中將其設置爲類似於下面的代碼。

在這裏,我正從我的web.config一個XML文件的路徑,並通過該值進入我的倉庫的構造:

var builder = new ContainerBuilder(); 
var xmlFileName = HttpContext.Current.Server.MapPath(
    ConfigurationManager.AppSettings["xmlData"]); 

builder.Register(c => new XmlAdvertisementRepository(new XmlContext(xmlFileName))) 
    .AsImplementedInterfaces() 
    .InstancePerHttpRequest(); 
+0

的問題是,你不知道在編譯時的值將是什麼 - 它們是動態在運行時生成,應用程序一次可以使用數千個獨特的實例。 – Stephen

+0

如果他們不是依賴項(大多數情況下是服務),那麼你不會注入它們。像你創建的工廠方法似乎是適當的。 – agartee

2

基本上有兩種方式來處理參數:

  • 在註冊時 - 您可以使用lambda註冊(Register(c => T))提供它們,或者您可以將參數附加到基於反射(RegisterType<T>)的註冊。
  • 在解決時間 - 您可以將參數追加到Resolve<T>()調用,或者您可以使用委託工廠或Func<T>依賴關係來動態創建組件可以使用的工廠方法。

有所有這些選項穩健文檔與在Autofac文檔站點的例子在:

+0

這指出我在正確的方向,謝謝。 – Stephen

相關問題