I have two objects that support the same interface. Each object has its own configuration object that gets passed as a constructor argument. I want Ninject to use the name of the object to resolve the same of its configuration parameter. Currently, if I do kernel.Get("one") it fails to resolve ThingConfig, even though there is exactly one registered by that name. (EDIT: Fixed example to include ThingConfig binding):
class MyService
{
public MyService([Named("one")] IThing one, [Named("two")] IThing two) {}
}
class ThingConfig {}
class Thing(ThingConfig cfg) : IThing {}
And in my binder:
Bind<IThing>().To(typeof(Thing)).InSingletonScope().Named("one");
Bind<IThing>().To(typeof(Thing)).InSingletonScope().Named("two");
Bind<ThingConfig>().ToMethod(() => new ThingConfig()).InSingletonScope().Named("one");
Bind<ThingConfig>().ToMethod(() => new ThingConfig()).InSingletonScope().Named("two");
I think I found an acceptable solution involving Named and WhenAnyAncestorNamed.
I wanted to essentially have a "tag" that identified the scope, so the name fits the bill. I wanted to be able to resolve object by name, or when injected into objects activated by that name. To do that, I had to bind the object twice - once by name, and once for any ancestor with that name:
Bind(interfaces.ToArray()).To(objectType).InSingletonScope().Named(name);
Bind(interfaces.ToArray()).ToMethod(
ctx => ctx.Kernel.Get(ctx.Request.Service, name)).WhenAnyAncestorNamed(name);
If anyone knows a more elegant solution, I'm all ears.