Geo*_*e R 35 c# ninject dependency-management
如何将构造函数注入与"手动"构造函数参数组合?即.
public class SomeObject
{
public SomeObject(IService service, float someValue)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我的DI容器应该解析/注入IService,并且应该指定someValue.我该如何混合这两个?
Rem*_*oor 34
应尽可能避免使用此类构造.因此,问问自己:这个参数真的需要作为构造函数参数吗?或者可以将SomeObject替换为无状态的,通过将参数传递给您在对象上执行的方法,每个依赖于它的每个人都可以重用它.
而不是
public class SomeObject
{
private float someValue
public SomeObject(IService service, float someValue)
{
this.someValue = someValue
}
public float Do(float x)
{
return this.Service.Get(this.someValue) * x;
}
}
Run Code Online (Sandbox Code Playgroud)
使用
public class SomeObject
{
public SomeObject(IService service)
{
}
public float Do(float x, float someValue)
{
return this.Service.Get(someValue) * x;
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要去工厂:
public interface ISomeObjectFactory
{
ISomeObject CreateSomeObject(float someValue);
}
public class SomeObjectFactory : ISomeObjectFactory
{
private IKernel kernel;
public SomeObjectFactory(IKernel kernel)
{
this.Kernel = kernel;
}
public ISomeObject Create(float someValue)
{
return this.kernel.Get<ISomeObject>(WithConstructorArgument("someValue", someValue);
}
}
Run Code Online (Sandbox Code Playgroud)
预览:Ninject 2.4不再需要实现,但允许
kernel.Bind<ISomeObjectFactory>().ToFactory(); // or maybe .AsFactory();
Run Code Online (Sandbox Code Playgroud)
另一种方法 - 分两步初始化(与 ninject 无关,任何 DI 框架):
public class SomeObject
{
private readonly IService _service;
public SomeObject(IService service)
{
// constructor only captures dependencies
_service = service;
}
public SomeObject Load(float someValue)
{
// real initialization goes here
// ....
// you can make this method return no value
// but this makes it more convienient to use
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
和用法:
public static class TestClass
{
public static void TestMethod(IService service)
{
//var someObject = new SomeObject(service, 5f);
var someObject = new SomeObject(service).Load(5f);
}
}
Run Code Online (Sandbox Code Playgroud)
您真的不应该尝试为此使用 DI。你可以想出所有类型的古怪解决方案,但它们在未来可能没有意义。
我们的方法是通过 DI 创建一个工厂,然后工厂的 Create 方法将使用传入的 DI 容器构建自己。我们不必经常使用这种模式,但是当我们这样做时,实际上会使产品更干净(因为它使我们的依赖图更小)。