gpt4 book ai didi

c# - 用 AutoFac 替换工厂

转载 作者:可可西里 更新时间:2023-11-01 02:59:28 25 4
gpt4 key购买 nike

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

public class ElementFactory
{
public IElement Create(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);
}
}

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

最佳答案

简短回答:是的。

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

在像您这样的更复杂的情况下,返回的确切具体取决于输入参数,您可以执行以下两项操作之一。首先,您可以注册一个工厂方法作为其返回值以提供参数化解析:

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))

这不是类型安全的(不会对 domInstance 进行编译器检查以确保它是 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");
}
}

如果您想将代码保留在 ElementFactory 中而不是将其放在 Autofac 模块中,您可以将工厂方法设为静态并注册它(这在您的情况下特别有效,因为您的工厂方法通常是静态的):

public class ElementFactory
{
public static IElement Create(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);
}
}

...

builder.Register<Func<IHtml, IElement>>(ElementFactory.Create);

关于c# - 用 AutoFac 替换工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18366762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com