2011-03-05 51 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