我在MVC 3 Web应用程序中使用Simple Injector作为IOC。我正在使用RavenDB进行数据存储。在mvc 3应用程序中使用RavenDB有几个注意事项。我搜索了一些关于如何连接IoC以使用RavenDB,但还没有找到如何连接简单的注入器来使用RavenDB。任何人都可以解释如何连接简单的注入器以在MVC 3 Web应用程序中使用RavenDB吗?
感谢。
答案 0 :(得分:13)
根据RavenDb tutorial,您的应用程序只需要一个IDocumentStore
实例(我假设每个数据库)。 IDocumentStore
是线程安全的。它生成IDocumentSession
个实例,它们代表RavenDB中的unit of work,而不线程安全。因此,你应该不在线程之间共享会话。
如何设置容器以与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数据库隐藏在repository后面,您可以在session.SaveChanges()
方法中调用repository.Save(entity)
。
但是,我发现这种类型的工作单元对于大型应用程序来说是有问题的。那么你可以做的是将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());
请注意,您需要Simple Injector ASP.NET Integration NuGet package(或将 SimpleInjector.Integration.Web.dll 包含在您的项目中,默认下载中包含该内容)才能使用{ {1}}扩展方法。
现在的问题是,在哪里拨打RegisterPerWebRequest
?
关于为每个网络请求注册作品单元存在一个问题,该问题还解决了有关session.SaveChanges()
的问题。请仔细看看这个答案:One DbContext per web request…why?。当您将SaveChanges
替换为DbContext
和IDocumentSession
替换为DbContextFactory
时,您将能够在RavenDb的上下文中阅读它。请注意,在使用RavenDb时,商业交易或交易的概念可能并不重要,但老实说我不知道。这是你必须自己找到的东西。