【发布时间】:2020-10-27 20:53:58
【问题描述】:
作为this question 的后续行动,我想了解如何改进手动调用服务。这比我想要的要长,但我觉得需要背景信息。
在进行 pub/sub(广播)时,不使用 Messaging API 中的正常顺序和流程,而是在收到 pub/sub 消息时使用 IRedisClient、IRedisSubscription 获得回调:
_subscription.OnMessage = (channel, msg) =>
{
onMessageReceived(ParseJsonMsgToPoco(msg));
};
然后,Action onMessageReceived 将依次调用正常的 .NET/C# 事件,如下所示:
protected override void OnMessageReceived(MyRequest request)
{
OnMyEvent?.Invoke(this, new RequestEventArgs(request));
}
这行得通,我收到了我的请求和所有这些,但是,我希望将它简化到另一个流程中,即消息 API 中的流程,这意味着,请求找到了进入 Service 类实现的方式,并且所有正常的样板和依赖注入都会像使用 Messaging API 一样发生。
因此,在我的事件处理程序中,我手动调用服务:
private void Instance_OnMyEvent(object sender, RequestEventArgs e)
{
using (var myRequestService = HostContext.ResolveService<MyRequestService>(new BasicRequest()))
{
myRequestService.Any(e.Request);
}
}
确实找到了 MyRequestService 并调用了 Any ,并且依赖注入适用于服务。
问题一:
-
OnBeforeExecute、OnAfterExecute等方法不会被调用,除非我手动调用它们,比如:myRequestService.OnBeforeExecute(e)等。管道的哪些部分丢失了?能否以某种简单的方式恢复它,这样我就不必按顺序手动调用它们?
问题 2:
我认为我这样做是在搞砸 DI 系统:
using (var myRequestService = HostContext.ResolveService<MyRequestService>(new BasicRequest()))
{
myRequestService.OnBeforeExecute(e.Request);
myRequestService.Any(e.Request);
myRequestService.OnAfterExecute(e.Request);
}
我看到的效果是,我使用container.AddScoped 注册的注入依赖项没有作用域,但似乎是静态的。我看到这一点是因为我在注入的类中有一个 Guid,在这种情况下 Guid 总是相同的,而每个请求的 Guid 应该不同。
container.AddScoped<IRedisCache, RedisCache>();
OnBeforeExecute(Service 的后代)就像:
public override void OnBeforeExecute(object requestDto)
{
base.OnBeforeExecute(requestDto);
IRedisCache cache = TryResolve<IRedisCache>();
cache?.SetGuid(Guid.NewGuid());
}
因此,IRedisCache Guid 每次都应该不同,但事实并非如此。但是,当我“从头到尾”使用消息传递 API 时,这可以正常工作。看来,如果我在 AppHostBase 后代中调用 TryResolve,则会忽略 AddScoped,并将一个实例放置在容器中,然后永远不会删除。
【问题讨论】:
标签: redis servicestack publish-subscribe