Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用AutoFac替换factory_C#_Autofac_Factory Pattern - Fatal编程技术网

C# 用AutoFac替换factory

C# 用AutoFac替换factory,c#,autofac,factory-pattern,C#,Autofac,Factory Pattern,我习惯于创建我自己的工厂,如图所示(为了便于说明,将其简化): 我终于开始在我当前的项目中使用IoC容器(AutoFac),我想知道是否有一些神奇的方法可以优雅地用AutoFac实现同样的功能?简短回答:是的 更详细的回答:首先,在简单的情况下,类Foo被注册为IFoo的实现,类型为Func的构造函数参数或属性将由Autofac自动解析,无需额外的连接。Autofac将注入一个委托,该委托在调用时基本上执行container.Resolve() 在像您这样更复杂的情况下,返回的具体化是基于输入参

我习惯于创建我自己的工厂,如图所示(为了便于说明,将其简化):

我终于开始在我当前的项目中使用IoC容器(AutoFac),我想知道是否有一些神奇的方法可以优雅地用AutoFac实现同样的功能?

简短回答:是的

更详细的回答:首先,在简单的情况下,类Foo被注册为IFoo的实现,类型为
Func
的构造函数参数或属性将由Autofac自动解析,无需额外的连接。Autofac将注入一个委托,该委托在调用时基本上执行
container.Resolve()

在像您这样更复杂的情况下,返回的具体化是基于输入参数的,您可以执行以下两种操作之一。首先,可以将factory方法注册为其返回值,以提供参数化解析:

builder.Register<IElement>((c, p) => {
    var dom= p.Named<IHtml>("dom");
    switch (dom.ElementType)
    {
        case "table":
            return new TableElement(dom);
        case "div":
            return new DivElement(dom);
        case "span":
            return new SpanElement(dom);
    }
    return new PassthroughElement(dom);
  });

//usage
container.Resolve<IElement>(new NamedParameter("dom", domInstance))
builder.Register((c,p)=>{
var dom=p.Named(“dom”);
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
});
//用法
container.Resolve(新名称参数(“dom”,domInstance))
这不是类型安全的(DominInstance不会被编译器检查以确保它是IHtml),也不是非常干净的。相反,另一种解决方案是将工厂方法实际注册为Func:

builder.Register<Func<IHtml, IElement>>(dom =>
{
    switch (dom.ElementType)
    {
        case "table":
            return new TableElement(dom);
        case "div":
            return new DivElement(dom);
        case "span":
            return new SpanElement(dom);
    }
    return new PassthroughElement(dom);
});


public class NeedsAnElementFactory //also registered in AutoFac
{
    protected Func<IHtml,IElement> CreateElement {get; private set;}

    //AutoFac will constructor-inject the Func you registered
    //whenever this class is resolved.
    public NeedsAnElementFactory(Func<IHtml,IElement> elementFactory)
    {
        CreateElement = elementFactory;
    }  

    public void MethodUsingElementFactory()
    {
        IHtml domInstance = GetTheDOM();

        var element = CreateElement(domInstance);

        //the next line won't compile;
        //the factory method is strongly typed to IHtml
        var element2 = CreateElement("foo");
    }
}
builder.Register(dom=>
{
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
});
公共类NeedsElementFactory//也在AutoFac中注册
{
受保护的Func CreateElement{get;private set;}
//AutoFac构造函数将注入您注册的Func
//每当该类被解析时。
公共需求元素工厂(Func元素工厂)
{
CreateElement=elementFactory;
}  
公共无效方法UsingElementFactory()
{
IHtml domInstance=gethedom();
var元素=CreateElement(domInstance);
//下一行不会编译;
//工厂方法是IHtml的强类型
var element2=CreateElement(“foo”);
}
}
如果希望将代码保留在ElementFactory中,而不是放在Autofac模块中,则可以将factory方法设置为静态并注册它(这在您的情况下尤其有效,因为factory方法基本上是静态的):

公共类元素工厂
{
公共静态IElement创建(IHtml dom)
{
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
}
}
...
builder.Register(ElementFactory.Create);
简短回答:是

更详细的回答:首先,在简单的情况下,类Foo被注册为IFoo的实现,类型为
Func
的构造函数参数或属性将由Autofac自动解析,无需额外的连接。Autofac将注入一个委托,该委托在调用时基本上执行
container.Resolve()

在像您这样更复杂的情况下,返回的具体化是基于输入参数的,您可以执行以下两种操作之一。首先,可以将factory方法注册为其返回值,以提供参数化解析:

builder.Register<IElement>((c, p) => {
    var dom= p.Named<IHtml>("dom");
    switch (dom.ElementType)
    {
        case "table":
            return new TableElement(dom);
        case "div":
            return new DivElement(dom);
        case "span":
            return new SpanElement(dom);
    }
    return new PassthroughElement(dom);
  });

//usage
container.Resolve<IElement>(new NamedParameter("dom", domInstance))
builder.Register((c,p)=>{
var dom=p.Named(“dom”);
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
});
//用法
container.Resolve(新名称参数(“dom”,domInstance))
这不是类型安全的(DominInstance不会被编译器检查以确保它是IHtml),也不是非常干净的。相反,另一种解决方案是将工厂方法实际注册为Func:

builder.Register<Func<IHtml, IElement>>(dom =>
{
    switch (dom.ElementType)
    {
        case "table":
            return new TableElement(dom);
        case "div":
            return new DivElement(dom);
        case "span":
            return new SpanElement(dom);
    }
    return new PassthroughElement(dom);
});


public class NeedsAnElementFactory //also registered in AutoFac
{
    protected Func<IHtml,IElement> CreateElement {get; private set;}

    //AutoFac will constructor-inject the Func you registered
    //whenever this class is resolved.
    public NeedsAnElementFactory(Func<IHtml,IElement> elementFactory)
    {
        CreateElement = elementFactory;
    }  

    public void MethodUsingElementFactory()
    {
        IHtml domInstance = GetTheDOM();

        var element = CreateElement(domInstance);

        //the next line won't compile;
        //the factory method is strongly typed to IHtml
        var element2 = CreateElement("foo");
    }
}
builder.Register(dom=>
{
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
});
公共类NeedsElementFactory//也在AutoFac中注册
{
受保护的Func CreateElement{get;private set;}
//AutoFac构造函数将注入您注册的Func
//每当该类被解析时。
公共需求元素工厂(Func元素工厂)
{
CreateElement=elementFactory;
}  
公共无效方法UsingElementFactory()
{
IHtml domInstance=gethedom();
var元素=CreateElement(domInstance);
//下一行不会编译;
//工厂方法是IHtml的强类型
var element2=CreateElement(“foo”);
}
}
如果希望将代码保留在ElementFactory中,而不是放在Autofac模块中,则可以将factory方法设置为静态并注册它(这在您的情况下尤其有效,因为factory方法基本上是静态的):

公共类元素工厂
{
公共静态IElement创建(IHtml dom)
{
开关(dom.ElementType)
{
案例“表格”:
返回新的TableElement(dom);
案件“div”:
返回新的DivElement(dom);
案例“span”:
返回新元素(dom);
}
返回新的PassthroughElement(dom);
}
}
...
生成器寄存器(ElementFactor)