ninject 2.0中基于参数的绑定

时间:2010-03-18 13:44:32

标签: parameters ninject conditional-binding contextual-binding

我想在ninject中使用条件绑定,基于传递的参数。我有类似下面的内容:

public class Subject
{
}

public interface ITarget
{
}

public class Target1 : ITarget
{
}

public class Target2 : ITarget
{
}

现在我需要实例化ITarget接口:

    public void MethodName(IKernel kernel)
    {
        ITarget target1 = kernel.Get<ITarget>(new Parameter("name", new Subject(), true)); // Should be instance of Target1
        ITarget target2 = kernel.Get<ITarget>(); // Should be instance of Target2
    }

我有定义正确绑定的问题。我尝试了以下方法:

kernel.Bind<ITarget>().To<Target1>().When(Predicate);
kernel.Bind<ITarget>().To<Target2>();

private bool Predicate(IRequest request)
{
    IParameter parameter = request.Parameters.Count == 0 ? null : request.Parameters[0];
    if (parameter == null)
    {
        return false;
    }
    object parameterValue = parameter.GetValue( /*what to put here?*/);
    return parameterValue != null && parameterValue.GetType().IsAssignableFrom(typeof(Subject));
}

但我不知道如何获取传递参数的值。我需要将IContext实例传递给GetValue方法,但不知道如何获取IContext的有效实例。或者也许有更好的方法来完成我的任务?

编辑: BindingMetadata是解决我的问题的更好方法。有关详细信息,请参阅Contextual bindings with Ninject 2.0

此致

2 个答案:

答案 0 :(得分:2)

IRequest.ParentContext没有给你足够的支持吗?

此外,如果您要查找的只是使用名称来消除多个实例的歧义[并且您每次都能够提供它并且很乐意以明确的服务位置方式工作,而不是使用DI作为IDeity意图],然后在绑定方面有一个名称和WithName的Get重载。

编辑:花了一些时间在Reflector,但仍然没有更明智。参数机制似乎是为了覆盖实际绑定发生的 context 中的特定值,而不是选择适用的绑定的一部分。建立一个上下文只能在一个地方内部完成(虽然Context有一个公共ctor)所以它看起来不像是一个整洁的工厂。

您的实际场景是否适合约束机制(使用名称进行过滤只是最简单的情况)。也就是说,你可以表达你的Get

_kernel.Get<ITarget>( (Ninject.Planning.Bindings.BindingMetadata metadata)=>metadata.Has("x") );

希望@Ian Davis很快就会到来,因为我也想知道答案:D

答案 1 :(得分:1)

IIRC请求可以是多个上下文的一部分。您看到的参数只是您在Get调用中指定的参数。在您给出的示例中,您应该能够将null作为IContext传递以获取主题实例。由于您提供的是对象而不是回调,因此该参数将回调构造为ctx =&gt;价值 - &gt;因此回调不使用您提供的上下文值。