具有EasynetQ消息生命周期的简单注入器Ioc DBContext

时间:2015-07-09 10:55:16

标签: c# entity-framework inversion-of-control simple-injector easynetq

我使用Simple Injector解决了EF的DBContext生命周期问题,我有一个连续运行的工作服务,但我希望在消息的生命周期内初始化DBContext不是工作服务申请的生命周期。

有关如何使用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);  

在工人模块中我们有:

container.RegisterModuleScoped(new CodeModule(), Lifestyle.Transient);

但是我们不想在我们的DBContext中使用Lifestyle Transient,我们希望在消息处理程序中使用它。

更新

史蒂文,这听起来像是一个很好的解决方案,只是在注册IMessageHandler<T>时遇到了一些问题。

LifetimeScopeMessageHandlerDecorator类型的构造函数包含类型为Func<NoticeMessageHandler>的参数,其名称为'decorateeFactory',未注册。

我之前尝试过注册,并试图将其删除,但有很多变化,但没有运气。这是我注册装饰的方式:

container.RegisterSingleDecorator(
    typeof(NoticeMessageHandler),
    typeof(LifetimeScopeMessageHandlerDecorator));

错误:

  

LifetimeScopeMessageHandlerDecorator类型的构造函数包含类型为Func<NoticeMessageHandler>的参数,其名称为'decorateeFactory',未注册。

1 个答案:

答案 0 :(得分:2)

您应该做的是用范围包装消息的执行。例如,您可以使用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并注册您的装饰器。也许你的架构看起来不一样,但这个想法总是一样的:围绕消息处理程序的解析和执行包装生命周期范围。