我想在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
此致
答案 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;因此回调不使用您提供的上下文值。