Skip to content

Factory interface: Referencing Named Bindings

James Manning edited this page May 24, 2013 · 14 revisions

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");

Using NamedLikeFactoryMethod extension method to get name directly from factory method

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.

Example customisation: Treating the first factory method parameter as a name specifier

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());

Clone this wiki locally