Partial injection with Ninject?

2019-10-19 08:29发布

我想实现对具有布尔参数的构造现有的类Ninject

public MyClass(bool val) //[OPTION 1: Current]
{
    //I Called static function to do something -> I want to inject this
    ...
    if(val){ ... } else{ ... }
    ...
}

我想改变注入逻辑ISomething ....的构造函数的样子:

public MyClass(ISomething something, bool val) //[OPTION 2: Desired]
{
    something.DoSomething();
    ...
    if(val){ ... } else{ ... }
    ...
}

此外,我使用的一次性类,称这一个:[例如。 使用选项1 - >试图转换到选项2]

public MyMaster(bool val)
{
    this.myclass = new MyClass(val); //-> now this has to be injected, how???
}

我实施了在几次using情境与true或false参数,就像这样:[例如。 使用选项1 - >试图转换到选项2]

using(var master = new MyMaster(true)){...} //-> This need to be refactored or injected, how???
//...
using(var master = new MyMaster(false)){...} //-> This need to be refactored or injected, how???

我种在这里受阻......因为我需要注入一个值,而不是注入等。 也许实现运行时注入? 此外它包裹在using ,如果它是需要的声明?

注:这是一个类库,不知道注射任何事情( Ninject是在后面的层)

Answer 1:

我希望我理解正确的问题-你需要一个MyClass基础上, bool传递给MyMaster构造,并且要避免使用new ,而是有Ninject提供为你,是吗?

对于这一点,你可以使用一个抽象工厂。 (注意:您可以像西门白石指出,使用这个Ninject工厂扩建,但我只是为了清楚起见,做一个明确的说明)

这些接口/类在你的类库中定义,而不是在组合物根。

public interface IMyClassFactory
{
   IMyClass Create(bool val);
}

public interface IMyClass
{
   //whatever methods, etc, it's supposed to have.
}

public class MyClass:IMyClass
{
   public MyClass(bool val)
    {
       //do something with val here in the ctor
    }
}

这个类是在你的作文根定义

public class MyClassFactory:IMyClassFactory
{
   readonly IKernel _kernel;
   public MyClassFactory(IKernel kernel)
   {
      _kernel=kernel;
   }
   public IMyClass Create(bool val)
   {
      return _kernel.Get<IMyClass>(new ConstructorArgument("val",val);
   }
}

然后你绑定的类在你的作文根,无论你做你平常的绑定:

kernel.Bind<IMyClassFactory>().To<MyClassFactory>();
kernel.Bind<IMyClass>().To<MyClass>();

和你的MyMaster构造函数现在看起来像:

readonly IMyClass myclass;
public MyMaster(bool val,IMyClassFactory factory)
{
    this.myclass = factory.Create(val); 
}

一旦你得到这个工作,并了解它是如何工作的,你可以把它扔掉,并使用Ninject厂扩展的建议,因为他们让您不用(举例写工厂类自己:) 点击这里 )



Answer 2:

通常,当您使用new关键字..你放弃了依赖注入。

我知道你说:“ 这是一个类库,不知道注射任何事情(Ninject是在后面的层)” ..但你的复合根系应该只是..根。 我的意思是说,那是你DI引导应在最上层发生(通常到一边,在一个单独的项目中引用的所有其他项目)。

一旦你的设置,你就可以开始考虑使用Ninject.Factories扩展。 您可以创建一个工厂是这样的:

public interface ObjectCreatorFactory {
    MyClass CreateInstanceOfMyClass();
    MyMaster CreateInstanceOfMyMaster();
}

..和有工厂注入某个地方,从而使你有Ninject实例的实例为你的能力。

你唯一的选择是恢复到良好的旧服务定位器 。 我一般尽量远离他们..因为它使单元测试困难的,如果您的测试实现需要使用DI容器中。

不幸的是,这些是你唯一的选择。 有没有办法只希望Ninject做什么它需要做的..你需要告诉它。 这涉及到你如何目前正在做的事情的变化。



文章来源: Partial injection with Ninject?