ninject 2.0 中基于参数的绑定

发布于 2024-08-26 05:01:20 字数 1349 浏览 7 评论 0原文

我想根据传递的参数在 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 的上下文绑定

有关详细信息,

I want to use conditional binding in ninject, based on passed parameters. I have something like below:

public class Subject
{
}

public interface ITarget
{
}

public class Target1 : ITarget
{
}

public class Target2 : ITarget
{
}

And now I need to instantiate ITarget interface:

    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
    }

I have problems to define proper bindings. I tried the following:

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));
}

but I don't know how to get value of passed parameter. I need to pass IContext instance to GetValue method, but don't know how to get valid instance of IContext. Or maybe there is better way to accomplish my task?

EDIT:
BindingMetadata is better way to solve my problem. See Contextual bindings with Ninject 2.0 for details

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木有鱼丸 2024-09-02 05:01:20

IRequest.ParentContext 还不够吗?

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

编辑:在 Reflector 上花了一些时间,但我仍然没有聪明多少。参数机制似乎是为了覆盖实际绑定发生的上下文中的特定值,而不是作为选择适用的绑定的一部分。建立上下文仅在内部的一个地方完成(尽管 Context 有一个公共构造函数),因此看起来没有一个整洁的工厂可以做到这一点。

你的实际场景是否正好符合约束机制(其中使用名称进行过滤只是最简单的情况)。即,您能否将您的 Get 表达为:

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

希望 @Ian Davis 将是我也很想知道答案:D

Does IRequest.ParentContext not give you enough ?

Also, if all you are looking for is to use a Name to disambiguate multiple instances [and you'll be in a position to provide it each time and are happy to work in that explicit Service Location manner instead of using DI as IDeity intended], then there is a Get overload with a name and a WithName for on the Bind side.

EDIT: Spent some time in Reflector but am still not much wiser. The parameters mechanism seems to be for the purposes of overriding specific values in the context of an actual binding happening, not as part of selecting the binding that applies. Establishing a context is only done in one place internally (though Context has a public ctor) so it doesnt look like there's a neat factory for that.

Does your actual scenario happen to fit the constraint mechanism (of which using a name to filter is just the simplest case). i.e., can you express your Get as something like:

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

Hopefully @Ian Davis will be along soon as I'd love to know the answer too :D

我做我的改变 2024-09-02 05:01:20

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

IIRC a request can be part of several contexts. The parameters you see are only parameters that you specify in the Get call. In the example you give, you should be able to pass null as the IContext in order to get your subject instance. Since you supply an object instead of a callback, the parameter constructs a callback as ctx => value -> thus the callback doesn't use the context value you supply.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文