So far I've managed to easily implement contextual binding using Unity and Castle Windsor. Meaning, given multiple registered implementations of an interface, I can register the client component that uses those as a dependency to pick a specific one. However with Ninject, there doesn't seem to be the same interface for performing this and the example I found on:
Unity example:
Given interface, IFoo and implementations Foo1, Foo2, Foo3.
container.RegisterType<IFoo , Foo1>("Foo1", new TransientLifetimeManager());
container.RegisterType<IFoo , Foo2>("Foo2", new TransientLifetimeManager());
container.RegisterType<IFoo , Foo3>("Foo3", new TransientLifetimeManager());
container.RegisterType<FooClient, FooClient>("FooClient1", new InjectionConstructor(new ResolvedParameter<IFoo>("Foo2")));
var fooClient = container.Resolve<FooClient>("FooClient1");
Castle Windsor example:
internal class FooInstaller: IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IFoo>().Named("Foo1").ImplementedBy<Foo1>().LifeStyle.Transient);
container.Register(Component.For<IFoo>().Named("Foo2").ImplementedBy<Foo2>().LifeStyle.Transient);
container.Register(Component.For<IFoo>().Named("Foo3").ImplementedBy<Foo3>().LifeStyle.Transient);
container.Register(Component.For<FooClient>().LifeStyle.Singleton.DependsOn(ServiceOverride.ForKey<IFoo>().Eq("Foo2")));
}
}
var fooClient = container.Resolve<FooClient>();
Ninject(using binding metadata):
class FooClient{
public FooClient(Named["Foo2"] IFoo fooDependency)
{
}
....
}
is even admitted in the documentation to be an anti-pattern by directly using service locator to ask for a specific implementation instead of relying on auto-resolution.
The Unity & Castle Windsor worked exactly as expected, fooClient used the Foo2 implementation of IFoo. It was automatically resolved.
Regarding the Ninject approach, this worked but that means it's hard-baked into the implementation of the higher-level component and I've violated dependency inversion principle. The nice part about the Unity/Windsor approach is the composition root(IOC setup) is the isolation point.
Is there something on the Ninject API that I missed that would allow me to preserve the DIP?