5

Sto usando Simple Injector per un IOC in un'applicazione web MVC 3. Sto usando RavenDB per l'archiviazione dei dati. Ci sono diverse considerazioni sull'uso di RavenDB in un'applicazione mvc 3. Ho cercato un po 'su come collegare un IoC per usare RavenDB ma non ho scoperto come collegare un semplice iniettore per usare RavenDB. Qualcuno può spiegare come collegare un semplice iniettore per utilizzare RavenDB in un'applicazione web MVC 3?Come configurare Simple Injector IoC per usare RavenDB

grazie.

risposta

13

In base allo RavenDb tutorial, l'applicazione richiede esattamente un'istanza IDocumentStore (per database presumo). A IDocumentStore è thread-safe. Produce istanze IDocumentSession e rappresentano un unit of work in RavenDB e quelle sono non thread-safe. Pertanto, è consigliabile non condividere sessioni tra thread.

Come configurare il contenitore per l'uso con RavenDb dipende principalmente dalla progettazione dell'applicazione. La domanda è: cosa vuoi iniettare ai consumatori? IDocumentStore o IDocumentSession?

Quando si va con la IDocumentStore, la registrazione potrebbe essere la seguente:

// Composition Root 
IDocumentStore store = new DocumentStore 
{ 
    ConnectionStringName = "http://localhost:8080" 
}; 

store.Initialize(); 

container.RegisterSingle<IDocumentStore>(store); 

Un consumatore potrebbe assomigliare a questo:

public class ProcessLocationCommandHandler 
    : ICommandHandler<ProcessLocationCommand> 
{ 
    private readonly IDocumentStore store; 

    public ProcessLocationCommandHandler(IDocumentStore store) 
    { 
     this.store = store; 
    } 

    public void Handle(ProcessLocationCommand command) 
    { 
     using (var session = this.store.OpenSession()) 
     { 
      session.Store(command.Location); 

      session.SaveChanges(); 
     }    
    } 
} 

Perché il IDocumentStore viene iniettata, i consumatori sono essi stessi responsabili della gestione della sessione: creazione, salvataggio e smaltimento. Questo è molto conveniente per le piccole applicazioni o, ad esempio, quando si nasconde il database RavenDb dietro a repository, dove si chiama session.SaveChanges() all'interno del metodo repository.Save(entity).

Tuttavia, ho trovato questo tipo di utilizzo di un'unità di lavoro problematico per le applicazioni più grandi. Quindi, ciò che puoi fare invece è iniettare il IDocumentSession nei consumatori. In questo caso la registrazione potrebbe essere la seguente:

IDocumentStore store = new DocumentStore 
{ 
    ConnectionStringName = "http://localhost:8080" 
}; 

store.Initialize(); 

// Register the IDocumentSession per web request 
// (will automatically be disposed when the request ends). 
container.RegisterPerWebRequest<IDocumentSession>(
    () => store.OpenSession()); 

Nota che è necessario il Simple Injector ASP.NET Integration NuGet package (o includere la SimpleInjector.Integration.Web.dll al progetto, che è incluso nel download di default) di essere in grado di utilizzare il metodo di estensione RegisterPerWebRequest.

La domanda ora diventa, dove chiamare session.SaveChanges()?

C'è una domanda sulla registrazione dell'unità di lavoro per richiesta web, che affronta anche la domanda su SaveChanges. Si prega di dare un'occhiata a questa risposta: One DbContext per web request…why?. Quando si sostituiscono le parole DbContext con IDocumentSession e DbContextFactory con IDocumentStore, sarà possibile leggerlo nel contesto di RavenDb. Si noti che forse la nozione di transazioni commerciali o transazioni in generale non è così importante quando si lavora con RavenDb, ma onestamente non lo so. Questo è qualcosa che dovrai scoprire da solo.