在Ninject 2.0中,如何为特定案例同时具有通用绑定和绑定?

时间:2010-09-09 14:54:08

标签: ioc-container ninject ninject-2

我有一种情况,我希望依赖注入我的用户对象,但也将当前用户放在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 *()方法的上下文绑定,但我无法想出任何方法来做到这一点。我觉得应该有什么方法可以检测是否应用了命名实例。类似的东西:

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

我在IRequest界面上找不到任何地方,或者它的属性告诉我要求的名称。我该怎么做?

1 个答案:

答案 0 :(得分:3)

这个问题已在邮件列表中回答: 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<User>().ToSelf()
                .WhenTargetHas<NewUserAttribute>();
    Bind<User>().ToMethod(LoadCurrentUser)
                .InRequestScope()
                .WhenTargetHas<CurrentUserAttribute>();