2010-09-09 5 views
8

Ich habe eine Situation, in der ich mein Benutzerobjekt Abhängigkeit injizieren möchte, sondern auch den aktuellen Benutzer in den IoC-Container platzieren. Ich möchte die folgenden Zeilen arbeiten:In Ninject 2.0, wie habe ich sowohl eine allgemeine Bindung als auch eine Bindung für einen bestimmten Fall?

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

Man könnte denken, Bindungen wie dies funktionieren würde:

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

Natürlich, das gibt:

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.

Ich verstehe den Fehler, da ein Benannte Bindung beschränkt nicht die Anwendung dieser Bindung, so dass beide Bindungen gelten. Es scheint klar zu sein, dass ich die kontextabhängige Bindung mit den .When *() Methoden verwenden muss, aber ich kann keine Möglichkeit finden, dies zu tun. Ich habe das Gefühl, dass es Methoden geben sollte, die erkennen, ob eine benannte Instanz angewendet wird. Etwas wie:

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

ich keinen Platz auf der IRequest Schnittstelle finden kann oder es Eigenschaften, die mir den Namen angefordert erzählt. Wie mache ich das?

Antwort

3

Diese Frage wurde auf der Mailingliste answerd: http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en


Wenn Sie den Benutzer zugreifen, indem Sie auf den Kernel Get Aufruf (was ich hoffe, dass Sie dies nicht tun), dann geben Sie die erste Bindung einen Namen als gut und Zugang Benutzer immer mit Namen. Tatsächlich gibt es eine Möglichkeit, eine Instanz von der Bindung ohne einen Namen zu erhalten. Aber weil ich es wärmstens empfehle, dies nicht zu tun, zeige ich hier nicht, wie das geht. Wenn Sie es immer noch so machen wollen, erzähle ich Ihnen später, wie das funktionieren würde.

Wenn Sie es besser und bevorzugte Art und Weise und injizieren um den Benutzer zu den Objekten zu tun, dass es als Abhängigkeit es erfordern, sind zwei Möglichkeiten:

  1. Je einfacher ein: Geben Sie den ersten Namen verbindlich und fügen Sie den Parametern z. B. ein benanntes Attribut hinzu Ctor ([Named ("NewUser") IUser newUser [Named ("Current")] IUser current)
  2. Oder die bevorzugte Art und Weise die Implementierungsklassen frei von dem IoC Rahmen zu halten: benutzerdefinierte Attribute angeben und hinzufügen sie zu den Parametern z ctor ([NewUser] IUser neuer Benutzer, [CurrentUser] IUser currentUser). Ändern Sie die Bindungen zu:

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

Sorry für die lange Verzögerung in der Reaktion, kann ich auch nicht davon, weil, wenn ein neuer Benutzer angefordert wird, dass durch NHibernate geschieht. Also kann ich keinen Namen oder ein Attribut hinzufügen. Ich könnte in den Fällen, wo ich den aktuellen Benutzer möchte, aber dann würde die neue Benutzerbindung immer noch gelten. –

Verwandte Themen