如何使 class 使用注入依赖项的不同实现?
How to make a class use different implementations of injected dependencies?
假设我有这个 类:
public class MyClass : IMyClass
{
private readonly ISomething1 _something1;
private readonly ISomething2 _something2;
public MyClass(ISomething1 something1, ISomething2 something2)
{
_something1 = something1;
_something2 = something2;
}
public SomeObject Get(AnotherObject anotherObject)
{
var a = _something1.Calculate(anotherObject.Property1);
var b = _something2.Get(anotherObject.Property2, a);
return b;
}
}
public class MyClass2 : IMyClass
{
private readonly ISomething1 _something1;
private readonly ISomething2 _something2;
public MyClass(ISomething1 something1, ISomething2 something2)
{
_something1 = something1;
_something2 = something2;
}
public SomeObject Get(AnotherObject anotherObject)
{
var a = _something1.Calculate(anotherObject.Property1);
var b = _something2.Get(anotherObject.Property2, a);
return b;
}
}
看起来MyClass
和Myclass2
是一样的。但是,区别在于我使用 Ninject
为这些 类 注入 ISomething1
和 ISomething2
的不同实现:
//MyClass
Bind<ISomething1>().To<AmazingSomething>().WhenInjectedInto<MyClass>();
Bind<ISomething2>().To<BeautifulSomething>().WhenInjectedInto<MyClass>();
//MyClass2
Bind<ISomething1>().To<GoodSomething>().WhenInjectedInto<MyClass2>();
Bind<ISomething2>().To<UglySomething>().WhenInjectedInto<MyClass2>();
我不喜欢这个解决方案,因为它违反了 DRY 原则。但是,我喜欢它,因为它遵循 Open/closed 原则(我希望如此)。
有没有更好的方法来实现我的目标?
绝对不需要MyClass2
。
很可能您需要工厂创建 IMyClass
实现,使用一些自定义逻辑来选择要注入的 ISomething1
和 ISomething2
实现。
我没有在我的项目中使用 Ninject,但我相信,您可以将一些元数据附加到您的依赖项,这将帮助您实现选择逻辑。
例如,使用穷人的DI会有这样的东西:
public class MyClassFactory
{
public IMyClass Create()
{
if (DateTime.Today.DayOfWeek = DayOfWeek.Friday)
{
return new MyClass(new ASomething1(), new ASomething2());
}
return new MyClass(new BSomething1(), new BSomething2());
}
}
因此,工厂代码取决于必须如何实例化和组合所有这些对象。
假设我有这个 类:
public class MyClass : IMyClass
{
private readonly ISomething1 _something1;
private readonly ISomething2 _something2;
public MyClass(ISomething1 something1, ISomething2 something2)
{
_something1 = something1;
_something2 = something2;
}
public SomeObject Get(AnotherObject anotherObject)
{
var a = _something1.Calculate(anotherObject.Property1);
var b = _something2.Get(anotherObject.Property2, a);
return b;
}
}
public class MyClass2 : IMyClass
{
private readonly ISomething1 _something1;
private readonly ISomething2 _something2;
public MyClass(ISomething1 something1, ISomething2 something2)
{
_something1 = something1;
_something2 = something2;
}
public SomeObject Get(AnotherObject anotherObject)
{
var a = _something1.Calculate(anotherObject.Property1);
var b = _something2.Get(anotherObject.Property2, a);
return b;
}
}
看起来MyClass
和Myclass2
是一样的。但是,区别在于我使用 Ninject
为这些 类 注入 ISomething1
和 ISomething2
的不同实现:
//MyClass
Bind<ISomething1>().To<AmazingSomething>().WhenInjectedInto<MyClass>();
Bind<ISomething2>().To<BeautifulSomething>().WhenInjectedInto<MyClass>();
//MyClass2
Bind<ISomething1>().To<GoodSomething>().WhenInjectedInto<MyClass2>();
Bind<ISomething2>().To<UglySomething>().WhenInjectedInto<MyClass2>();
我不喜欢这个解决方案,因为它违反了 DRY 原则。但是,我喜欢它,因为它遵循 Open/closed 原则(我希望如此)。
有没有更好的方法来实现我的目标?
绝对不需要MyClass2
。
很可能您需要工厂创建 IMyClass
实现,使用一些自定义逻辑来选择要注入的 ISomething1
和 ISomething2
实现。
我没有在我的项目中使用 Ninject,但我相信,您可以将一些元数据附加到您的依赖项,这将帮助您实现选择逻辑。
例如,使用穷人的DI会有这样的东西:
public class MyClassFactory
{
public IMyClass Create()
{
if (DateTime.Today.DayOfWeek = DayOfWeek.Friday)
{
return new MyClass(new ASomething1(), new ASomething2());
}
return new MyClass(new BSomething1(), new BSomething2());
}
}
因此,工厂代码取决于必须如何实例化和组合所有这些对象。