12

Nó có thể dường như là một câu hỏi ngu ngốc vì tất cả mọi thứ trong mã của tôi đang làm việc, nhưng tôi đã đăng ký một singleton cách này với container Unity tôi _ambientContainer:UnityContainer.Resolve hoặc ServiceLocator.GetInstance?

_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager()); 

Để tránh sử dụng lĩnh vực địa phương của tôi, tôi sử dụng :

get { 
    return ServiceLocator.Current.GetInstance<Application.StateContext>(); 
} 

bên trong thuộc tính get của tôi để có được một ví dụ về đối tượng của tôi. Bằng cách này tôi nhận được cùng một trường hợp (Application.StateContext vẫn là một singleton) hoặc không GetInstance tạo một hình thức mới?

Thay vào đó, tốt hơn bạn nên sử dụng trường _ambientContainer cục bộ?

get { 
    return _ambientContainer.Resolve<Application.StateContext>(); 
} 

Cảm ơn bạn.

Trả lời

7

Tốt bạn nên tránh cả hai cách (ab) sử dụng container của bạn.

ServiceLocator is considered an anti-pattern trong kiến ​​trúc ứng dụng hiện đại.

+1

Bạn có đề xuất thay thế không? (cụ thể cho mã ví dụ trong câu hỏi?) – Adam

+0

@Adam Một thay thế cho mã nào? Các getter? Hoặc đăng ký 'Application.StateContext'? Tác giả không cho biết loại ứng dụng nào anh ta sử dụng (asp.net/mcv, winforms, wpf, console, wcf ...) nên tôi không thể nói là bạn đã đặt mã đăng ký. Mỗi loại ứng dụng có [root root] khác nhau (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx). Đối với các cuộc gọi đến các định vị dịch vụ: làm cho 'StateContext' một tham số ctor của những lớp cần nó. Điều đó làm cho sự phụ thuộc rõ ràng và có thể hoán đổi cho nhau (ví dụ: đối với các thử nghiệm). –

+1

Bất kỳ mẫu nào là mẫu chống nếu bạn sử dụng sai cách. TẤT CẢ các thư viện DI sử dụng vị trí dịch vụ theo các cách khác, chúng không hoạt động. Đừng tin mọi thứ bạn đọc trên internet! – JBeckton

15

Đi qua xung quanh trường hợp của container đến các lớp học của người tiêu dùng không phải là nói chung là một ý tưởng tốt, vì bạn không còn được bảo đảm để có một đơn nơi trong ứng dụng của bạn, nơi các thành phần và dịch vụ đang được đăng ký (được gọi là Composition Root) .

Lớp học cần nêu phụ thuộc của họ trong API công cộng của họ, lý tưởng bởi specifying them as constructor arguments, mà hộp sẽ tự động cung cấp một ví dụ cho bất cứ khi nào nó được yêu cầu để giải quyết một loại cụ thể (một quá trình gọi là Autowiring).

Dependency Injection thường là the preferred choice nhưng không phải lúc nào cũng áp dụng được. Trong những trường hợp đó, sử dụng Service Locator, như bạn đang làm trong ví dụ của mình, là giải pháp tốt nhất tiếp theo cho decouple a class from its dependencies.

Tóm lại, nếu Dependency Injection không phải là một lựa chọn, tôi sẽ tránh để các lớp của tôi tham chiếu trực tiếp vào vùng chứa và thay vào đó họ truy cập nó thông qua một Service Locator.