在保持解析过程的同时,如何使Ninject对特定类型使用自定义构造逻辑? [英] How to make Ninject use a custom construction logic for a specific type while keeping the resolution process?

查看:76
本文介绍了在保持解析过程的同时,如何使Ninject对特定类型使用自定义构造逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它接受依赖项作为构造函数参数.此类可以由其他一些类继承,并且由于技术原因(关于构造函数的顺序等),我必须使用工厂方法并使用Activator.CreateInstance进行动态调用.工厂方法不是纯粹的基础设施,而是内部具有某种初始化逻辑.

I have a class which accepts dependencies as constructor arguments. This class may be inherited by some other classes and due to technical reasons (about constructor order and so) I have to use a factory method and dynamic invocation using Activator.CreateInstance. The factory method is not purely infrastructural, but it has some kind of initialization logic inside.

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来解析依赖关系并创建对象树.

The possible descendants can take even more dependencies, etc. I would like to still use Ninject to resolve dependencies and create the object tree.

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

However, using ToMethod binding I have to create to whole sub-tree myself. Is there any way when I could customize only the construction of a specific type in the resolution process?

我想这样使用它.

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

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

where ConstructWith and ctx.Arguments are fictional parts. I hope my problem is clear.

推荐答案

这些是您的选择(带有一些示例):

These are your options (with some examples):

  • 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>()))
  • ToMethod(ctx => Foo.Create(ctx.Kernel.Get<IDependency>())
  • ToConstructor(s => new Foo(s.Inject<IDependency1>(), s.Inject<IDependency2>())
  • WithConstructorArgument(typeof(string), "someParameter") to just specify single arguments and use default resolution for the rest (or other, custom, paremeters)
  • OnActivation(o => o.SetDefaultValues()) to perform your post-activation logic like SetDefaultValues.
  • alternatively: OnActivation((IContext ctx, Foo instance) => foo.Initialize(ctx.Kernel.Get<Settings>()))

这篇关于在保持解析过程的同时,如何使Ninject对特定类型使用自定义构造逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆