2010-01-29 27 views
33

Tôi đang sử dụng vùng chứa Unity IoC để giải quyết các đối tượng của mình. Tuy nhiên, tôi đã gặp phải vấn đề. Khi tôi có nhiều hơn một nhà xây dựng - Unity biết cái nào để sử dụng? Nó dường như sử dụng một với các tham số khi tôi có một với một và không có. Tôi có thể nói một cách rõ ràng nó để sử dụng constructor nào không?Chỉ định hàm tạo cho vùng chứa Unity IoC để sử dụng

Cụ thể, tôi đã có một trường hợp tương tự như lớp Person sau đây với hai hàm tạo. Trong trường hợp này, tôi muốn container IoC sử dụng hàm tạo mặc định - không có tham số - nhưng nó chọn một tham số có tham số.

public class SomeValueObject 
{ 
    public SomeValueObject(string name) 
    { 
     Name = name; 
    } 
    public string Name { get; set; } 
} 

public class Person 
{ 
    private string _name; 

    public Person() 
    { 
     _name = string.Empty; 
    } 

    public Person(SomeValueObject obj) 
    { 
     _name = obj.Name; 
    } 
} 

Điều này rõ ràng là không thành công vì không thể tạo SomeValueObject - không biết phải đưa vào thông số chuỗi của nó. Lỗi mà nó đưa ra là:

Độ phân giải của phụ thuộc không thành công, type = "MyApp.Person", name = "". Thông báo ngoại lệ là: Hoạt động xây dựng hiện tại (khoá xây dựng Khóa [MyApp.Person, null]) không thành công: Tham số obj không thể được giải quyết khi cố gắng gọi hàm tạo MyApp.Person (MyApp.SomeValueObject obj). (Chiến lược loại BuildPlanStrategy, chỉ số 3)

Việc đăng ký container:

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager()); 

Và giải quyết:

var person = Container.Resolve<Person>(); 
+0

Không phải là điểm của IoC để sử dụng giao diện ??? – Martin

+3

Chắc chắn, và tôi làm điều đó chủ yếu. Nhưng điều này không tạo ra sự khác biệt cho câu hỏi. – stiank81

+0

@Martin Nhiều lập trình viên sử dụng các lớp và tránh tính tổng quát giả tạo ra một giao diện và sau đó chỉ thực hiện một giao diện của nó. Nó cũng tránh được khối lượng dây IoC có mùi mà bạn thấy trong hầu hết các ứng dụng doanh nghiệp, nhưng vẫn cho phép bạn chuyển đổi một số triển khai khi cần. http://programmers.stackexchange.com/questions/133471/writing-testable-code-vs-avoiding-speculative-generality –

Trả lời

46

đăng ký nó như thay vì điều này:

container.RegisterType<Person>(new InjectionConstructor()); 

Bạn có thể thêm LifetimeManager cũng sử dụng một tình trạng quá tải của các phương pháp RegisterType.

Điều đó nói rằng, khi lập mô hình cho DI, cuộc sống của bạn sẽ dễ dàng hơn nhiều nếu bạn có các contructors rõ ràng (nghĩa là không có nhà thầu quá tải).

+0

Bạn đang tham chiếu quá tải nào? – Casey

+0

@Casey ... Tôi tin rằng nhà xây dựng trống. – granadaCoder

+0

Vì không có đối số cho InjectionConstructor, nó đang gọi hàm tạo rỗng của Person. Nếu mã đã được 'mới InjectionConstructor (new SomeValueObject ("John Smith"))', mà có thể đã được gọi là (người khác) constructor, nơi constructor "khác" là một trong đó sử dụng đối tượng SomeValueObject/đối số. – granadaCoder

4

Multiple-Constructor Injection Using an Attribute

Khi một lớp đối tượng chứa hơn một hàm tạo w thứ i cùng số các thông số, bạn phải áp dụng InjectionConstructor thuộc tính đến constructor rằng container Unity sẽ sử dụng để chỉ ra các constructor container nên sử dụng. Như với constructor injection tự động, bạn có thể chỉ định các nhà xây dựng thông số như một loại bê tông, hoặc bạn có thể chỉ định một giao diện hoặc lớp cơ sở mà container Unity chứa một ánh xạ đăng ký .

22

Theo mặc định, Unity chọn một hàm tạo với số lượng đối số tối đa. Để ghi đè điều này, hãy trang trí hàm tạo yêu cầu với InjectionConstructorAttribute.

+4

Chúng ta nên đề cập rằng trang trí các nhà xây dựng cặp vợ chồng thành phần để Unity như container IoC của nó. Việc xử lý đặc tả trong quá trình đăng ký có lẽ là thích hợp hơn để các thành phần không cần tham chiếu đến Unity và do đó một IoC khác có thể được hoán đổi nếu muốn. –

0

Tôi thực sự phải chỉ ra cách bạn đang sử dụng tiêm phụ thuộc trong trường hợp này là sai. Các container sẽ có thể tiêm SomeValueObject về xây dựng.

Điều bạn nên làm là đăng ký đối tượng mặc định của SomeValueObject mà.Tên tài sản trả về string.Empty thay thế.

+0

Có lẽ ví dụ đơn giản của tôi là một chút đi, nhưng imo có một nhu cầu của hai nhà thầu khác nhau trong mã thực tế .. Cảm ơn bạn đã đề cập anyway. – stiank81

+0

Nếu bạn chưa viết thì sao? – Casey

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