2014-06-20 15 views
10

Tôi có một trình trang trí có một số phụ thuộc khác cũng nên được giải quyết bằng cách sử dụng vùng chứa. Ví dụ:Đăng ký trang trí trong autofac mà không cần chỉ định tất cả các phụ thuộc theo cách thủ công

public class FooDecorator : IFoo 
{ 
    public FooDecorator(IFoo inner, IBar bar, IBaz baz) 
} 

Tôi có thể đăng ký này như thế này:

builder.RegisterType<Foo>().As<IFoo>(); 
builder.RegisterDecorator<IFoo>((c, inner) => 
    new FooDecorator(inner, c.Resolve<IBar>(), c.Resolve<IBaz>()), "key"); 

này đang làm việc, tuy nhiên không phải là tốt đẹp mà tôi phải tự xác định tất cả các phụ thuộc khác. Những gì tôi muốn làm là:

builder.RegisterDecorator<FooDecorator, IFoo>("key"); 

Trường hợp IFoo được giải quyết cho 'nội' IFoo và các phụ thuộc khác được giải quyết từ container. Điều này có thể, hoặc tôi có thể đăng ký một trang trí với một Func mà sẽ dẫn đến hành vi này?

Trả lời

8

Để tránh chỉ định tất cả các phụ thuộc theo cách thủ công, bạn nên đăng ký trang trí theo số Autofac và giải quyết nó bên trong thông số đầu tiên của phương pháp RegisterDecorator.

builder.RegisterType<Foo>() 
     .Named<IFoo>("original"); 
builder.RegisterType<FooDecorator>() 
     .Named<IFoo>("decorator"); 
builder.RegisterDecorator<IFoo>((c, inner) => c.ResolveNamed<IFoo>("decorator", TypedParameter.From(inner)), "original") 
     .As<IFoo>(); 

Đăng ký trang trí bằng cách sử dụng đăng ký có tên sẽ tránh bất kỳ xung đột nào.

+0

Điều này thật tuyệt vời, nhưng nếu bạn không biết (hoặc quan tâm) rằng việc triển khai cụ thể của 'IFoo' là' Foo'? Có thể tuyên bố một cái gì đó dọc theo dòng "trang trí bất cứ điều gì hiện đang giải quyết để' IFoo' với 'FooDecorator'"? (giả sử IFoo đã được đăng ký trước để cung cấp 'IFoo', nhưng không nhất thiết phải là một dịch vụ _named_) - Tôi nghĩ đây là những gì OP đang tìm kiếm, quá –

+0

@CristiDiaconescu không có giải pháp dễ dàng để làm điều này và không chỉ định trang trí đầu tiên, bạn sẽ có 2 đăng ký trong vùng chứa Autofac. Vui lòng đặt câu hỏi mới nếu bạn muốn biết thêm chi tiết về cách đạt được những gì bạn muốn. –

1

Dựa trên câu trả lời Cyril Durand của, đây là một phương pháp helper generic để đăng ký một trang trí:

private void RegisterDecorator<TInterface, TImplementation, TDecorator>(ContainerBuilder builder) where TImplementation : TInterface where TDecorator : TInterface 
    { 
     builder.RegisterType<TImplementation>().Named<TInterface>("implementation"); 
     builder.RegisterType<TDecorator>().Named<TInterface>("decorator"); 
     builder.RegisterDecorator<TInterface>((c, inner) => c.ResolveNamed<TInterface>("decorator", TypedParameter.From(inner)), "implementation"); 
    } 

Nếu có nhiều hơn một trang trí lồng nhau được yêu cầu, một phương pháp tương tự với nhiều tham số generic (TDecorator1, TDecorator2 vv) có thể được giới thiệu.

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