【问题标题】:Simple Injector Ioc DBContext with EasynetQ message life cycle具有 EasynetQ 消息生命周期的简单注入器 Ioc DBContext
【发布时间】:2015-07-09 10:55:15
【问题描述】:

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

有一些关于如何使用 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,我们希望它在消息处理程序期间处于活动状态。

更新:

Steven,这听起来不错的解决方案,只是在注册 IMessageHandler&lt;T&gt; 时遇到了一些问题,例如

LifetimeScopeMessageHandlerDecorator 类型的构造函数包含未注册的名为“decorateeFactory”的Func&lt;NoticeMessageHandler&gt; 类型参数。

我之前尝试过注册它并试图将其排除在外,并且有很多变化,但没有运气。以下是我注册装饰器的方式:

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

错误:

LifetimeScopeMessageHandlerDecorator 类型的构造函数包含未注册的名为“decorateeFactory”的Func&lt;NoticeMessageHandler&gt; 类型参数。

【问题讨论】:

  • 使用生命周期范围,参见here,并在消息生命周期开始时启动范围。
  • 同时阅读[装饰器文档](simpleinjector.readthedocs.org/en/latest/…)。您得到的异常表明该类不是装饰器。如果您仍然遇到问题,请同时发布您的装饰器的代码。

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


【解决方案1】:

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

【讨论】:

  • 好吧,这听起来像是一个很好的解决方案,只是在注册 IMessageHandler 时遇到了一些问题,例如LifetimeScopeMessageHandlerDecorator 类型的构造函数包含名称为“decorateeFactory”的 Func 类型的参数,该参数未注册。我之前曾尝试过注册,并试图将其排除在外,还有很多变化,但没有运气。这是我注册装饰器的方式: container.RegisterSingleDecorator( typeof(NoticeMessageHandler), typeof(LifetimeScopeMessageHandlerDecorator));
  • @MichaelCarr 仔细看看我回答中的装饰器:参数包含一个 T。
  • 谢谢!真的帮了我大忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2017-05-28
  • 2023-03-28
相关资源
最近更新 更多