我目前正在尝试使用Ninject设置如何为某些字段设置初始值。
我有这样的事情:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
}
public void DoAThing()
{
_something.DoSomething();
}
}
我的困境在于将_something
设置为初始值,因为我不希望该类知道要使用哪个ISomething
的默认实现,是否有办法在Ninject实现这一目标?
我应该补充说,通过构造函数传递初始值不是一种选择。
我还应该补充一点,这是在一个类库中,因此任何有关如何以及何时设置内核的信息。注射应该很棒:)。
详细说明:似乎人们可能会感到困惑,我不是想让ISomething进入类(它不是依赖),而是ISomething的默认实现是依赖,这是为什么我选择了服务定位器模式,对于实际的依赖关系,我当然会在构造函数中使用它们。
感谢。
答案 0 :(得分:1)
是的,拥有高度耦合的类并不是很好,因此取决于抽象是一个不错的选择。但是隐藏你的依赖关系不是很好的解决方案。使它们对您的类的客户端可见,并使用依赖注入为您的类提供依赖项的具体实现:
public class SomeClass
{
private ISomething _something;
public SomeClass(ISomething something, string someParam)
{
_something = something;
}
public void DoAThing()
{
_something.DoSomething();
}
}
还要考虑创建工厂,它将为创建的ISomething
个对象提供SomeClass
的默认实现。
答案 1 :(得分:0)
最后,我决定使用静态IOC访问类,以允许我的代码访问类库中用于主注入的核心Ninject内核。
所以:
internal static class IOC
{
private static readonly IKernel _kernel;
static IOC()
{
_kernel = new StandardKernel(new IModule[] {
new SomethingModule(),
});
}
static T Get<T>()
{
return _kernel.Get<T>();
}
}
internal sealed class SomethingModule : StandardModule
{
public override void Load()
{
Bind<ISomething>().To<ConcreteSomething>(
new ConstructorParam("arg", "value"));
}
}
然后在我上一课:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
_something = IOC.Get<ISomething>();
}
public void DoAThing()
{
_something.DoSomething();
}
}
现在我可以得到具体的实现,甚至用默认值初始化它们来启动!
使用默认值初始化具体类的方法有点脆弱,但我确信在Ninject中有更聪明的方法可以实现这一点,但它看起来似乎是服务定位器式代码的混合解决方案Ninject工作得很好!
BTW我相信你也可以在不同的范围内拥有多个IOC容器(它们通过Ninject传递:P),以防止创建一个庞然大物“无所不在”的内核。
希望这有助于某人!