Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject multiple binding of injected interface

Tags:

c#

.net

ninject

I have the following classes:

using System;

interface IA { }

class A1 : IA { }

class A2 : IA { }

class B
{
    public B(IA a) {}
}

class BProvider : Provider<B>
{
    IA _a;

    public BProvider(IA a) { _a=a; }

    protected override B CreateInstance(IContext context) { return new B(_a); }
}

ninject module Load() code:

Bind<IA>().To<A1>();
Bind<IA>().To<A2>();
Bind<B>().ToProvider<BProvider>();

main code:

kernel.GetAll<IA>(); // works fine
kernel.GetAll<B>(); // I expect to get IEnumerable<B> with two elements, but instead of this I get an error that there are multiple bindings of IA and ninject cannot determine which to use

So the question is if I can make the last statement work as expected or do it some other way?

like image 279
Nikolay Bobrovskiy Avatar asked Jul 26 '12 19:07

Nikolay Bobrovskiy


1 Answers

It will throw that exception because Ninject will need to create an instance of object of type BProvider. To do it, it has to fill in the dependency on IA. But moment... there are two bindings on IA, which one should I choose?....

You can use some conditional binding to decide which implementation should be used. One way is with NamedAttribute:

Bind<IA>().To<A1>();
Bind<IA>().To<A2>().Named("SecondImpl");
Bind<B>().ToProvider<BProvider>();


class BProvider : Provider<B>
{
    IA _a;

    public BProvider([Named("SecondImpl")]IA a) { _a=a; }

    protected override B CreateInstance(IContext context) { return new B(_a); }
}

In this case A1 will be injected as default where NamedAttribute is not specified.

or like @Remo Gloor explains in this post: Configuring Ninject

Bind<IA>().To<A1>();
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl");
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl");

This is bit cleaner, because you dont have to tie your code to Ninject and can just let it on configuration (in one place).

like image 60
mipe34 Avatar answered Oct 20 '22 12:10

mipe34