2013-04-16 12 views
5

ho un'interfaccia generica IRepository<T> e due implementazioni xrmRepository<T> e efRepository<T>Ninject contestuale Binding w/Open Generics

voglio cambiare l'associazione sulla base di T, più specificamente utilizzare xrmRepository quando T deriva da Entity. Come posso farlo?

Al momento ho:

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(); 

Ma quando provo a risolvere IRepository<Contact> va a efRepository, anche se di contatto eredita entità.

Non voglio usare Named Bindings altrimenti dovrò aggiungere i nomi ovunque.

risposta

2

È inoltre possibile definire i binding come questo. Non conosco le prestazioni del tempo di esecuzione, ma penso che sia più leggibile in questo modo. E se non mi manca qualcosa dovrebbe comportare lo stesso comportamento.

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

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

Modifica

Se l'obiettivo è quello di utilizzare xrmRepository per ogni classe che eredita da Entity questo dovrebbe fare il trucco

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

Non funziona con la classe base "Entity". Ancora vincolante per efRepository. Funziona se si utilizza la classe stessa (come Contatto). –

+0

Vuoi risolvere IRepository in xrmRepository per tutte le sottoclassi di Entity? – treze

+0

Sì! Ma probabilmente finirò per creare un IXRMRepository: IRepository perché non riesco a farlo funzionare. –

1

Utilizzare il metodo When per dichiarare una condizione di associazione. L'esempio è riportato sotto

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

continui a ricevere l'errore "GenericArguments [0], 'sf2015 .Infrastructure.Xrm.Contact ', su' sf2015.Repositories.sfRepository'1 [T] 'viola il vincolo del parametro type' T '. ". Informazioni di tipo addizionale: f2015.Infrastructure.Xrm.Contact è di tipo Microsoft.Xrm.Sdk.Entity. Ho dovuto cambiare First() con [0] e xrmRepository è quello che si dovrebbe legare con Entity. Vedi domanda aggiornata. –

+0

@JoaoLeme fornisce definizioni di interfaccia e la loro implementazione. Fornisci anche esempi di chiamate ** Ottieni ** e risultati attesi –

+0

Quando chiami Ricevi da un nuovo modulo funziona se uso ... GetGenericArguments(). First() == typeof (Contatto) ... e chiama kernel.Get >(); ma se sostituisco Contact sull'associazione dalla sua classe ereditata Entity e chiamo kernel.Get >() Ottengo lo stesso errore. A proposito, fare lo stesso trucco di risoluzione dei problemi (sostituendo Entity by Contact) in RegisterServices in NinjectWebCommon non funziona (ad ogni modo mi dà lo stesso errore). –

Problemi correlati