Tôi có một giao diện được gọi là IContext
. Đối với mục đích này, nó thực sự không quan trọng những gì nó làm ngoại trừ những điều sau đây:
T GetService<T>();
Phương pháp này làm là nhìn vào thùng chứa DI hiện tại của ứng dụng và cố gắng giải quyết sự phụ thuộc. Tôi nghĩ là khá chuẩn.
Trong ứng dụng ASP.NET MVC của tôi, hàm tạo của tôi trông như thế này.
protected MyControllerBase(IContext ctx)
{
TheContext = ctx;
SomeService = ctx.GetService<ISomeService>();
AnotherService = ctx.GetService<IAnotherService>();
}
Vì vậy, thay vì thêm nhiều tham số trong hàm tạo cho mỗi dịch vụ (vì điều này sẽ thực sự gây phiền nhiễu và tốn thời gian cho các nhà phát triển mở rộng ứng dụng) Tôi đang sử dụng phương pháp này để nhận dịch vụ.
Bây giờ, nó cảm thấy sai . Tuy nhiên, cách mà tôi hiện đang biện minh nó trong đầu là thế này - tôi có thể chế giễu nó .
Tôi có thể. Sẽ không khó để giả lập IContext
để kiểm tra Bộ điều khiển. Dù sao tôi cũng phải:
public class MyMockContext : IContext
{
public T GetService<T>()
{
if (typeof(T) == typeof(ISomeService))
{
// return another mock, or concrete etc etc
}
// etc etc
}
}
Nhưng như tôi đã nói, nó cảm thấy sai. Bất kỳ suy nghĩ / lạm dụng hoan nghênh.
public SomeClass(Context c)
. Mã này khá rõ ràng phải không? Nó tuyên bố, that SomeClass
phụ thuộc vào a Context
. Err, nhưng chờ đợi, nó không! Nó chỉ phụ thuộc vào sự phụ thuộc X
mà nó nhận được từ Ngữ cảnh. Điều đó có nghĩa là, mỗi khi bạn thay đổi Context
nó có thể bị hỏng SomeObject
, mặc dù bạn chỉ thay đổi Context
s Y
. Nhưng vâng, bạn biết rằng bạn chỉ thay đổi Y
không X
, vậy SomeClass
là tốt. Nhưng viết mã tốt không phải là về những gì bạn biết mà là những gì nhân viên mới biết khi anh ta nhìn vào mã của bạn lần đầu tiên.