如何让Ninject在保持解析过程的同时为特定类型使用自定义构造逻辑?

时间:2016-02-19 16:18:56

标签: c# ninject

我有一个接受依赖项作为构造函数参数的类。这个类可能会被其他一些类继承,并且由于技术原因(关于构造函数顺序等等),我必须使用工厂方法和使用Activator.CreateInstance的动态调用。工厂方法不是纯粹的基础结构,但它内部有一些初始化逻辑。

public class Foo {
  protected Foo(IService service, IOtherService otherService) { ... }
  ...
  public Foo Create(Type fooType, params object[] constructorArgs) {
    var instance (Foo)Activator.CreateInstance(fooType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, constructorArgs, null, null); // or something similar...
    instance.SetDefaultValues(); // for example...
    instance.StartChangeNotifications();
    return instance;
}

可能的后代可以采用更多依赖项等。我仍然希望使用Ninject来解析依赖项并创建对象树。

但是,使用ToMethod绑定我必须自己创建整个子树。有什么方法可以在解决过程中自定义特定类型的仅构造吗?

我想像这样使用它。

kernel.Bind<ConcreteFoo>().ConstructWith(ctx => Foo.Create(ctx.Request.Service, ctx.Arguments));

其中ConstructWithctx.Arguments是虚构的部分。我希望我的问题很清楚。

1 个答案:

答案 0 :(得分:2)

这些是你的选择(有一些例子):

  • ToMethod(ctx => Foo.Create(ctx.Kernel.Get<IDependency>())
  • ToConstructor(s => new Foo(s.Inject<IDependency1>(), s.Inject<IDependency2>())
  • WithConstructorArgument(typeof(string), "someParameter")只指定单个参数并对其余参数使用默认分辨率(或其他,自定义,参数)
  • OnActivation(o => o.SetDefaultValues())执行您的激活后逻辑,例如SetDefaultValues
  • 或者:OnActivation((IContext ctx, Foo instance) => foo.Initialize(ctx.Kernel.Get<Settings>()))