- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要访问请求上下文,特别是我的自定义类中的项目,我不想让它从 ServiceStack
服务继承或在我的服务中设置它。
因此,如果我有一个像下面这样的类,它的实现类 (ContextItemsGetter
) 也实现了 IRequiresRequest
,我希望 Request
属性能够被填充。
public interface IGetContextItems
{
string Get(string key);
}
public class ContextItemsGetter : IGetContextItems, IRequiresRequest
{
public string Get(string key)
{
//someway to access http context items
//im RequestContext.Instance.Items[key] e.g. Prop1 Prop2
//or Request.blah but Request is always null
}
public IRequest Request { get; set; }
}
但是,当从真正的HTTP 请求 或redis 消息请求 调用SessionIdGetter 时,请求始终为空。难道我做错了什么?目的是解耦并使用Items在http请求和redis消息请求之间传递信息。
我也尝试过使用 RequestContext.Instance.Items,它适用于 HTTP 请求,但在 redis 消息请求期间,项目不存在,我在调用 ExecuteMessage 之前填充的键不存在。
var req = new BasicRequest { Verb = HttpMethods.Get };
req.Items.Add("Prop1", m.GetBody().Prop1);
req.Items.Add("Prop2", m.GetBody().Prop2);
var result = HostContext.ServiceController.ExecuteMessage(m, req);
我使用的是 4.0.50 版。
此外,此页 Access HTTP specific features in services哪里提到
Note:
ServiceStack
's Service base class already implementsIRequiresRequestContext
which allows you to access theIRequestContext
withbase.RequestContext
and the HTTP Request and Response withbase.Request
andbase.Response
.
我相信 IRequiresRequestContext
现在称为 IRequiresRequest
,所以我认为应该更新文档。
Updated: full code to demo my original intention:
[Route("/test", Verbs = "GET")]
public class Dto : IReturnVoid
{ }
public class DtoService : Service
{
//So that IGetContextItems is taken care of by IDependencyThatUsesIGetContextItems
public IDependencyThatUsesIGetContextItems DependencyThatUsesIGetContextItems { get; set; }
public void Get(Dto req)
{
DependencyThatUsesIGetContextItems.SomeMethod();
}
}
public interface IGetContextItems
{
string Get(string key);
}
//since ContextItemsGetter implmeents IRequiresRequest
//I can still easily test any service that uses IGetContextItems by mocking IGetContextItems
public class ContextItemsGetter : IGetContextItems, IRequiresRequest
{
public IRequest Request { get; set; }
public string Get(string key)
{
//either through injection
//return Request.Items[key].ToString();
//or some static class
//return RequestContext.RequestItems.Items[key].ToString();
return RequestContext.Instance.Items[key].ToString();
}
}
public interface IDependencyThatUsesIGetContextItems
{
string SomeMethod();
}
public class DependencyThatUsesIGetContextItems : IDependencyThatUsesIGetContextItems
{
//this will be inejcted
public IGetContextItems ContextItemsGetter { get; set; }
public string SomeMethod()
{
var a = ContextItemsGetter.Get("SomeKey");
return "blah";
}
}
最佳答案
IRequiresRequest
只注入(inject)当前的 IRequest
到您的Service 类和Validation Filters,它不会将 IRequest 注入(inject)到您的依赖项中,这些依赖项直接从 IOC 解析并且无法访问当前 IRequest能够注入(inject)。
还有ServiceStack的方便Service
和 AbstractValidator<T>
基类已经实现 IRequiresRequest
所以在大多数情况下,IRequiresRequest
所在的地方applys 已经实现,所以你不需要自己实现它。
传递 IRequest
的推荐方法进入您的依赖项是将它们作为参数从您的服务传递,例如:
public class MyServices : Service
{
public IGetContextItems ContextItems { get; set; }
public object Get(Request request)
{
return ContextItems.Get(base.Request, request.Id);
}
}
您确实有机会通过覆盖 OnPreExecuteServiceFilter()
来检查和修改您的服务实例,然后再执行您的服务。在你的 AppHost 中通过并注入(inject) IRequest
在实现 IRequiresRequest
的每个服务依赖项中与:
public override object OnPreExecuteServiceFilter(IService service,
object request, IRequest req, IResponse res)
{
service.InjectRequestIntoDependencies(req);
return request;
}
只要每个父级实现 IRequiresRequest
,调用下面的扩展方法就会递归地填充您的服务依赖关系图。 :
public static class ServiceExtensions
{
public static void InjectRequestIntoDependencies(this object instance, IRequest req)
{
foreach (var pi in instance.GetType().GetPublicProperties())
{
var mi = pi.GetGetMethod();
if (mi == null)
continue;
var dep = mi.Invoke(instance, new object[0]);
var requiresRequest = dep as IRequiresRequest;
if (requiresRequest != null)
{
requiresRequest.Request = req;
requiresRequest.InjectRequestIntoDependencies(req);
}
}
}
}
但是你需要注意不要执行IRequiresRequest
在您的任何 Singleton 依赖项(默认范围)上,因为它不是 ThreadSafe,而将 IRequest 作为参数传递。
另外,为了避免将您的逻辑类耦合到 ServiceStack,我会考虑仅从 IRequest
传递您的依赖项所需的内容。而不是 IRequest
实例本身,这也将使它更容易测试。
关于c# - ServiceStack中如何使用IRequiresRequest注入(inject)IRequest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37472059/
我需要访问请求上下文,特别是我的自定义类中的项目,我不想让它从 ServiceStack 服务继承或在我的服务中设置它。 因此,如果我有一个像下面这样的类,它的实现类 (ContextItemsGet
可能是一个简单的问题,但我没有在文档或 SO 上找到任何可以直接回答它的内容。 我必须使用 Ninject When(Func condition)第一次扩展方法,并因空对象异常而挂断了一点。我发现
我们正在为我们的 Web 应用程序使用 Service Stack Web API。在生产服务器上,所有功能都可以使用,但是对于每个请求,当我们向服务器发出请求时,都会生成如下错误。 "System.
我是一名优秀的程序员,十分优秀!