2009-09-10 24 views
50

Do đăng ký sauAutofac: Giải quyết tất cả các trường hợp của một Loại

builder.Register<A>().As<I>(); 
builder.Register<B>().As<I>(); 
builder.Register<C>().As<I>(); 

var container = builder.Build(); 

tôi tìm cách để giải quyết tất cả các trường hợp của loại I như một IEnumerable (Mảng hoặc Bộ sưu tập nó không quan trọng).

Ở Windsor, tôi đã viết như sau.

foreach(I i in container.ResolveAll<I>()) 
{ 
... 
} 

Tôi đang di chuyển từ Windsor sang Autofac 1.4.4.561 nhưng không thể thấy cú pháp tương đương.

+0

Bất kỳ lý do nào mà bạn muốn chia sẻ, vì lý do bạn chuyển từ Windsor sang Autofac? –

+0

Điều mà tôi thực sự thích với Autofac là có thể thể hiện cấu trúc thành phần động thông qua các biểu thức lamda.Bằng cách sử dụng các biểu thức như trái ngược với autowiring có ít chỗ cho sự hiểu lầm về những gì các container là "làm" khi nó giải quyết một loại (lưu ý: autofac hỗ trợ autowiring nếu bạn thích). Cuối cùng, API Windsor đã trở nên quá lớn để phục vụ cho mọi khả năng nó mang lại ấn tượng về sự phức tạp, khi IOC là một khái niệm thực sự khá đơn giản. Không nói rằng tôi sẽ không bao giờ sử dụng Windsor nữa, chỉ cần thử các tùy chọn khác. – crowleym

+1

Tôi đã xem xét chuyển từ Windsor sang Autofac. API của Windsor rất khó hiểu. – Amy

Trả lời

69

Đối versons hiện tại của Autofac: (2.0+, vì vậy bất cứ điều gì bạn nên sử dụng ngày nay)

Bạn đăng ký nhiều ILoggers (ví dụ):

var builder = new ContainerBuilder(); 

builder.Register<ConsoleLogger>() 
    .As<ILogger>(); 

builder.Register<EmailLogger>() 
    .As<ILogger>() 
    .PreserveExistingDefaults(); //keeps console logger as the default 

Sau đó, nhận được tất cả ILogger s:

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

Bạn không cần phải làm gì đặc biệt, chỉ cần yêu cầu IEnumerable<T> của loại mong muốn. Autofac có bộ sưu tập hỗ trợ ra khỏi hộp, cùng với adapters khác có thể bọc các thành phần của bạn với chức năng bổ sung. .

này là việc sử dụng giống như ImplicitCollectionSupportModule trước 2.x, nhưng nướng ngay trong

Đối với phiên bản cũ (0.X - 1,4)

Hai cách:

1) Sử dụng đăng ký bộ sưu tập

var builder = new ContainerBuilder(); 
builder.RegisterCollection<ILogger>() 
    .As<IEnumerable<ILogger>>(); 

builder.Register<ConsoleLogger>() 
    .As<ILogger>() 
    .MemberOf<IEnumerable<ILogger>>(); 

builder.Register<EmailLogger>() 
    .As<ILogger>() 
    .MemberOf<IEnumerable<ILogger>>(); 

Sau đó:

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

cung cấp cho bạn IEnumerable.

hoặc 2) Bạn có thể sử dụng các mô-đun ImplicitCollectionSupport, mà sẽ làm cho công việc mã như các phiên bản mới hơn của Autofac:

builder.RegisterModule(new ImplicitCollectionSupportModule()); 
builder.Register(component1).As<ILogger>; 
builder.Register(component2).As<ILogger>; 

Sau đó giải quyết một tập hợp các ILogger chứ không phải tìm kiếm để giải quyết tất cả.

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

cung cấp cho bạn IEnumerable, một lần nữa.

+0

Hoàn hảo. Đã đi cho một lựa chọn như nó có vẻ hiệu quả hơn bởi vì các container "biết" những gì để đưa vào bộ sưu tập. Tùy chọn thứ hai lặp lại mặc dù mọi đăng ký trong phân cấp vùng chứa tìm kiếm các loại đối sánh. – crowleym

+0

@ philip-rieck hi, nó có nghĩa là container.resolve trong autofac ?. Nếu bạn không sử dụng autofac, theo cách nào bạn có thể khai báo giao diện Ilogger? cảm ơn bạn ... –

+1

@sebastian_h nếu bạn không sử dụng autofac, câu trả lời này sẽ không có ý nghĩa gì đối với bạn. Thay vào đó, bạn có thể muốn xem tại đây: http://stackoverflow.com/questions/5646820/logger-wrapper-best-practice –

54

Bản cập nhật vì lợi ích của phiên bản mới (2.x). Tất cả bạn cần bây giờ là:

container.Resolve<IEnumerable<I>>(); 

Không còn nhu cầu RegisterCollection() hoặc ImplicitCollectionSupportModule - chức năng này đi ra khỏi hộp.

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