我有一个工作正常的RabbitMQ Singleton,但是当消息到达时它依赖于作用域服务:
consumer.Received += _resourcesHandler.ProcessResourceObject; //Scoped Service
Run Code Online (Sandbox Code Playgroud)
我的服务注册如下:
services.AddScoped<IHandler, Handler>();
services.AddSingleton<RabbitMqListener>();
Run Code Online (Sandbox Code Playgroud)
作用域服务构造函数使用DI作为Db上下文:
private readonly ApplicationDbContext _appDbContext;
public ResourcesHandler(ApplicationDbContext appDbContext)
{
_appDbContext = appDbContext;
}
Run Code Online (Sandbox Code Playgroud)
此作用域服务调用Db上下文,以便在收到消息时将属性插入数据库.
但是,由于作用域服务具有不同的生命周期,因此启动失败.
有一个更好的方法吗?我可以使作用域服务成为单例,但后来我遇到了使用DbContext作为依赖的问题.
DI中用于在单例服务中调用dbContext的"协议"是什么?
我可以使用一个using语句来确保它被丢弃,但是我必须使用DI来传递DbContextOptions.这是实现这一目标的唯一途径吗?
我在我们的解决方案中使用NServiceBus v4.3,MVC4,RavenDB 2.5和StructureMap 2.6.4.
我在StructureMap下遇到类似问题的问题,在这个问题的回答中我要求MVC控制器使用不同的生命周期,NServiceBus Handler在我的Web项目中使用RavenDB的IDocumentSession.
特别是在我的情况下,如果我使用HybridHttpOrThreadLocalScoped(如上面的答案建议Windsor)生命周期,会话没有被妥善处理,我很快就达到了30个事务限制错误.如果我使用HttpContext生命周期,则不会调用Web项目中的NSB事件处理程序.
在我的控制器中,会话被包含在通过MVC ActionFilter应用的工作单元中.我也使用处理程序中的UoW,因为我的注册表已连线以从UoW检索会话.代码是这样的:
RavenDbWebRegistry.cs
public sealed class RavenDbWebRegistry : Registry
{
public RavenDbWebRegistry()
{
// register RavenDB document store
ForSingletonOf<IDocumentStore>().Use(() =>
{
var documentStore = new DocumentStore
{
ConnectionStringName = "RavenDB",
Conventions =
{
IdentityPartsSeparator = "-",
JsonContractResolver = new PrivatePropertySetterResolver(),
},
};
documentStore.Initialize();
return documentStore;
});
For<IDocumentSession>().HybridHttpOrThreadLocalScoped().Add(ctx =>
{
var uow = (IRavenDbUnitOfWork)ctx.GetInstance<IUnitOfWork>();
return uow.DocumentSession;
});
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<WebRavenDbUnitOfWork>();
}
}
Run Code Online (Sandbox Code Playgroud)
Web项目处理程序示例:
public class SiteCreatedEventHandler : IHandleMessages<ISiteCreatedEvent>
{
public IBus Bus …Run Code Online (Sandbox Code Playgroud)