ServiceStack MQ: как заполнить данные в RequestContext

Я разрабатываю основанную на JWT мультитенантную систему с использованием ServiceStack. Токен JWT содержит информацию о шарде, и я использую JwtAuthProvider преобразовать токен JWT в объект сеанса, следуя инструкциям по адресу http://docs.servicestack.net/jwt-authprovider.

Теперь я хочу использовать ServiceStack MQ для асинхронной обработки. Запрос MQ должен знать об информации сегмента, поэтому я заполняю контекст запроса перед его выполнением следующим образом

mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
            {
                var req = new BasicRequest { Verb = HttpMethods.Post };
                var sessionKey = SessionFeature.GetSessionKey(m.GetBody().SessionId);
                var session = HostContext.TryResolve<ICacheClient>().Get<Context>(sessionKey);
                req.Items[Keywords.Session] = session;
                var response = ExecuteMessage(m, req);
                return response;
            });

Вот, Context мой пользовательский класс сессии Этот метод основан на инструкции по адресу http://docs.servicestack.net/messaging. Поскольку я выполняю сообщение в контексте reqЯ считаю, что я должен быть в состоянии решить Context следующим образом

container.AddScoped<Context>(c =>
        {
            var webRequest = HostContext.TryGetCurrentRequest();
            if (webRequest != null)
            {
                return webRequest.SessionAs<Context>();
            } else
            {
                return HostContext.RequestContext.Items[Keywords.Session] as Context;                    
            }
        });

Тем не мение, HostContext.RequestContext.Items всегда пусто Так что вопрос в том, как заселить HostContext.RequestContext.Items из кода регистрации обработчика сообщений?

Я попытался немного покопаться в коде ServiceStack и обнаружил, что ExecuteMessage(IMessage dto, IRequest req) в ServiceController не заполняет данные в RequestContext, В моем случае уже слишком поздно получать сеанс внутри экземпляра службы, так как экземпляр службы зависит от некоторых соединений с БД, чьи данные об этом хранятся в сеансе.

1 ответ

Решение

Тот же экземпляр контекста запроса не может быть разрешен из IOC. Экземпляр контекста запроса создается в MQ RegisterHandler<T>() где вы можете добавить пользовательские данные в IRequest.Items свойство, например:

mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
{
    var req = new BasicRequest { Verb = HttpMethods.Post };
    req.Items[MyKey] = MyValue; //Inject custom per-request data
    //...
    var response = ExecuteMessage(m, req);
    return response;
});

это IRequest экземпляр доступен по всему конвейеру запросов и от base.Request в ваших услугах. Он недоступен из ваших регистраций IOC, поэтому вам нужно будет передать его в качестве аргумента при вызове вашей зависимости, например:

public class MyServices : Service
{
    public IDependency MyDep { get; set; }

    public object Any(MyRequest request) => MyDep.Method(base.Request, request.Id);
}
Другие вопросы по тегам