根据 method 属性将接口绑定到 ninject 中的 2 个不同的具体对象

发布于 2024-08-28 05:23:39 字数 988 浏览 10 评论 0原文

我有 2 个不同的具体对象,让我们保存 ConcreteOne 和 ConcreteTwo。其中每一个都实现一个接口ILooseyGoosey。我希望 ninject 根据该方法的属性调用不同的方法。

这是我到目前为止所拥有的:

public class ConcreteOne : ILooseyGoosey
{
  public void SomeMethod() { };
}
public class ConcreteTwo : ILooseyGoosey
{
  public void SomeMethod() { } ;
}
public interface ILooseyGoosey
{
  [CallConcreteTwo()]
  void SomeMethod();
}

这是我在 Ninject 模块中定义的:

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

我收到以下错误:

System.NotSupportedException:注册服务时出错 ILooseyGoosey:为服务声明了多个默认绑定。 找到 2 个默认绑定:

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 : ILooseyGoosey
{
  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:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

问题在于您将一个接口分配给两个实现,而没有任何条件逻辑。您应用的逻辑仅适用于注入的方法。 Ninject 不知道要使用哪个绑定,因为您表明它们都是默认的。

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.

滿滿的愛 2024-09-04 05:23:39

不确定您是否仍然需要答案,基于元数据的方法是正确的选择。您希望在 Ninject 2.0 中以元数据方式进行绑定。请参阅与 Ninject 2.0 的上下文绑定

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

月野兔 2024-09-04 05:23:39

不是我写的。请参阅: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.

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文