简单的注入器/ IoC - 队列处理器的Windows服务和请求周期

Bud*_*Joe 6 c# entity-framework ioc-container inversion-of-control simple-injector

我正在用C#编写一个队列处理器作为Windows服务.后端队列机制是MongoDB.队列的目的是运行源自我们主网站(Angular w Web API)的带外请求.对于每个排队的项目,我想要一个序列化的Command实例+序列化的上下文信息

foreach请求周期:
1)如果当前命令处理程序需要它,则新建DbContext(EF)
2)反序列化AppContext并将该信息注入当前的命令处理程序

不知道如何在Simple Injector中处理这些模式.特别是因为这是Timer的循环,而不是已经为其编写过helper/classes的Web Request.思考?我见过其他IoC容器过去使用lambda表达式来处理这类东西.只是不确定如何处理我的#1和#2场景.

Ste*_*ven 7

每个定时器脉冲都可以被认为是新的请求.或者,如果您在一个脉冲中处理多个命令,则可以将每个命令视为新请求.

一些框架(如ASP.NET和WCF)具有请求(Web请求,WCF操作等)的概念,这允许Simple Injector插入框架的请求模型.因此,Simple Injector包含MVC,Web API和WCF的集成包.这些集成包挂钩到框架的请求模型中,这允许您注册每个请求实例而无需执行任何特殊操作.

但是,Windows服务不向我们提供此类基于请求的模型.这意味着您必须手动定义请求边界.这适用于所有DI容器; 不仅是简单的注射器.

Simple Injector包含两种不同的Lifestyles,允许您创建显式范围.这些是ThreadScopedLifestyleAsyncScopedLifestyle.它ThreadScopedLifestyle是特定于线程的,而AsyncScopedLifestyle在处理异步操作时可以使用; 它允许范围流过异步方法调用.

提示:更喜欢使用AsyncScopedLifestyleover ThreadScopedLifestyle,因为它可以作为单线程操作进行异步操作.ThreadScopedLifestyle通常只应在运行.NET 4.0应用程序时使用,因为AsyncScopedLifestyle它仅适用于.NET 4.5,.NET Core和.NET Standard 1.3.

这意味着在从用于处理该命令的容器中解析新服务之前,必须在容器中启动新的"范围".例如:

public void ProcessCommand(object command) {
    using (AsyncScopedLifestyle.BeginScope(this.container)) {
        Type handlerType = 
            typeof(ICommandHandler<>).MakeGenericType(command.GetType());

        dynamic handler = container.GetInstance(handlerType);

        handler.Handle((dynamic)command);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将操作包装在生命周期范围内,我们允许重用服务.我们可以通过以下方式注册它们来实现AsyncScopedLifestyle:

var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

container.Register<IUnitOfWork, DbContextUnitOfWork>(Lifestyle.Scoped);
Run Code Online (Sandbox Code Playgroud)

使用生命周期范围注册的服务将在该范围的持续时间内生效,并且在范围被处置时将被处置(在ProcessCommand方法结束时的示例中).