Ninject可能将上下文绑定应用于绑定组?

时间:2014-02-19 19:56:22

标签: c# dependency-injection ninject

是否可以将上下文绑定应用于一组绑定?

基本上我想将相同的上下文绑定应用于多个绑定,在本例中是在模块中:

public class MyNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<IType1>().To<MyFirstType>();
        Bind<IType2>().To<MySecondType>();
        Bind<IType3>().To<MyThirdType>();
        // ...and so on

        // here I want to apply a contextual binding to all bindings previously defined in this module
        // something like:
        foreach (var binding in this.Bindings)
            binding.WhenInjectedInto(typeof(MyClass));
    }
}

1 个答案:

答案 0 :(得分:0)

这有点棘手,我不知道如何执行它。我所知道的是,我们只能使用一个条件。我担心覆盖你以前的背景,但后来我意识到不可能“结合”这些条件。

所以,如果你想这样做,试试吧:

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IType1>().To<MyFirstType>();
        Bind<IType2>().To<MySecondType>();
        Bind<IType3>().To<MyThirdType>();

        foreach (var binding in Bindings)
        {
            AssignedWhenInjectedInto<MyClass>(binding);
        }
    }

    public void AssignedWhenInjectedInto<T>(IBinding binding)
    {
        var parent = typeof (T);

        //Copied from Ninject's WhenInjectedInto<T> implementation
        if (parent.IsGenericTypeDefinition)
        {
            if (parent.IsInterface)
            {
                binding.BindingConfiguration.Condition = r =>
                    r.Target != null &&
                    r.Target.Member.ReflectedType.GetInterfaces().Any(i =>
                        i.IsGenericType &&
                        i.GetGenericTypeDefinition() == parent);
            }
            else
            {
                binding.BindingConfiguration.Condition = r =>
                    r.Target != null &&
                    r.Target.Member.ReflectedType.GetAllBaseTypes().Any(i =>
                        i.IsGenericType &&
                        i.GetGenericTypeDefinition() == parent);
            }
        }
        else
        {
            binding.BindingConfiguration.Condition = r => r.Target != null && parent.IsAssignableFrom(r.Target.Member.ReflectedType);
        }
    }
}

以下测试用于此:

[Test]
public void RewriteBindingConditionTest()
{
    _kernel = new StandardKernel(new MyModule());
    var instance = _kernel.Get<MyClass>();

    Assert.IsInstanceOf<MyFirstType>(instance.Type1);
    Assert.IsInstanceOf<MySecondType>(instance.Type2);
    Assert.IsInstanceOf<MyThirdType>(instance.Type3);

    try
    {
        _kernel.Get<MyOtherClass>();
    }
    catch (ActivationException)
    {
        Assert.Pass();
    }

    Assert.Fail("Bindings were injected into MyOtherClass while there was no configured binding for them.");
}

辅助班:

public class MyClass
{
    public IType1 Type1 { get; set; }
    public IType2 Type2 { get; set; }
    public IType3 Type3 { get; set; }

    public MyClass(IType1 type1, IType2 type2, IType3 type3)
    {
        Type1 = type1;
        Type2 = type2;
        Type3 = type3;
    }
}

public class MyOtherClass
{
    public IType1 Type1 { get; set; }
    public IType2 Type2 { get; set; }
    public IType3 Type3 { get; set; }

    public MyOtherClass(IType1 type1, IType2 type2, IType3 type3)
    {
        Type1 = type1;
        Type2 = type2;
        Type3 = type3;
    }
}

public class MyThirdType : IType3
{
}

public class MySecondType : IType2
{
}

public class MyFirstType : IType1
{
}

public interface IType3
{
}

public interface IType2
{
}

public interface IType1
{
}