2010-03-18 21 views
31

Cho một lớp học với một số nhà xây dựng - làm thế nào tôi có thể nói cho Resolve mà constructor sử dụng?Unity.Resolve biết constructor để sử dụng như thế nào?

Hãy xem xét các lớp ví dụ sau:

public class Foo 
{ 
    public Foo() { } 
    public Foo(IBar bar) 
    { 
     Bar = bar; 
    } 
    public Foo(string name, IBar bar) 
    { 
     Bar = bar; 
     Name = name; 
    } 
    public IBar Bar { get; set; }   
    public string Name { get; set; } 
} 

Nếu tôi muốn tạo một đối tượng của loại Foo sử dụng Giải quyết như thế nào sẽ giải quyết biết constructor sử dụng không? Và làm thế nào tôi có thể nói nó để sử dụng đúng? Hãy nói rằng tôi có một container với một IBar đăng ký - nó sẽ hiểu rằng nó nên ủng hộ các nhà xây dựng dùng IBar? Và nếu tôi chỉ định một chuỗi quá - nó sẽ sử dụng constructor (string, IBar)?

Foo foo = unityContainer.Resolve<Foo>(); 

Và hãy bỏ qua một thực tế rằng nó có lẽ sẽ dễ dàng hơn nếu lớp chỉ có một constructor đơn ...

Trả lời

53

Khi một lớp đối tượng chứa nhiều hơn một nhà xây dựng, Unity sẽ sử dụng một trong các có thuộc tính InjectionConstructor được áp dụng. Nếu có nhiều hơn một hàm tạo, và không có thuộc tính InjectionConstructor, Unity sẽ sử dụng hàm tạo với hầu hết các tham số. Nếu có nhiều hơn một hàm tạo như vậy (nhiều hơn một trong số "dài nhất" có cùng số tham số), Unity sẽ tăng một ngoại lệ.

Taken từ link text

+0

Tuyệt vời. Cảm ơn..! – stiank81

+0

Chính xác những gì tôi đang tìm kiếm! Tôi chỉ trang trí các nhà xây dựng tôi muốn được sử dụng với [InjectionConstructor] –

+2

Đó là câu trả lời sẽ tiết kiệm được một ngày cuối tuần. Được xác định rõ. –

28

Khi bạn đăng ký kiểu, bạn có thể xác định những nhà xây dựng để sử dụng như thế này:

container.RegisterType<Foo>(
    new InjectionConstructor(
     new ResolvedParameter<IBar>())); 

Đoạn mã trên là từ bộ nhớ, nhưng đó là nguyên tắc chung. Trong trường hợp này, tôi đã chọn hàm khởi tạo lấy một tham số duy nhất của kiểu IBar.

Và hãy bỏ qua một thực tế rằng nó có lẽ sẽ dễ dàng hơn nếu lớp chỉ có một constructor đơn ...

tôi không thể bỏ qua điều này. Khi nói đến Constructor Injection, mơ hồ là một mùi thiết kế. Về cơ bản bạn đang nói: Tôi thực sự không biết liệu tôi có quan tâm đến sự phụ thuộc này hay không.

Chắc chắn, Unity có khả năng tìm ra nó cho bạn, nhưng sau đó bạn sẽ dựa vào hành vi vùng chứa cụ thể thay vì thiết kế đúng API của bạn. Các thùng chứa khác có thể có hành vi khác nhau, vì vậy nếu bạn chọn di chuyển từ Unity sang vùng chứa tốt hơn, các lỗi tinh vi có thể xảy ra.

Sẽ an toàn hơn khi viết mã theo cách DI-friendly, but container-agnostic.

+0

Cảm ơn! Nhưng tôi có thực sự cần phải đăng ký loại trong container? Tôi sẽ sử dụng container để giải quyết các trường hợp của Foo, nhưng tôi không cần Foo để được trong container. Nhưng tôi vẫn nên sử dụng RegisterType?Hoặc chỉ vì tôi có nhu cầu cụ thể này để nói cho nó biết nhà xây dựng nào nên sử dụng? – stiank81

+0

Có, và không. Như ozczecho trích dẫn, Unity sử dụng phương pháp heuristic để chọn một nhà xây dựng khi đối mặt với sự mơ hồ (nó chọn nhà xây dựng với hầu hết các tham số). Nếu bạn cần nó để đi chệch khỏi thuật toán này, bạn phải nói rõ điều đó. Một cách là áp dụng thuộc tính InjectionConstructor và một cách khác là đăng ký nó trong vùng chứa. Cá nhân tôi thích đăng ký loại trong vùng chứa, vì điều đó cho phép tôi giữ cho mã của tôi không thuyết phục được. Nó cũng cho phép các cấu hình vùng chứa khác nhau, nếu có. –

+0

FWIW, khả năng của Unity để giải quyết các loại bê tông ngay cả khi chúng chưa được đăng ký trong thùng chứa là một tính năng đặc biệt cho nó. Một số vùng chứa hỗ trợ tính năng đó, trong khi các vùng chứa khác thì không. –

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