我有一个服务面料ASP.NET核心无状态服务,可实现自定义中间件。在那个中间件中,我需要访问我的服务实例。我将如何使用ASP.NET Core的内置DI/IOC系统注入此信息?
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
// ** need access to service instance here **
return _next(httpContext);
}
}
有人提到在2017年4月20日的Web API 2中使用Tinyioc在2017年4月20日的Q& A#11 [45:30]与服务面料团队一起完成此操作。同样,当前推荐的方法是使用ASP.NET核心。
任何帮助或示例都将不胜感激!
在创建ServiceInstanceListener
的ASP.NET Core无状态服务中您可以注入这样的上下文:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(serviceContext =>
new WebListenerCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
logger.LogStatelessServiceStartedListening<WebApi>(url);
return new WebHostBuilder().UseWebListener()
.ConfigureServices(
services => services
.AddSingleton(serviceContext) // HERE IT GOES!
.AddSingleton(logger)
.AddTransient<IServiceRemoting, ServiceRemoting>())
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls(url)
.Build();
}))
};
}
您的中间件比这样使用:
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext, StatelessServiceContext serviceContext)
{
// ** need access to service instance here **
return _next(httpContext);
}
}
有关一个完整的示例,请查看此存储库:https://github.com/deheersoftware/azure-service-fabric-logging-and-monitoring
您的兴趣点:
- 设置DI:https://github.com/deheersoftware/azure-service-fabric-logging-and-monitoring-and-monitoring/blob/master/src/webapi/webapi/webapi/webapi.cs
- 在中间件中使用上下文:https://github.com/deheersoftware/azure-service-fabric-logging-and-monitoring-and-monitoring/blob/master/src/servicefabric.logging/middleware/middleware/requesttrackingmiddleware.cs cs cs
通过构造函数和其他人的依赖性注入依赖项。只需将其他参数添加到中间件构造函数
public MyMiddleware(RequestDelegate next, IMyService myService)
{
_next = next;
...
}
但是您也可以将依赖关系直接添加到Invoke
方法
文档:因为中间件是在应用程序启动中构建的,而不是每次请求期间,中间件构造仪使用的中间人的寿命服务范围不是与其他依赖性注射类型的类型共享。如果您必须在中间件和其他类型之间共享范围的服务,请将这些服务添加到Invoke方法的签名中。
Invoke
方法可以接受依赖注入填充的其他参数。
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
{
svc.MyProperty = 1000;
await _next(httpContext);
}
}