作者:对不起太依赖你 | 来源:互联网 | 2023-05-26 18:43
我正在用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场景.
1> Steven..:
每个定时器脉冲都可以被认为是新的请求.或者,如果您在一个脉冲中处理多个命令,则可以将每个命令视为新请求.
一些框架(如ASP.NET和WCF)具有请求(Web请求,WCF操作等)的概念,这允许Simple Injector插入框架的请求模型.因此,Simple Injector包含MVC,Web API和WCF的集成包.这些集成包挂钩到框架的请求模型中,这允许您注册每个请求实例而无需执行任何特殊操作.
但是,Windows服务不向我们提供此类基于请求的模型.这意味着您必须手动定义请求边界.这适用于所有DI容器; 不仅是简单的注射器.
Simple Injector包含两种不同的Lifestyles,允许您创建显式范围.这些是ThreadScopedLifestyle和AsyncScopedLifestyle.它ThreadScopedLifestyle
是特定于线程的,而AsyncScopedLifestyle
在处理异步操作时可以使用; 它允许范围流过异步方法调用.
提示:更喜欢使用AsyncScopedLifestyle
over 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);
}
}
通过将操作包装在生命周期范围内,我们允许重用服务.我们可以通过以下方式注册它们来实现AsyncScopedLifestyle
:
var cOntainer= new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Register(Lifestyle.Scoped);
使用生命周期范围注册的服务将在该范围的持续时间内生效,并且在范围被处置时将被处置(在ProcessCommand
方法结束时的示例中).