-
Notifications
You must be signed in to change notification settings - Fork 36
Factory interface: Referencing Named Bindings
In some cases when employing an Abstract Factory using the extension, one wants to use a specific Named Binding (i.e., where the Bind<T> expression terminates in a .Named("name") subexpression). The default instance provider of the extension uses a convention of attempting to resolve an instance based on a named binding whenever the name of the method declaration on the abstract factory interface method starts with “Get”. For instance:-
IFoo GetMySpecialFoo()
leads to the internally generated code performing the equivalent of the following resolution call:
resolutionRoot.Get<IFoo>("MySpecialFoo");
Instead of specifying a string in the named binding like in the example above, you can use the extension method NamedLikeFactoryMethod.
For example, if you have a factory like this:
public interface IFooFactory
{
IFoo GetMySpecialFoo();
}
Instead of defining the binding with a name specified by a string:
kernel.Bind<IFoo>().To<Foo>().Named("MySpecialFoo")
You can write:
kernel.Bind<IFoo>().To<Foo>().NamedLikeFactoryMethod<IFooFactory>(f => f.GetMySpecialFoo())
This makes the naming convention explicit and therefore is easier to refactor.
If you wish to control the binding name based on a string in your code rather than this convention, this can be achieved by hooking in a custom instance provider implemented as follows:-
class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider
{
protected override string GetName(System.Reflection.MethodInfo methodInfo, object[] arguments)
{
return (string)arguments[0];
}
protected override Ninject.Parameters.ConstructorArgument[] GetConstructorArguments(System.Reflection.MethodInfo methodInfo, object[] arguments)
{
return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray();
}
}
using the following Binding expression syntax:-
this.Bind<IMyFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());