在保持解析过程的同时,如何使Ninject对特定类型使用自定义构造逻辑? [英] How to make Ninject use a custom construction logic for a specific type while keeping the resolution process?
问题描述
我有一个类,它接受依赖项作为构造函数参数.此类可以由其他一些类继承,并且由于技术原因(关于构造函数的顺序等),我必须使用工厂方法并使用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));
其中ConstructWith
和ctx.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 likeSetDefaultValues
.- alternatively:
OnActivation((IContext ctx, Foo instance) => foo.Initialize(ctx.Kernel.Get<Settings>()))
这篇关于在保持解析过程的同时,如何使Ninject对特定类型使用自定义构造逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!