2013-03-14 24 views
15

Tôi đang cố gắng hiểu mẫu nhà sản xuất ủy nhiệm với Autofac. Tôi biết làm thế nào để thực hiện nhà máy sử dụng IIndex <> với Keyed() đăng ký, được giải thích độc đáo ở đây: Configuring an Autofac delegate factory that's defined on an abstract classNhà máy ủy quyền của Autofac bằng cách sử dụng func <>

Tôi muốn biết nếu tôi có thể tạo ra một nhà máy sử dụng Func <>, và làm thế nào tôi sẽ làm đăng ký mẫu sau:

public enum Service 
{ 
    Foo, 
    Bar 
} 

public interface FooService : IService 
{ 
    ServiceMethod(); 
} 

public interface BarService : IService 
{ 
    ServiceMethod(); 
} 

public class FooBarClient 
{ 
    private readonly IService service; 

    public FooBarClient(Func<Service, IService> service) 
    { 
     this.service = service(Service.Foo); 
    } 

    public void Process() 
    { 
     service.ServiceMethod(); // call the foo service. 
    } 
} 
+0

Tại sao bạn không chỉ cần sử dụng 'IIndex <>' với 'Keyed()'? Autofac không thể tạo 'Func ' này cho bạn. Bạn cần phải đăng ký nó trong thùng chứa của bạn bằng cách sử dụng 'Keyed()' hoặc 'Named()' giống như: 'builder.Register > (c => s => c.ResolveKeyed (s)) 'Các nhà máy ủy nhiệm chỉ có thể tạo một kiểu với các tham số và không chọn một kiểu dựa trên tham số vì đây là' IIndex <> 'cho. – nemesv

+2

Đối với IIndex <> tôi sẽ cần phải tham khảo thư viện Autofac mà tôi đang cố gắng tránh. Tôi muốn mã DI của tôi được trong Composite gốc (thư viện riêng biệt) chỉ khi có thể. –

Trả lời

16

Autofac không thể xây dựng Func<Service, IService> cho bạn cho phép bạn trả về các loại khác nhau dựa trên tham số. Đây là những gì IIndex<> dành cho.

Tuy nhiên nếu bạn không muốn/không thể sử dụng IIndex<> bạn có thể tạo chức năng nhà máy này với sự giúp đỡ của Keyed hoặc Named và đăng ký nhà máy của bạn trong container:

var builder = new ContainerBuilder(); 
builder.RegisterType<FooBarClient>().AsSelf(); 
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo); 
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar); 

builder.Register<Func<Service, IService>>(c => 
{ 
    var context = c.Resolve<IComponentContext>(); 
    return s => context.ResolveKeyed<IService>(s); 
}); 
+0

cảm ơn nemesv! nó hoạt động như mong đợi !!! jus một câu hỏi, sẽ có bất kỳ sự khác biệt trong hiệu suất - IIndex vs Func? –

+0

Tôi không biết làm thế nào IIndex được thực hiện và loại chaching hoặc tối ưu hóa hiệu suất nó có. Bạn có thể kiểm tra việc cấy ghép hoặc bạn cần thực hiện các kiểm tra hiệu suất được điều chỉnh cho kịch bản của bạn để so sánh hai. – nemesv

+2

Tôi chỉ thử rằng với phiên bản lý do, nhưng nó mang lại cho tôi một 'ObjectDisposedException' ... Tôi" giải quyết "điều này bằng cách gọi 'mới Foo' bên trong đại biểu (đó là một nogo biiiig!) –

Các vấn đề liên quan