Tôi nhầm lẫn về việc triển khai Dependency Injection trong một ví dụ cụ thể.Làm việc với Nhà máy Trừu tượng được bơm qua DI container
Giả sử chúng tôi có lớp SomeClass có phụ thuộc kiểu IClassX.
public class SomeClass
{
public SomeClass(IClassX dependency){...}
}
Creation triển khai cụ thể của giao diện IClassX phụ thuộc vào thời gian chạy thông số N.
Với constructor nào đó, tôi không thể cấu hình DI container (Unity được sử dụng), vì tôi không biết những gì thực hiện IClassX sẽ được sử dụng trong thời gian chạy. Mark Seemann trong cuốn sách Dependency Injection In .Net gợi ý rằng chúng ta nên sử dụng Abstract Factory làm tham số tiêm.
Bây giờ chúng tôi có SomeAbstractFactory trả về việc triển khai IClassX dựa trên runtimeTimeater parametimeParam.
public class SomeAbstractFactory
{
public SomeAbstractFactory(){ }
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1();
case 2: return new ClassX2();
default : return new ClassDefault();
}
}
}
SomeClass bây giờ chấp nhận ISomeAbstractFactory như một tham số tiêm:
public class SomeClass
{
public SomeClass(ISomeAbstractFactory someAbstractfactory){...}
}
Và đó là tốt. Chúng tôi chỉ có một thành phần gốc, nơi chúng tôi tạo ra đồ thị đối tượng. Chúng ta cấu hình container Unity để tiêm SomeAbstractFactory vào SomeClass.
Nhưng, chúng ta hãy giả sử rằng lớp ClassX1 và ClassX2 có phụ thuộc của mình:
public class ClassX1 : IClassX
{
public ClassX1(IClassA, IClassB) {...}
}
public class ClassX2 : IClassX
{
public ClassX2(IClassA, IClassC, IClassD) {...}
}
Làm thế nào để giải quyết IClassA, IClassB, IClassC và IClassD phụ thuộc?
1. tiêm qua constructor SomeAbstractFactory
Chúng tôi có thể tiêm triển khai cụ thể của IClassA, IClassB, IClassC và IClassD để SomeAbstractFactory như thế này:
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD)
{...}
...
}
Unity chứa sẽ được sử dụng trong ban đầu thành phần gốc và sau đó sử dụng DI của người nghèo để trả về bê tông ClassX1 hoặc ClassX2 dựa trên tham số runTimeParam
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1(classA, classB);
case 2: return new ClassX2(classA, classC, classD);
default : return new ClassDefault();
}
}
}
Vấn đề với cách tiếp cận này:
- SomeAbstractFactory biết về phụ thuộc mà don `t thực sự thuộc về nó.
- đồ thị đối tượng sâu hơn sẽ đòi hỏi phải thay đổi cả constructor và lớp SomeAbstractFactory thực hiện
- DI chứa sẽ không được sử dụng để giải quyết phụ thuộc, man`s nghèo DI phải được sử dụng
2. gọi Explicit để DI vùng chứa
Thay vì "làm mới" ClassX1 hoặc ClassX2, chúng tôi sẽ giải quyết chúng bằng cách sử dụng vùng chứa DI.
public class SomeAbstractFactory
{
public SomeAbstractFactory(IUnityContainer container){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return container.Resolve<IClassX>("x1");
case 2: return container.Resolve<IClassX>("x2");
default : return container.Resolve<IClassX>("xdefault");
}
}
}
Vấn đề với cách tiếp cận này:
- DI container được thông qua vào SomeAbstractFactory
- DI phương pháp Giải quyết không chỉ được sử dụng ở thư mục gốc tổng hợp (ServiceLocator chống mẫu)
Có cách tiếp cận nào phù hợp hơn không?