我在 MVC 4 项目中使用 NServiceBus (3.2.2)、RavenDB (1.2.2017-Unstable) 和 Windsor (3.0.0.4001)。
我有一个处理 3 个不同消息的 IHandleMessages 类,它需要一个 IDocumentSession,因此定义了一个属性,例如:
public IDocumentSession DocumentSession { get; set; }
我已经从 NServiceBus 的网站复制了 RavenDbUnitOfWork 实现
我在 Windsor 容器中注册了 IDocumentStore、IDocumentSession 和 IManageUnitsOfWork,如下所示:
container.Register(
Component
.For<IManageUnitsOfWork>()
.ImplementedBy<RavenUnitOfWork>()
.LifestyleTransient()
);
container.Register(
Component
.For<IDocumentStore>()
.UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
.LifestyleSingleton(),
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleTransient()
);
NServiceBus 配置为使用我的容器:
Configure.With()
.CastleWindsorBuilder(container);
我遇到了 UnitOfWork 和消息处理程序接收 DocumentSession 的不同实例的问题。这意味着存储在消息处理程序中的会话中的对象不会被保存,因为 SaveChanges() 是在不同的 DocumentSession 上调用的。
删除 Transient 生活方式会导致不同类型的问题,这会导致在从 RavenDb 更新对象时出现并发/冲突,因为(可能)消息处理程序不断获取 DocumentSession 的相同实例,该实例包含更新对象的缓存版本。
更新:
正如建议的那样,我尝试将 Windsor 中 IDocumentSession 的注册更改为 Scope 生活方式,如下所示:
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleScope()
当容器尝试解析 MVC 控制器时,这会导致异常,说找不到范围,并询问我是否忘记调用 BeginScope()。