【发布时间】:2017-06-08 04:51:34
【问题描述】:
在我的 Web API 项目中,我有一个需要当前请求的依赖项。
代码如下:
public interface IResourceLinker {
Uri Link(string routeName, object routeValues);
}
public class ResourceLinker : IResourceLinker {
private readonly HttpRequestMessage _request;
public ResourceLinker(HttpRequestMessage request) {
_request = request;
}
public Uri Link(string routeName, object routeValues) {
return new Uri(_request.GetUrlHelper()
.Link(routeName, routeValues));
}
}
public class TestController : ApiController {
private IResourceLinker _resourceLinker;
public TestController(IResourceLinker resourceLinker) {
_resourceLinker = resourceLinker
}
public Test Get() {
var url = _resourceLinker.Link("routeName", routeValues);
// etc.
}
}
使用Simple Injector,是否可以在运行时将当前请求注入到容器中?
我尝试了以下方法:
public class InjectRequestHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
InjectRequest(request);
return base.SendAsync(request, cancellationToken);
}
public static void InjectCurrentRequestIntoContainer(
HttpRequestMessage request)
{
var resolver = (SimpleInjectorDependencyResolver)
request.GetDependencyScope();
resolver.Container.Register(() => request);
}
}
但收到以下错误
第一次调用 GetInstance、GetAllInstances 和 Verify 后,容器无法更改。
有没有办法在运行时将当前请求注入到容器中?
【问题讨论】:
-
为什么不在 HttpRequestMessage 上将链接方法定义为扩展方法并在
TestController中调用this.Request.Link (...)?否则,由于HttpRequestMessage是运行时值,请将其作为方法参数传递给您的Link方法,而不是使用构造函数注入。 -
史蒂文,感谢您的意见。作为simpleinjector的创造者,是否可以运行时注册?
-
从容器中解析出第一个实例后,不能添加任何新的注册。但即使是这样,在容器中注册
HttpRequestMessage也会导致竞争条件,因为容器是全局的,但每个请求都需要一条消息。 -
Simple Injector 2.5 现在包含一个 Web API 集成包,它包含一个 GetCurrentHttpRequestMessage() 扩展方法,允许您从容器中检索当前消息。
标签: c# .net dependency-injection simple-injector