Câu trả lời ngắn gọn: Có.
Câu trả lời dài hơn: Đầu tiên, trong trường hợp đơn giản khi một lớp Foo được đăng ký để thực hiện cho IFoo, tham số hàm xây dựng hoặc thuộc tính loại Func<IFoo>
sẽ tự động được giải quyết bởi Autofac. Autofac sẽ tiêm một đại biểu về cơ bản thực hiện container.Resolve<IFoo>()
khi được gọi.
Trong trường hợp phức tạp hơn như trường hợp của bạn, nơi mà sự phản xạ chính xác được trả về dựa trên các thông số đầu vào, bạn có thể thực hiện một trong hai điều. Trước tiên, bạn có thể đăng ký một phương pháp nhà máy như giá trị trả về của nó để cung cấp một giải pháp tham số:
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))
Đây không phải là loại an toàn (domInstance sẽ không được biên dịch kiểm tra để đảm bảo nó là một IHtml), cũng không phải rất dọn dẹp. Thay vào đó, một giải pháp khác là để thực sự đăng ký phương pháp nhà máy như một 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");
}
}
Nếu bạn muốn giữ các mã trong ElementFactory thay vì đặt nó trong module Autofac, bạn có thể làm cho phương thức tĩnh và đăng ký đó (điều này đặc biệt hữu ích trong trường hợp của bạn vì phương pháp nhà máy của bạn được tạo ra không đáng kể):
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);
Lợi thế của việc thay thế nhà máy này bằng Autofac là gì? – Steven
Xin lỗi, như tôi đã ám chỉ trong nhận xét của tôi về câu trả lời của KeithS, tôi đã hy vọng sẽ có một số voodoo AutoFac cho phép tôi tránh việc chuyển đổi. Lợi thế của việc tránh chuyển đổi là gì? I dunno ... Tôi dường như đã được truyền bá với một sự ác cảm với họ: ( –
IoC không phải là cây đũa thần. Bạn có thể sử dụng tên đăng ký, và bạn có thể loại bỏ công tắc, nhưng cuối cùng sẽ luôn có một số loại Lời khuyên của tôi: sử dụng một nhà máy pháo đài của mình và đăng ký các nhà máy trong Autofac – Steven