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);
}