Gok*_*ath 1 c# dependency-injection simple-injector asp.net-web-api owin
我目前正在使用WebApiRequestLifestyle具有默认的范围生活方式.我想在OWIN中间件和其中一个API控制器中注入一个服务,服务的范围应该仍然是WebAPI,即对于整个请求,应该只有一个服务实例.
public class TestMiddleware : OwinMiddleware
{
private readonly ITestService _testService;
public TestMiddleware(OwinMiddleware next, ITestService testService) : base(next)
{
_testService = testService;
}
public override async Task Invoke(IOwinContext context)
{
var test = _testService.DoSomething();
await Next.Invoke(context);
}
}
public class ValuesController : ApiController
{
private readonly ITestService _testService;
public ValuesController(ITestService testService)
{
_testService = testService;
}
}
Run Code Online (Sandbox Code Playgroud)
整个请求的ITestService实例应该相同.我该如何注册中间件?
这就是我现在这样做的方式:
using (container.BeginExecutionContextScope())
{
var testService = container.GetInstance<ITestService>();
app.Use<TestMiddleware>(testService);
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是 - 在注册期间为中间件创建一个ITestService实例并永久保留(如单例),并且对于每个webapi请求,都会在控制器之间创建和共享新实例(webapi范围)
请不要指出这些问题 - WebApi + Simple Injector + OWIN
无论您在容器中配置哪种类型的生命周期,OWIN的Use<T>方法都会T在OWIN管道中注册提供的单例.因此,当您在活动作用域中解析中间件时,您(隐式)告诉OWIN永远缓存此实例.
你有两个选择:
确保中间件组件可以用作单例很容易.只需在Simple Injector中将其注册为singleton,当您调用时Verify(),Simple Injector将检测此组件是否可用作单例,或者它是否具有较短生活方式的依赖项.但这确实意味着所有依赖项都应该是单例,并且在构建对象图之后,应该通过方法调用传递运行时数据(如DbContext和其他数据对象).我认为这是一个很好的做法,但这可能是你的应用程序的一个很大的变化,可能是一个很大的转变.因此,我认为这超出了这个问题的范围,所以你应该选择2.
如果您的中间件组件具有较短生活方式的依赖项,则应根据请求请求解析该中间件.这意味着你不应该使用OWIN的Use<T>(middleware)方法,因为这会使它成为单身.
这是怎么做的:
app.Use(async (context, next) =>
{
var middleware = container.GetInstance<TestMiddleware>();
await middleware.Invoke(context, next);
});
Run Code Online (Sandbox Code Playgroud)
请注意,TestMiddleware每个请求都会解析.这使Simple Injector可以完全控制构建的对象图.但这意味着您需要对您的TestMiddleware班级进行一些小调整.它应该是这样的:
public sealed class TestMiddleware
{
private readonly ITestService _testService;
public TestMiddleware(ITestService testService)
{
_testService = testService;
}
public async Task Invoke(IOwinContext context, Func<Task> next)
{
var test = _testService.DoSomething();
await next();
}
}
Run Code Online (Sandbox Code Playgroud)
注意,OwinMiddleware参数从构造函数中删除,并由方法中的Func<Task>参数替换Invoke.这允许Simple Injector构造类型,因为它的构造函数将不再包含任何运行时参数.记住:通过构造函数编译时间依赖性,通过方法调用编译运行时数据.
另请注意,中间件不再继承OwinMiddleware.由于中间件没有注入包装的中间件,因此继承它变得毫无用处.
| 归档时间: |
|
| 查看次数: |
1802 次 |
| 最近记录: |