具有 EasynetQ 消息生命周期的简单注入器 Ioc DBContext
Simple Injector Ioc DBContext with EasynetQ message life cycle
我对 EF 的 DBContext
's life cycle using Simple Injector , I have a worker service that is running continuously but I want the DBContext
to be initialized during the messages' 生命周期有疑问,而不是工作人员服务应用程序的生命周期。
有一些关于如何使用 Autofac 执行此操作的示例,但我无法使用 Simple Injector 想出一些东西。以前有人这样做过吗?
参见:http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/
我们注册的当前实现是:
var registration = applicationLifestyle.CreateRegistration<ProjectContext>(container);
container.AddRegistration(typeof(IProjectContext), registration);
container.AddRegistration(typeof(ProjectContext), registration);
在 worker 模块中我们有:
container.RegisterModuleScoped(new CodeModule(), Lifestyle.Transient);
然而,我们不想为我们的 DBContext
使用 Lifestyle Transient,我们希望它在消息处理程序期间处于活动状态。
更新:
Steven,这听起来是个不错的解决方案,只是在注册 IMessageHandler<T>
时遇到了一些问题,例如
类型 LifetimeScopeMessageHandlerDecorator
的构造函数包含名称为 'decorateeFactory' 的类型 Func<NoticeMessageHandler>
的参数未注册。
我之前尝试过注册这个,并试图将其排除在外,并且有很多变化,但没有成功。这是我注册装饰器的方式:
container.RegisterSingleDecorator(
typeof(NoticeMessageHandler),
typeof(LifetimeScopeMessageHandlerDecorator));
错误:
The constructor of type LifetimeScopeMessageHandlerDecorator contains the parameter of type Func<NoticeMessageHandler>
with name 'decorateeFactory' that is not registered.
您应该做的是用范围包装消息的执行。例如,您可以使用 LifetimeScopeLifestyle
。在哪里包装当然完全取决于您的体系结构,但我想您有一个消息处理程序,在这种情况下您可以为此定义一个装饰器:
public class LifetimeScopeMessageHandlerDecorator<T>
: IMessageHandler<T>
{
private readonly Func<IMessageHandler<T>> decorateeFactory;
public LifetimeScopeMessageHandlerDecorator(Container container,
Func<IMessageHandler<T>> decorateeFactory) {
this.decorateeFactory = decorateeFactory;
}
public void Handle(T message) {
using (this.container.BeginLifetimeScope()) {
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(message);
}
}
}
这意味着您必须使用 LifetimeScopeLifestyle
注册您的 DbContext 并注册您的装饰器。也许您的体系结构看起来不同,但想法始终是相同的:将生命周期范围包裹在消息处理程序的解析和执行中。
我对 EF 的 DBContext
's life cycle using Simple Injector , I have a worker service that is running continuously but I want the DBContext
to be initialized during the messages' 生命周期有疑问,而不是工作人员服务应用程序的生命周期。
有一些关于如何使用 Autofac 执行此操作的示例,但我无法使用 Simple Injector 想出一些东西。以前有人这样做过吗?
参见:http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/
我们注册的当前实现是:
var registration = applicationLifestyle.CreateRegistration<ProjectContext>(container);
container.AddRegistration(typeof(IProjectContext), registration);
container.AddRegistration(typeof(ProjectContext), registration);
在 worker 模块中我们有:
container.RegisterModuleScoped(new CodeModule(), Lifestyle.Transient);
然而,我们不想为我们的 DBContext
使用 Lifestyle Transient,我们希望它在消息处理程序期间处于活动状态。
更新:
Steven,这听起来是个不错的解决方案,只是在注册 IMessageHandler<T>
时遇到了一些问题,例如
类型 LifetimeScopeMessageHandlerDecorator
的构造函数包含名称为 'decorateeFactory' 的类型 Func<NoticeMessageHandler>
的参数未注册。
我之前尝试过注册这个,并试图将其排除在外,并且有很多变化,但没有成功。这是我注册装饰器的方式:
container.RegisterSingleDecorator(
typeof(NoticeMessageHandler),
typeof(LifetimeScopeMessageHandlerDecorator));
错误:
The constructor of type LifetimeScopeMessageHandlerDecorator contains the parameter of type
Func<NoticeMessageHandler>
with name 'decorateeFactory' that is not registered.
您应该做的是用范围包装消息的执行。例如,您可以使用 LifetimeScopeLifestyle
。在哪里包装当然完全取决于您的体系结构,但我想您有一个消息处理程序,在这种情况下您可以为此定义一个装饰器:
public class LifetimeScopeMessageHandlerDecorator<T>
: IMessageHandler<T>
{
private readonly Func<IMessageHandler<T>> decorateeFactory;
public LifetimeScopeMessageHandlerDecorator(Container container,
Func<IMessageHandler<T>> decorateeFactory) {
this.decorateeFactory = decorateeFactory;
}
public void Handle(T message) {
using (this.container.BeginLifetimeScope()) {
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(message);
}
}
}
这意味着您必须使用 LifetimeScopeLifestyle
注册您的 DbContext 并注册您的装饰器。也许您的体系结构看起来不同,但想法始终是相同的:将生命周期范围包裹在消息处理程序的解析和执行中。