簡答:是的。
較長答案:首先,在將類Foo被登記爲IFoo的實施簡單的情況下,構造函數的參數或Func<IFoo>
類型的屬性將自動被Autofac解決,無需額外的佈線。 Autofac將注入一個委託,在調用時基本執行container.Resolve<IFoo>()
。
在像您這樣的複雜情況下,返回的確切結果基於輸入參數,您可以執行以下兩項操作之一。首先,你可以註冊一個工廠方法,它的返回值提供參數分辨率:
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);
用Autofac替換這個工廠的優勢是什麼? – Steven
對不起,正如我在我對KeithS的回答的評論中提到的那樣,我希望會有一些AutoFac voodoo讓我避免切換。避免交換機的優點是什麼?我不知道......我似乎已經厭惡他們:( –
IoC不是魔術棒,你可以使用命名註冊,並且你可以移除開關,但最終總會有某種形式的開關邏輯,我的建議是:使用工廠堡壘,並在Autofac註冊工廠 – Steven