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.