当为同一类型找到多个绑定时,Ninject会显示错误

时间:2017-10-11 06:20:58

标签: c# dependency-injection ninject

在Ninject中,如果有多个绑定可用于同一类型,则会显示错误。 有没有办法代替显示错误它将它绑定为null?

class TestModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        Bind<ITemp<SomeType>>().To<TempClass1>().Named("temp");
        Bind<ITemp<SomeType>>().To<TempClass2>().Named("temp1");
        Bind<Func<string, ITemp<SomeType>>>().ToMethod(ctx => name =>
        {
            Ninject.IKernel kernel = new StandardKernel(new NinjectSettings 
                                       { AllowNullInjection = true }, 
                                        new TestModule());
            return kernel.Get<ITemp<SomeType>>(name);
        });
    }
}

//Test Class
public class TestClass
{
    private readonly ITemp<SomeType> temp;
    private readonly Func<string,ITemp<SomeType>> _createRepository; 
    public TestClass(ITemp<SomeType> temp = null, 
                     Func<string,ITemp<SomeType>> _createRepository = null)
    {
        this.temp = temp;
        this._createRepository = _createRepository;
    }

    public void fun(string bindingName = null){
        if(bindingName != null){
            var repo = _createRepository(bindingName);
            repo.SomeFunction();
        }
        else {
            temp.SomeFunction();
        }
    }
}

public static void Main()
{
    Ninject.IKernel kernel = new StandardKernel(new NinjectSettings { 
                             AllowNullInjection = true }, new TestModule());
    var testObject = kernel.Get<TestClass>();

    //if named bindings are used 
    //testObj.fun("temp");

   //if named bindings are not defined then
   //testObj.fun();
}

当我尝试获取TestClass的实例时,它会说无法解析ITemp找到多个绑定。 根据我的要求,我希望TestClass中的temp field被注入为null。

2 个答案:

答案 0 :(得分:1)

您可以对依赖项使用named绑定。

来自ninject wiki:

  

命名绑定是条件的最简单(也是最常见)形式   绑定,使用方法如下:

     

在类型绑定中,为。注册多个类型绑定   相同的服务类型,但添加绑定元数据,以便您能够   在以后的情况下指出哪一个适合: -

Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");
     

在目标位置,您指定要在给定上下文中使用的名称: -

class WeakAttack {
    readonly IWeapon _weapon;
    public WeakAttack([Named("Weak")] IWeapon weakWeapon){
        _weapon = weakWeapon;
    }
    public void Attack(string victim){
        Console.WriteLine(_weapon.Hit(victim));
    }
}
     

或者,您可以以编程方式直接请求特定命名的服务实例(但要小心 - 直接这样做   通常执行以下操作:服务位置反模式的实例:

kernel.Get<IWeapon>("Weak");

或者您可以使用attribute-based helpers指定不同的案例

答案 1 :(得分:1)

使用依赖注入时,Null不能很好地运行。当您需要代表null的服务时,您应该怎么做才能使用Null Object Pattern

public class NullTemp : ITemp<SomeType>
{
    // provide no-op implementation
    public void DoSomething()
    {
    }
}

然后,应更改服务实施中的任何null检查,以检查NullTemp类型。

//if (temp == null)
if (temp.GetType().Equals(typeof(NullTemp)))

由于您的示例中没有对您的可归属依赖项进行任何null检查,因此很难想象它是如何工作的。