2013-04-16 13 views
5

Ich habe eine generische Schnittstelle IRepository<T> und zwei Implementierungen xrmRepository<T> und efRepository<T>Ninject Kontext-bezogene Bindung w/Open Generics

ich die Bindung basierend auf T, genauer gesagt xrmRepository verwenden ändern will, wenn T von Entity ableitet. Wie kann ich das erreichen?

Ich habe derzeit:

kernel.Bind(typeof(IRepository<>)).To(typeof(efRepository<>)).InRequestScope(); 
kernel.Bind(typeof(IRepository<>)).To(typeof(xrmRepository<>)).When(request => request.Service.GetGenericArguments()[0].GetType().IsSubclassOf(typeof(Entity))).InRequestScope(); 

Aber wenn ich versuche IRepository<Contact> zu lösen geht es zu efRepository, obwohl Kontakt Entity erbt.

Ich möchte keine Named Bindings verwenden, sonst muss ich die Namen überall hinzufügen.

Antwort

2

Sie können die Bindungen auch so definieren. Ich weiß nichts über Laufzeit-Performance, aber ich denke, dass es auf diese Weise besser lesbar ist. Und wenn ich etwas nicht verpasse, sollte es zum gleichen Verhalten führen.

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(efRepository<>)) 
     .InRequestScope(); 

kernel.Bind<IRepository<Entity>>() 
     .To<xrmRepository<Entity>>() 
     .InRequestScope(); 

bearbeiten

Wenn das Ziel ist xrmRepository für jede Klasse von Entity erben diese die

kernel.Bind(typeof(IRepository<>)) 
        .To(typeof(XrmRepository<>)) 
        .When(request => typeof(Entity).IsAssignableFrom(request.Service.GetGenericArguments()[0])); 
+0

Funktionierte nicht mit der Basisklasse "Entity". Noch immer an efRepository gebunden. Funktioniert, wenn die Klasse selbst verwendet wird (wie Kontakt). –

+0

Möchten Sie IRepository für alle Unterklassen von Entity in xmRepository auflösen? – treze

+0

Ja! Aber ich werde wahrscheinlich am Ende ein IXRM Repository: IRepository erstellen, da ich es nicht zum Laufen kriege. –

1

Verwenden Sie die Methode When, um eine Bindungsbedingung zu deklarieren. Beispiel ist unten

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(efRepository<>)) 
     .When(request => request.Service.GetGenericArguments()[0] == typeof(Entity)) 
     .InRequestScope(); 

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(xrmRepository<>)) 
     .InRequestScope(); 

kernel.Get<IRepository<Entity>>(); //will return efRepository<Entity> 

kernel.Get<IRepository<int>>(); //will return xrmRepository<int> 
+0

Halten Trick tun sollten verwenden immer die Fehlermeldung „GenericArguments [0],‚sf2015 .Infrastructure.Xrm.Contact ', on' sf2015.Repositories.sfRepository'1 [T] 'verstößt gegen die Einschränkung des Typparameters' T '. ". Weitere Informationen: f2015.Infrastructure.Xrm.Contact ist vom Typ Microsoft.Xrm.Sdk.Entity. Ich musste First() zu [0] ändern und das xrmRepository ist derjenige, der mit Entity binden soll. Siehe aktualisierte Frage. –

+0

@JoaoLeme geben Interface-Definitionen und ihre Implementierung. Geben Sie auch Beispiele für Aufruf ** Get ** und erwartete Ergebnisse –

+0

Wenn Get von einem neuen Modul aufrufen funktioniert es, wenn ich ... GetGenericArguments(). First() == typeof (Kontakt) ... und rufen Sie kernel.Get >(); aber wenn ich Contact auf der Bindung durch seine geerbte Klasse Entity ersetze und kernel.Get >() erhalte ich den gleichen Fehler. By the way, funktioniert die gleiche Troubleshoot Trick (Ersetzung von Entität durch Kontakt) unter RegisterServices in NinjectWebCommon nicht (Entweder gibt mir den gleichen Fehler). –

Verwandte Themen