问题
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;
}
The possible descendants can take even more dependencies, etc. I would like to still use Ninject to resolve dependencies and create the object tree.
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?
I'd like to use it like this.
kernel.Bind<ConcreteFoo>().ConstructWith(ctx => Foo.Create(ctx.Request.Service, ctx.Arguments));
where ConstructWith
and ctx.Arguments
are fictional parts. I hope my problem is clear.
回答1:
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")
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>()))
来源:https://stackoverflow.com/questions/35509906/how-to-make-ninject-use-a-custom-construction-logic-for-a-specific-type-while-ke