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

How to make Ninject use a custom construction logic for a specific type while keeping the resolution process?

我有一个 class 接受依赖项作为构造函数参数。这个 class 可能会被其他一些 classes 继承,并且由于技术原因(关于构造函数顺序等)我必须使用工厂方法和使用 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 是虚构的部分。我希望我的问题很清楚。

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

  • 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()) 执行您的 post-激活逻辑,如 SetDefaultValues
  • 或者:OnActivation((IContext ctx, Foo instance) => foo.Initialize(ctx.Kernel.Get<Settings>()))