Thuật ngữ từ câu hỏi không thực sự khớp với mã ví dụ. Mẫu Ambient Context
này được sử dụng để lấy một phụ thuộc từ bất kỳ lớp nào trong bất kỳ mô-đun nào một cách dễ dàng nhất có thể, mà không gây ô nhiễm cho mọi lớp để chấp nhận giao diện của phụ thuộc, nhưng vẫn giữ ý tưởng đảo ngược điều khiển. Các phụ thuộc như vậy thường được dành riêng để ghi nhật ký, bảo mật, quản lý phiên, giao dịch, lưu trữ, kiểm toán cho bất kỳ mối quan tâm xuyên suốt nào trong ứng dụng đó. Đó là bằng cách nào đó gây phiền nhiễu để thêm một ILogging
, ISecurity
, ITimeProvider
đơn vị thi công và hầu hết thời gian không phải tất cả các lớp học cần tất cả cùng một lúc, vì vậy tôi hiểu nhu cầu của bạn.
Điều gì xảy ra nếu thời gian tồn tại của ISession
cá thể khác với trường hợp ILogger
? Có lẽ phiên bản ISession nên được tạo trên mỗi yêu cầu và ILogger một lần. Vì vậy, có tất cả các phụ thuộc này được chi phối bởi một đối tượng không phải là chính nó sẽ không phải là lựa chọn đúng đắn vì tất cả những vấn đề này với quản lý và bản địa hóa trọn đời và các đối tượng khác được mô tả trong chuỗi này.
Trong IAmbientContext
câu hỏi không giải quyết được vấn đề không gây ô nhiễm cho mọi nhà xây dựng. Bạn vẫn phải sử dụng nó trong chữ ký của nhà xây dựng, chắc chắn, chỉ một lần duy nhất lần này.
Vì vậy, cách dễ nhất là KHÔNG sử dụng phương thức tiêm xây dựng hoặc bất kỳ cơ chế tiêm nào khác để xử lý các phụ thuộc cắt chéo, mà sử dụng lệnh gọi tĩnh . Chúng tôi thực sự thấy mô hình này khá thường xuyên, được thực hiện bởi chính khuôn khổ. Kiểm tra Thread.CienPrincipal , một thuộc tính tĩnh trả về việc thực hiện IPrincipal
giao diện. Nó cũng có thể giải quyết để bạn có thể thay đổi việc triển khai nếu bạn muốn như vậy, do đó bạn không được kết hợp với nó.
MyCore
bây giờ trông giống như
public class MyCoreClass
{
public void BusinessFeature(string data)
{
LoggerContext.Current.Log(data);
_repository.SaveProcessedData();
SessionContext.Current.SetData(data);
...etc
}
}
Mô hình này và các triển khai có thể đã được mô tả chi tiết bởi Mark Seemann trong bài viết này . Có thể có các triển khai dựa vào chính bộ chứa IoC mà bạn sử dụng.
Bạn muốn tránh AmbientContext.Current.Logger
, AmbientContext.Current.Session
vì những lý do tương tự như mô tả ở trên.
Nhưng bạn có các tùy chọn khác để giải quyết vấn đề này: sử dụng trang trí, đánh chặn động nếu container của bạn có khả năng này hoặc AOP. Bối cảnh xung quanh nên là giải pháp cuối cùng vì thực tế khách hàng của họ che giấu sự phụ thuộc của họ thông qua nó. Tôi vẫn sẽ sử dụng Ambient Context nếu giao diện thực sự bắt chước sự thúc đẩy của tôi để sử dụng một phụ thuộc tĩnh như DateTime.Now
hoặc ConfigurationManager.AppSettings
và nhu cầu này tăng lên khá thường xuyên. Nhưng cuối cùng, tiêm constructor có thể không phải là một ý tưởng tồi để có được những phụ thuộc phổ biến này.
IService
sử dụng để liên lạc với các dịch vụ khác là gì?" NếuIService
đại diện cho một sự phụ thuộc mơ hồ vào các dịch vụ khác thì nó có vẻ như là một công cụ định vị dịch vụ và không nên tồn tại. Lớp học của bạn nên phụ thuộc vào các giao diện mô tả rõ ràng những gì người tiêu dùng của họ sẽ làm với họ. Không có lớp nào cần một dịch vụ để cung cấp quyền truy cập vào một dịch vụ. Một lớp cần một sự phụ thuộc làm một cái gì đó cụ thể mà lớp cần.