在 Ninject 2.0 中,如何同时拥有一般绑定和特定案例的绑定?

发布于 2024-09-18 14:11:21 字数 999 浏览 1 评论 0原文

我有一种情况,我想依赖注入我的用户对象,但也将当前用户放入 IoC 容器中。我希望以下几行起作用:

kernel.Get<User>(); // Should return a new User()
kernel.Get<User>("Current"); // Should return the current user

人们可能认为这样的绑定会起作用:

Bind<User>().ToSelf();
Bind<User>().ToMethod(LoadCurrentUser).InRequestScope().Named("Current");

当然,这给出了:

Ninject.ActivationException: Error activating User
More than one matching bindings are available.
Activation path:
1) Request for User

Suggestions:
1) Ensure that you have defined a binding for User only once.

我理解错误,因为命名绑定不限制该绑定的应用,因此两个绑定都适用。很明显,我需要将上下文绑定与 .When*() 方法一起使用,但我无法想出任何方法来做到这一点。我觉得应该有when 方法来检测是否应用了命名实例。例如:

// Not valid Ninject syntax
Bind<User>().ToSelf().WhenUnnamedRequested();
Bind<User>().ToMethod(LoadCurrentUser).WhenNamedRequested().InRequestScope().Named("Current");

我在 IRequest 接口上找不到任何位置,或者它的属性告诉我所请求的名称。我该怎么做?

I have a situation where I want to dependency inject my user object, but also place the current user in the IoC container. I want the following lines to work:

kernel.Get<User>(); // Should return a new User()
kernel.Get<User>("Current"); // Should return the current user

One might think bindings like this would work:

Bind<User>().ToSelf();
Bind<User>().ToMethod(LoadCurrentUser).InRequestScope().Named("Current");

Of course, that gives:

Ninject.ActivationException: Error activating User
More than one matching bindings are available.
Activation path:
1) Request for User

Suggestions:
1) Ensure that you have defined a binding for User only once.

I understand the error since a Named binding does not restrict the application of that binding, so both bindings apply. It seems clear that I need to use the contextual bind with the .When*() methods but I can't come up with any way to do that. I feel like there should be when methods that detect whether a named instance is applied. Something like:

// Not valid Ninject syntax
Bind<User>().ToSelf().WhenUnnamedRequested();
Bind<User>().ToMethod(LoadCurrentUser).WhenNamedRequested().InRequestScope().Named("Current");

I can't find any place on the IRequest interface or it's properties that tells me the name requested. How do I do this?

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

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

发布评论

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

评论(1

少女七分熟 2024-09-25 14:11:21

这个问题在邮件列表上得到了回答:
http://groups.google.com/group/ninject/browse_thread /thread/cd95847dc4dcfc9d?hl=en


如果您通过调用内核上的 Get 来访问用户(我希望您不要这样做),那么也为第一个绑定指定一个名称,并始终通过名称访问 User。实际上,有一种方法可以从没有名称的绑定中获取实例。但因为我衷心建议不要这样做,所以我不会在这里展示如何做到这一点。如果您仍然想这样做,我稍后会告诉您这是如何工作的。

如果您采用更好且更喜欢的方式,并将用户注入到需要它作为依赖项的对象中,则有两个选项:

  1. 更简单的一个:为第一个绑定指定名称并添加命名属性参数例如 ctor([Named("NewUser") IUser newUser, [Named("Current")] IUser
    currentUser)
  2. 或者保持实现类不受 IoC 框架影响的首选方法:指定自定义属性并将它们添加到参数中,例如 ctor([NewUser] IUser newUser, [CurrentUser]IUser currentUser )。将绑定更改为:

    Bind().ToSelf()
                .WhenTargetHas();
    Bind().ToMethod(LoadCurrentUser)
                .InRequestScope()
                .WhenTargetHas();
    

This question was answerd on the mailing list:
http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en


If you are accessing the user by calling Get on the kernel (which I hope you do not) then give the first binding a name as well and access User always by name. Actually, there is a way to get an instance from the binding without a name. But because I heartily recommend not to do this, I do not show how to to this here. If you still want to do it this way I'll tell you later how this would work.

If you are doing it the better and prefered way and inject the user to the objects that require it as dependency there are two options:

  1. The easier one: Give the first binding a name and add a named attribute to the parameters e.g. ctor([Named("NewUser") IUser newUser, [Named("Current")] IUser
    currentUser)
  2. Or the prefered way to keep the implementation classes free of the IoC framework: Specify custom attributes and add them to the parameters e.g. ctor([NewUser] IUser newUser, [CurrentUser]IUser currentUser). Change the Bindings to:

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