3

我想根据传递的参数在 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 是解决我的问题的更好方法。有关详细信息,请参阅Ninject 2.0 的上下文绑定

问候

4

2 回答 2

2

IRequest.ParentContext给你的还不够吗?

此外,如果您正在寻找的只是使用名称来消除多个实例的歧义[并且您每次都可以提供它,并且很乐意以明确的服务位置方式工作,而不是像 IDeity 那样使用 DI] ,然后在 Bind 端有一个带有名称和 WithName for 的 Get 重载。

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

您的实际情况是否恰好适合约束机制(其中使用名称进行过滤只是最简单的情况)。即,您可以将您的表达Get为:

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

希望@Ian Davis会尽快出现,因为我也很想知道答案:D

于 2010-03-18T14:31:01.343 回答
1

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

于 2010-03-20T19:26:28.623 回答