2011-03-05 59 views
0

初學者問題: 給定兩個類:Myclass5和Myclass6如何可以在一個金屬絲向上以下工廠方法(返回爲函數功能) 使得 myclass5和myclass6實例和IMyClass它們依賴於經由所有檢索到的autofac(假設這三個實例已註冊)。Autofac佈線問題 - 初級

public static MyClass4 FactoryMethod(int nu) 
    { 
     if (nu == 1) 
      return new MyClass5(....); 
     if (nu == 4) 
      return new MyClass6(....); 

     throw new NotImplementedException(); 
    } 

public abstract class MyClass4 
{ 

} 

public class MyClass5 : MyClass4 
{ 
    public MyClass5(int nu, IMyClass a) 
    { 

    } 
} 

public class MyClass6 : MyClass4 
{ 
    public MyClass6(int nu, IMyClass a) 
    { 

    } 
} 

回答

3

對於FactoryMethod能夠創建實例,它需要訪問一個容器。我會建議爲工廠方法創建一個委託類型,這可以很容易地依賴它。註冊是這樣的:

var cb = new ContainerBuilder(); 
cb.RegisterType<SomeClass>().As<IMyClass>(); 
cb.RegisterType<MyClass5>(); 
cb.RegisterType<MyClass6>(); 
cb.Register((c, p) => 
    { 
     var context = c.Resolve<IComponentContext>(); 
     return new FactoryMethod(nu => 
      { 
       var nuParameter = TypedParameter.From(nu); 
       switch (nu) 
       { 
        case 1: 
         return context.Resolve<MyClass5>(nuParameter); 
        case 4: 
         return context.Resolve<MyClass6>(nuParameter); 
        default: 
         throw new NotImplementedException(); 
       } 
      }); 
     }); 

var container = cb.Build(); 

在解決時間,你就可以拿上FactoryMethod委託類型的依賴,並用它來解決實例:

var factory = container.Resolve<FactoryMethod>(); 
var instance5 = factory(1); 
var instance6 = factory(1); 

注:我們正在創建的委託實例需要一個上下文。我們不能直接使用c參數,因爲該上下文只是暫時的。因此,我們必須解決一個IComponentContext「烤」到lambda。

更新:如果您想提取工廠實現進入一個方法是不依賴於容器上,我建議如下:

public class FactoryMethodImpl 
    { 
     readonly Func<int, MyClass5> _factory5; 
     readonly Func<int, MyClass6> _factory6; 

     public FactoryMethodImpl(Func<int, MyClass5> factory5, Func<int, MyClass6> factory6) 
     { 
      _factory5 = factory5; 
      _factory6 = factory6; 
     } 

     public MyClass4 Create(int nu) 
     { 
      switch (nu) 
      { 
       case 1: 
        return _factory5(nu); 
       case 4: 
        return _factory6(nu); 
       default: 
        throw new NotImplementedException(); 
      } 
     } 
    } 

現在,註冊代碼改成這樣:

var cb = new ContainerBuilder(); 
cb.RegisterType<SomeClass>().As<IMyClass>(); 
cb.RegisterType<MyClass5>(); 
cb.RegisterType<MyClass6>(); 
cb.RegisterType<FactoryMethodImpl>().SingleInstance(); 
cb.Register(c=> new FactoryMethod(c.Resolve<FactoryMethodImpl>().Create)); 
+0

謝謝。看來,我別無選擇,只能創建FactoryMethod類型。但我想這個工廠方法是我的代碼的一部分,但如果我這樣做,那麼我將不得不在我的代碼中攜帶Autofacs IComponentContext。圍繞這種情況的任何工作? – GreatOrdinary 2011-03-06 17:55:19

+0

@ user645788:查看我更新的答案。我會說,與Autofac總是有一個選擇;) – 2011-03-06 21:14:16

+0

非常感謝...這太簡單了...不錯 – GreatOrdinary 2011-03-06 23:44:17