开发者

Binding an interface to 2 different concrete objects in ninject based on the method attribute

开发者 https://www.devze.com 2022-12-25 19:28 出处:网络
I have 2 different concrete objects, lets save ConcreteOne and ConcreteTwo. Each of these implement an interface ILooseyGoosey. I would like ninject to call a different method depending on the attribu

I have 2 different concrete objects, lets save ConcreteOne and ConcreteTwo. Each of these implement an interface ILooseyGoosey. I would like ninject to call a different method depending on the attribute on that method.

This is what I have so far:

public class ConcreteOne : ILooseyGoosey
{
  public void SomeMethod() { };
}
public class ConcreteTwo : ILoo开发者_如何学CseyGoosey
{
  public void SomeMethod() { } ;
}
public interface ILooseyGoosey
{
  [CallConcreteTwo()]
  void SomeMethod();
}

This is what I have defined in my Ninject module:

public override void Load()
{
  Bind<ILooseyGoosey>().To<ConcreteOne>().InjectMethodsWhere(mi => mi.GetCustomAttributes(true).Where(a => a.GetType() == typeof(CallConcreteTwoAttribute)).Count() == 0);
  Bind<ILooseyGoosey>().To<ConcreteTwo>().InjectMethodsWhere(mi => mi.GetCustomAttributes(true).Where(a => a.GetType() == typeof(CallConcreteTwoAttribute)).Count() > 0);
}

I get the error of:

System.NotSupportedException : Error registering service ILooseyGoosey: Multiple default bindings declared for service. Found 2 default bindings:


The problem is that you are assigning one interface to two implementations without any conditional logic. The logic you are applying is only applied to which methods are injected. Ninject has no idea which binding to use since you are indicating that they are both default.


Not sure if you still need the answer, meta data based approach is the way to go. You'd want to bind in the meta data way in Ninject 2.0. Refer Contextual bindings with Ninject 2.0


Not written by me. Please see: http://www.ninject.org/wiki.html

Ninject
Download it Extensions Contribute Visit the Dojo Speak up Sponsors Merchandise

Version:  
»Ninject
»MVC3
Multi injectionEdit PagePage History
Ninject allows you to inject multiple objects bound to a particular type or interface. For example, if we have our IWeapon interface, and two implementations, Sword and Dagger:

public interface IWeapon
{
    string Hit(string target);
}

public class Sword : IWeapon 
{
    public string Hit(string target) 
    {
        return "Slice " + target + " in half";
    }
}

public class Dagger : IWeapon 
{
    public string Hit(string target) 
    {
        return "Stab " + target + " to death";
    }
}
Here we have the Samurai class. You can see that its constructor takes an array of IWeapon.

public class Samurai 
{
    readonly IEnumerable allWeapons;
    public Samurai(IWeapon[] allWeapons) 
    {
        this.allWeapons = allWeapons;
    }

    public void Attack(string target) 
    {
        foreach (IWeapon weapon in this.allWeapons)
            Console.WriteLine(weapon.Hit(target));
    }
}
We can create bindings from the IWeapon interface to the Sword and Dagger types.

class TestModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        Bind().To();
        Bind().To();
    }
}
Finally, a kernel is created with the module we defined above. We ask Ninject for an instance of a Samurai. Now, when you ask the Samurai to attack, you will see it has been given an array of all the types bound to IWeapon.

class Program
{
    public static void Main() 
    {
        Ninject.IKernel kernel = new StandardKernel(new TestModule());

        var samurai = kernel.Get();
        samurai.Attack("your enemy");
    }
}
And you’ll see:

Stab your enemy to death
Slice your enemy in half
The kernel also exposes a GetAll method which lets you generate the same output by doing:

class Program
{
    public static void Main() 
    {
        Ninject.IKernel kernel = new StandardKernel(new TestModule());

        IEnumerable weapons = kernel.GetAll();
        foreach(var weapon in weapons)
            Console.WriteLine(weapon.Hit("the evildoers"));
    }
}
Continue reading: Object Scopes

Enkari
Ninject is the illegitimate brainchild of Nate Kohari. Copyright ©2007-2012 Enkari, Ltd and the Ninject project contributors.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号