问题
I have the following code
public class Something {
[Inject]
public Configuration config {get;set;} //singleton
[Inject]
public Provider<WindowHandler> windowsProvider { get; set; } //NOT singleton
public void Search(string text) {
WindowHandler handler = windowsProvider.Create(xxxxxx);
//use the new handler that was created
}
}
but it seems the Provider takes an IContext where I put xxxxxx. Shouldn't the IContext from when I bootstrapped and created Something.cs from the kernel be used. Where is the no parameter Create method on the Provider??? (I am coming from Guice land point of view where it would be coded like above).
so the question is How do I do this correctly?
thanks, Dean
回答1:
It seems you are trying to use a provider as a factory in your code.
A provider in Ninject terms is a factory that is given to Ninject to create specially created objects. Therefore it gets the resolving context which can be used to create different instances depending where the instance in injected into.
public class FooProvider : Provider<IFoo>
{
public override IFoo CreateInstance(IContext ctx)
{
// add here your special IFoo creation code
return new Foo();
}
}
kernel.Bind<IFoo>().ToProvider<FooProvider>();
What you want is a factory in your coder that creates an instance of WindowHandler
. Therefore create an interface to create the instance like this:
public interface IWindowHandlerFactory
{
WindowHandler Create();
}
Bind<IWindowHandlerFactory>().ToFactory();
Alternatively you can inject Func<WindowHandler>
without adding a configuration. But this is less meaningful in my opinion.
NOTE: All this requires Ninject.Extensions.Factory available as prerelease 3.0.0-rc2 from Nuget.
See also: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/
回答2:
Well, my final solution was to cheat in ninject 2.0 with the following code...
var windowFactory = kernel.Get<IEWindowFactory>();
var tabFactory = kernel.Get<IETabFactory>();
windowFactory.Kernel = kernel;
tabFactory.Kernel = kernel;
and in the bindings list I have
Bind<IEWindowFactory>().ToSelf().InSingletonScope();
Bind<IETabFactory>().ToSelf().InSingletonScope();
and after that I just start my app
var main = kernel.Get<MainForm>();
main.Start();
and of course the factories are injected where I need them in the heirarchy of that MainForm.
so I manually put the kernel when starting up and then when I bootstrap my app, naturally these factories are fields in classes with [Ninject] annotation and so they can create objects. not the cleanest until we get 3.0, but it works(and I hate the extra factory classes I have to write code for but oh well).
来源:https://stackoverflow.com/questions/8716258/how-to-use-a-provider-in-ninject