servicestack:手动调用服务时恢复管道?

t30tvxxf  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(444)

作为这个问题的后续,我想了解如何改进手动调用服务。这变得比我想要的长,但我觉得背景信息是必要的。
在执行发布/订阅(广播)时,不使用消息传递api中的正常序列和流,而是在接收到发布/订阅消息时使用iDisclient、iDissubscription获得回调:

_subscription.OnMessage = (channel, msg) =>
{
    onMessageReceived(ParseJsonMsgToPoco(msg));
};

行动 onMessageReceived 将依次调用正常的.net/c事件,如下所示:

protected override void OnMessageReceived(MyRequest request)
{
    OnMyEvent?.Invoke(this, new RequestEventArgs(request));
}

这是可行的,我得到了我的请求和所有这些,但是,我希望它被简化成另一个流,消息传递api中的流,也就是说,请求找到了它进入一个 Service 类实现,所有正常的样板文件和依赖项注入都会像使用消息传递api一样进行。
因此,在我的事件处理程序中,我手动调用服务:

private void Instance_OnMyEvent(object sender, RequestEventArgs e)
{
    using (var myRequestService = HostContext.ResolveService<MyRequestService>(new BasicRequest()))
    {
        myRequestService.Any(e.Request);
    }
}

myrequestservice确实被找到并调用了,依赖注入对服务起作用。
问题1:
方法,例如 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(在服务的子代中)类似于:

public override void OnBeforeExecute(object requestDto)
{
    base.OnBeforeExecute(requestDto);
    IRedisCache cache = TryResolve<IRedisCache>();
    cache?.SetGuid(Guid.NewGuid());
}

因此,irediscache guid每次都应该不同,但事实并非如此。不过,当我使用消息传递api“从头到尾”时,这一点很好。似乎如果我在apphostbase子代中调用tryresolve,addscoped就会被忽略,一个示例被放置在容器中,然后再也不会被删除。

8tntrjer

8tntrjer1#

管道的哪些部分丢失了?
没有执行任何请求管道:

myRequestService.Any(e.Request);

只调用 Any c#你的方法 MyRequestService 类,它不(也不能)做任何其他事情。
在服务请求期间调用其他服务的推荐方法是使用服务网关。
但是,如果要在http请求之外调用服务,可以使用rpc网关在调用完整请求管道时执行不受信任的服务&将http错误响应转换为类型化错误响应:

HostContext.AppHost.RpcGateway.ExecuteAsync()

要在服务请求之外执行内部/受信任服务,可以使用servicestack mq使用的hostcontext.apphost.executemessage,它应用消息请求/响应筛选器、服务操作筛选器和事件。
我已向container.addscoped注册
不要在http请求之外使用请求范围内的依赖项,如果依赖项是线程安全的,请使用singleton,否则将它们注册为临时依赖项。如果您需要传递每个请求存储,请传递它们 IRequest.Items .

相关问题