是否有可靠的方法将Ninject绑定的服务范围限定到NServicebus消息处理程序?

是否有可靠的方法将Ninject绑定的服务范围限定到NServicebus消息处理程序?,ninject,nservicebus,Ninject,Nservicebus,我想将实体框架上下文绑定到每个NServicebus消息的作用域。下面的代码能否成功地做到这一点 Bind().To()) .InScope(x=>x.Kernel.Get().CurrentMessageContext.Id); 背景 我有一个NServicebus服务,它有几个IMessageHandler,可以从MSMQ队列中读取事件 每个处理程序通过位于实体框架上下文上的特定IRepository转换消息并将其保存到MS SQL数据库 每个处理程序所需的存储库都是使用NServiceb

我想将实体框架上下文绑定到每个NServicebus消息的作用域。下面的代码能否成功地做到这一点

Bind().To())
.InScope(x=>x.Kernel.Get().CurrentMessageContext.Id);
背景

我有一个NServicebus服务,它有几个IMessageHandler,可以从MSMQ队列中读取事件

每个处理程序通过位于实体框架上下文上的特定IRepository转换消息并将其保存到MS SQL数据库

每个处理程序所需的存储库都是使用NServicebus.ObjectBuilder.ninject通过ninject注入的

公共类产品
{
公共字符串代码{get;set;}
公共类别{get;set;}
}
公共类类别
{
公共字符串代码{get;set;}
}
公共类SampleContext:IDbContext
{
IDbSet产品{get;}
IDbSet类别{get;}
}
公共类ProductRepository:IPProductRepository
{
私有上下文_上下文;
公共产品存储库(IDbContext ctx){{u context=ctx;}
公共无效添加(产品p)
{
_上下文。产品。添加(p);
_SaveChanges();
}
}
公共类CategoryRepository:ICategoryRepository
{
私有上下文_上下文;
公共类别存储(IDbContext ctx){{u context=ctx;}
公共类别GetByCode(字符串代码)
{
返回_context.Categories.FirstOrDefault(x=>x.Code==Code);
}
}
公共类AddProductMessageHandler:IMessageHandler
{
私有IPProductRepository\u产品;
私有ICategoryRepository_类别;
public AddProductMessageHandler(IPProductRepository p、ICategoryRepository c)
{
_产品=p;
_类别=c;
}
公共无效句柄(IADDPRODUCT事件e)
{
var p=新产品();
p、 代码=e.ProductCode;
p、 Category=\u categories.GetByCode(例如CategoryCode);
_产品.加入(p);;
}
}
问题

如果EF上下文绑定在临时范围内(默认),那么处理程序中的每个绑定存储库都有自己的上下文实例

Bind().To();
如果我从一个存储库加载一个对象,然后通过另一个存储库保存它,则会出现问题

同样,如果它绑定在单例范围内,那么所有存储库都会使用相同的上下文,但随后它会慢慢地被跟踪的更改填满,并在我的所有ram中使用Google(启动速度越来越慢)

Bind().To().InSingletonScope();
问题

理想情况下,我希望每个消息处理程序都有一个EF上下文,所有必需的存储库(该处理程序的)都使用它来加载和保存实体

将上下文范围限定到当前消息Id属性是否是一种安全/可靠/良好的方法

Bind().To())
.InScope(x=>x.Kernel.Get().CurrentMessageContext.Id);

我不熟悉EF上下文,因此如果下面的答案没有任何意义,请忽略

如果EF上下文类似于NH会话,那么我认为更好的选择是使用与相同的UoW。

您可以阅读更多关于UoW的信息。

请参阅我的博客文章,其中介绍了NSB 4.0之外的范围


如果您有3.0,您可以查看当前的开发分支,并将扩展方法移植到代码中。您只需更改作用域名称。

我看过您的帖子,但由于我们使用的是Ninject 3.0.1.10,因此我无法访问所需的方法之一:
IBindingInNamedWithOrOnSyntax WhenNoAncestorNamed(字符串名称)确定。这个方法很容易编程。在升级之前,您可以使用apache2许可证标题将其从GH repo复制粘贴到您的项目中。实体框架上下文本质上是一个工作单元。我没有深入研究它们,因为我真的不想在我的数据存储项目中引用NServicebus(使IManageUnitsOfWork)。