Gemäß der RavenDb tutorial benötigt Ihre Anwendung genau eine IDocumentStore
Instanz (pro Datenbank nehme ich an). A IDocumentStore
ist Thread-sicher. Es produziert IDocumentSession
Instanzen und sie repräsentieren eine unit of work in RavenDB, und das sind nicht Thread-Safe. Sie sollten daher nicht Sitzungen zwischen Threads teilen.
Wie Sie Ihren Container für die Verwendung mit RavenDb einrichten, hängt hauptsächlich vom Design der Anwendung ab. Die Frage ist: Was möchten Sie den Verbrauchern bieten? Die IDocumentStore
oder die IDocumentSession
?
Wenn Sie mit dem IDocumentStore
gehen, Ihre Registrierung könnte wie folgt aussehen:
// Composition Root
IDocumentStore store = new DocumentStore
{
ConnectionStringName = "http://localhost:8080"
};
store.Initialize();
container.RegisterSingle<IDocumentStore>(store);
Ein Verbraucher könnte wie folgt aussehen:
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();
}
}
}
Da die IDocumentStore
injiziert wird, sind die Verbraucher selbst verantwortlich für Verwalten der Sitzung: Erstellen, Speichern und Entsorgen. Dies ist sehr praktisch für kleine Anwendungen, oder zum Beispiel wenn Sie die RavenDb-Datenbank hinter einer repository verstecken, wo Sie innerhalb der repository.Save(entity)
Methode session.SaveChanges()
aufrufen.
Allerdings fand ich diese Art der Verwendung einer Arbeitseinheit für größere Anwendungen problematisch. Was Sie stattdessen tun können, ist die Injektion der IDocumentSession
in die Verbraucher. In diesem Fall könnte Ihre Registrierung wie folgt aussehen:
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());
Beachten Sie, dass Sie die Simple Injector ASP.NET Integration NuGet package (oder schließen die SimpleInjector.Integration.Web.dll zu einem Projekt, das im Standard-Download enthalten ist) sein müssen Kann die Erweiterungsmethode RegisterPerWebRequest
verwenden.
Die Frage wird jetzt, wo session.SaveChanges()
anrufen?
Es gibt eine Frage über die Registrierung der Einheit der Arbeiten pro Webanforderung, die auch die Frage SaveChanges
betrifft. Bitte werfen Sie einen Blick auf diese Antwort: One DbContext per web request…why?. Wenn Sie die Wörter DbContext
durch IDocumentSession
und DbContextFactory
durch IDocumentStore
ersetzen, können Sie es im Zusammenhang mit RavenDb lesen. Beachten Sie, dass die Vorstellung von Geschäftstransaktionen oder Transaktionen im Allgemeinen nicht so wichtig ist, wenn Sie mit RavenDb arbeiten, aber ich weiß es ehrlich gesagt nicht. Das müssen Sie selbst herausfinden.