Configurazione del repository generico con Windsor

Sono fuori di idee su come configurare il contenitore Windsor giusto da usare con i repository nell’app Windows. Ho un repository di implementazione del repository generico, dove T è un tipo di quadro, ha una dipendenza IDatacontextProvider, che fornisce datacontext per esso:

public class Repository : IRepository where T : class { protected DataContext DataContext; public Repository(IDataContextProvider dataContextProvider) { DataContext = dataContextProvider.DataContext; } .... } 

E per cose semplici tutto funziona bene con la seguente configurazione:

  container.Register( Component.For() .ImplementedBy() .Lifestyle.Transient, Component.For(typeof(IRepository)) .ImplementedBy(typeof(Repository)) .Lifestyle.Transient, .... 

I problemi si verificano quando cerco di unire entity framework diverse da diversi repository, purché ciascuna istanza di repository abbia un’istanza di contesto dati diversa.
Ad esempio, ho un servizio semplice:

 public class SimpleService : ISimpleService { public SimpleService(IRepository, IRepository) { .... } } 

Potrei rendere IDataContextProvider come Singleton, ma penso che porterebbe problemi ancora più grandi.
Potrei passare IDataContextProvider a SimpleService e provare a risolvere le istanze del repository, ma ciò richiederebbe un codice aggiuntivo per rendere il servizio facilmente testabile e richiederebbe dipendenze aggiuntive. Qualcuno potrebbe avere un’idea migliore di come risolverlo?

aggiornamento: seguendo i consigli, ho creato un repository factory (è leggermente diverso dal proposto in risposta, non ha dipendenza diretta da datacontext, ma l’idea è molto simile):

  public interface IRepositoryFactory { IRepository GetRepository() where T:class; } public class RepositoryFactory : IRepositoryFactory { private readonly IDataContextProvider dataContextProvider; public RepositoryFactory(IDataContextProvider dataContextProvider) { this.dataContextProvider = dataContextProvider; } public IRepository GetRepository() where T : class { return new Repository(dataContextProvider); } } 

Che dire di avere un altro livello intermedio, come ad esempio RepositoryFactory? Quello potrebbe avere uno stile di vita transitorio. Tutti i repository creati dalla fabbrica condividono la stessa istanza di DataContext. Dovresti anche modificare le classi del tuo repository in modo che prendano un’istanza DataContext invece di DataContextProvider.

 public class RepositoryFactory : IRepositoryFactory { protected DataContext dataContext; public RepositoryFactory(IDataContextProvider provider) { dataContext = dataContextProvider.DataContext; } public IRepository GetRepository() { return new Repository(dataContext); } } public class SimpleService : ISimpleService { public SimpleService(IRepositoryFactory factory) { .... } } 

IDatacontextProvider suona come un’interfaccia di fabbrica e questi sono solitamente definiti come singleton nell’iniezione delle dipendenze. Vedo diversi potenziali percorsi per una soluzione:

  1. Non conosco i dettagli della tua applicazione, ma forse puoi scrivere il tuo manager stile di vita per IDatacontextProvider (dal momento che non dici né singleton né transient ti si addice).
  2. Se si desidera garantire che lo stesso IDatacontextProvider sia passato tra i repository, forse si dovrebbe pensare di IDatacontextProvider esplicitamente come parametro del metodo , invece di una dipendenza iniettata.
  3. @ La risposta di Can è anche una ansible soluzione, l’ho usata io stesso una volta.

Il tuo problema è nella configurazione dello stile di vita. Ho avuto gli stessi problemi. Devi configurare i tuoi repository con uno stile di vita PerWebRequest. Questo mi ha dato un buon incremento delle prestazioni e riducendo i miei errori da dozzine a zero.

Sul mio blog è ansible trovare un semplice esempio http://marcofranssen.nl dell’iniezione di dipendenza in combinazione con mvc3 e codice EF prima.