2010-09-09 13 views
8

J'ai une situation où je veux dépendance injecter mon objet utilisateur, mais aussi placer l'utilisateur actuel dans le conteneur IoC. Je veux que les lignes suivantes pour:Dans Ninject 2.0, comment ai-je une liaison générale et une liaison pour un cas particulier?

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

On pourrait penser consolidations comme celui-ci travailleraient:

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

Bien sûr, cela donne:

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.

Je comprends l'erreur depuis une La liaison nommée ne limite pas l'application de cette liaison, les deux liaisons s'appliquent donc. Il semble clair que j'ai besoin d'utiliser le bind contextuel avec les méthodes .When *() mais je ne peux pas trouver un moyen de le faire. Je me sens comme il devrait y avoir quand les méthodes qui détectent si une instance nommée est appliquée. Quelque chose comme:

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

Je ne peux pas trouver un endroit sur l'interface IRequest ou ses propriétés qui me dit que le nom demandé. Comment puis-je faire cela?

Répondre

3

Cette question a été Answerd sur la liste de diffusion: http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en


Si vous accédez à l'utilisateur en appelant Get sur le noyau (qui je l'espère vous ne) donnent alors la première liaison d'un nom bien et accédez Utilisateur toujours par son nom. En fait, il existe un moyen d'obtenir une instance de la liaison sans nom. Mais parce que je recommande vivement de ne pas le faire, je ne montre pas comment à cela ici. Si vous voulez toujours le faire de cette façon, je vous dirai plus tard comment cela fonctionnera.

Si vous faites le mieux et le mode preferred et injectez l'utilisateur aux objets qui en ont besoin comme la dépendance, il y a deux options:

  1. Le plus facile un: Donnez la première liaison d'un nom et ajouter un attribut nommé aux paramètres cteur ([Nommé ("NewUser") IUser newUser, [Nommé ("Current")] IUser currentUser)
  2. Ou la manière preferred pour maintenir les cours de mise en œuvre libre du cadre IoC: Spécifiez les attributs personnalisés et ajouter eux aux paramètres par exemple ctor ([NewUser] IUser newUser, [CurrentUser] IUser currentUser). Modifier les liaisons à:

    Bind<User>().ToSelf() 
          .WhenTargetHas<NewUserAttribute>(); 
    Bind<User>().ToMethod(LoadCurrentUser) 
          .InRequestScope() 
          .WhenTargetHas<CurrentUserAttribute>(); 
    
+0

Désolé pour le long retard dans la réponse, je ne peux pas le faire parce que l'une de ces lorsqu'un nouvel utilisateur est demandée, ce qui se passe par NHibernate. Donc je ne peux pas ajouter un nom ou un attribut à cela. Je pourrais dans les cas où je veux l'utilisateur actuel, mais alors la nouvelle liaison d'utilisateur s'appliquerait toujours. –