根据RavenDb 教程 http://www.geekbeing.com/2012/01/21/raven-db-tutorial,您的应用程序正好需要一个IDocumentStore
实例(我假设每个数据库)。 AIDocumentStore
是线程安全的。它产生IDocumentSession
实例,它们代表一个工作单元 http://martinfowler.com/eaaCatalog/unitOfWork.html在 RavenDB 中,这些是not线程安全。因此你应该not在线程之间共享会话。
如何设置容器以与 RavenDb 一起使用主要取决于应用程序设计。问题是:你想向消费者注入什么?这IDocumentStore
, 或者IDocumentSession
?
当你和IDocumentStore
,您的注册可能如下所示:
// Composition Root
IDocumentStore store = new DocumentStore
{
ConnectionStringName = "http://localhost:8080"
};
store.Initialize();
container.RegisterSingle<IDocumentStore>(store);
消费者可能看起来像这样:
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();
}
}
}
因为IDocumentStore
被注入后,消费者自己负责管理会话:创建、保存和处置。这对于小型应用程序非常方便,或者例如将 RavenDb 数据库隐藏在存储库 http://martinfowler.com/eaaCatalog/repository.html,你打电话的地方session.SaveChanges()
在 - 的里面repository.Save(entity)
method.
然而,我发现这种工作单元的使用方式对于较大的应用程序来说是有问题的。所以你可以做的是注入IDocumentSession
进入消费者。在这种情况下,您的注册可能如下所示:
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());
请注意,您需要简单注入器 ASP.NET 集成 NuGet 包 http://nuget.org/packages/SimpleInjector.Integration.Web(或包括SimpleInjector.Integration.Web.dll到您的项目,该项目包含在默认下载中)以便能够使用RegisterPerWebRequest
扩展方法。
现在的问题是,去哪里打电话session.SaveChanges()
?
有一个关于每个网络请求注册作品单元的问题,这也解决了以下问题SaveChanges
。请仔细看看这个答案:每个 Web 请求一个 DbContext……为什么? https://stackoverflow.com/a/10588594/264697。当你替换单词时DbContext
with IDocumentSession
and DbContextFactory
with IDocumentStore
,您将能够在 RavenDb 的上下文中阅读它。请注意,也许在使用 RavenDb 时,业务事务或一般事务的概念并不那么重要,但老实说我不知道。这是你必须自己去发现的事情。