I have a GUI application. In it I allow a user to select from a container-provided list of algorithms. Each algorithm will be kicked off as a background task in another view. I need to support multiple instances of this view, and support multiple instances of the same algorithm. That view will also be provided by the container. The algorithm is also stateful.
So I have a case where I need to create instances of my view and algorithm and bind them together at runtime. I don't have static binding points for these instances, so I can't use the normal injection facilities (constructor or property injection). I don't want to call new
, and I don't want to use the container like a Service Locator.
I solved this in Castle.Windsor with the Typed Factory Facility, but I had to deal with factories all over my app. The factory design was also a little strange because I had to return my instances to the factory when I was done with them.
I am now looking into using NInject because so far the learning curve and intro docs were much better, and I'd like to propose a container for my team to use. But for a scenario like this I think I'd have to write my own factories and call the kernel directly to resolve new instances (Service Locator embedded in a factory), as well as adding factory methods in my registration code.
Is there a generic way to solve this, or is this simply a problem that Dependency Injection wasn't designed to solve on its own?
Clarification:
I said in the comments that I'd like a specific answer for Ninject, and I've gotten that. And thanks very much :) In real life here I'll probably just use the pragmatic solutions that have been proposed.
But I botched my question by providing my basis as a concrete problem. I was hoping for a more purely fundamental answer to the question in my title.
Is there a pure-DI technique that allows the user to trigger new instances of components at runtime? Or would all such implementations use the container as a Service Locator, or require a specific "quirk" to the container (e.g. built-in factory support, ala Castle.Windsor or the soon-to-be-release Ninject factory feature), rather than utilize only aspects of "pure" DI?
I've only heard this word from the Java world, and I don't have much idea of what it means - so forgive me :) Is what I am looking for some kind of "outjection"?
Best you create a factory interface like this
public interface IFooFactory
{
IFoo CreateFoo(int someParameter);
}
For Ninject 2.3 see https://github.com/ninject/ninject.extensions.factory and let it be implemented by Ninject by adding the following configuration.
Bind<IFooFactory>().AsFactory();
For 2.2 do the implementation yourself. This implementation is part of the container configuration and not part of your implementations.
public class FooFactory: IFooFactory
{
private IKernel kernel;
public FooFactory(IKernel kernel)
{
this.kernel = kernel;
}
public ISession CreateFoo(int someParameter)
{
return this.kernel.Get<IFoo>(
new ConstructorArgument("someParameter", someParameter));
}
}