在 运行 时间 asp.net 核心注入请求范围对象
Inject request scoped object at run time asp.net core
我在 ASP.NET 核心管道中有一个中间件,我在其中像这样在运行时注入一个对象
public async Task Invoke(HttpContext context)
{
_container.Inject(someObject);
await _requestDelegate(context);
}
我现在面临的问题是,对于每个请求,它都会注入一个实例,这会使我的容器膨胀。
如果我这样做 _container.GetAllInstances<SomeType>()
,我会得到 100 多个对象。有什么方法可以注入请求范围内的对象并在请求完成后处理该对象?
不清楚您要做什么。在运行时为每个请求注入对象的目的是什么?
您使用 ServicesCollection 在 ConfigureServices
方法中设置了 DI,并使用内置 AddScoped
方法注入对特定请求有效的对象。
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(typeof(someclass), someObject);
}
如果您需要在中间件中访问 someObject 的实例。只需将依赖项作为附加参数添加到 Invoke 方法
public async Task Invoke(HttpContext context, IYourDependency someObject)
{
await _requestDelegate(context);
}
希望对您有所帮助
不应在运行时为每个请求配置依赖注入,而应在整个应用程序的应用程序启动时配置。
对于每个请求实例,使用 HttpContext.Items
管理请求数据是更好的方法。它是一个键值存储,用于单个 HTTP 请求中的共享对象。
在您的中间件中,您可以将对象添加到 HttpContext.Items
集合中:
context.Items.Add("someObjectKey", someObject);
然后在控制器中(或任何有 HttpContext 的地方),你可以获得对象:
if (context.Items.TryGetValue("someObjectKey", out object objSomeObject)
&& objSomeObject is SomeObjectType someObject)) {
// Do anything with your object here
}
如果你真的想使用 DI,你可以创建一个 helper class with scoped lifetime 获取当前 HttpContext
with IHttpContextAccessor
并以类型安全的方式提供你的对象方式。
public class SomeObjectAccessor
{
private readonly IHttpContextAccessor _httpContextAccessor;
public SomeObjectAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public SomeObject Object {
get
{
if (_httpContextAccessor.HttpContext?.Items != null && _httpContextAccessor.HttpContext.Items.TryGetValue("someObjectKey", out object objSomeObject))
return objSomeObject as SomeObject;
return null;
}
}
}
或者 class 也可以充当工厂并在首次访问时基于 HttpContext 创建对象,那么您就不会使用 HttpContext.Items
。但这取决于这里的用例。
我在 ASP.NET 核心管道中有一个中间件,我在其中像这样在运行时注入一个对象
public async Task Invoke(HttpContext context)
{
_container.Inject(someObject);
await _requestDelegate(context);
}
我现在面临的问题是,对于每个请求,它都会注入一个实例,这会使我的容器膨胀。
如果我这样做 _container.GetAllInstances<SomeType>()
,我会得到 100 多个对象。有什么方法可以注入请求范围内的对象并在请求完成后处理该对象?
不清楚您要做什么。在运行时为每个请求注入对象的目的是什么?
您使用 ServicesCollection 在 ConfigureServices
方法中设置了 DI,并使用内置 AddScoped
方法注入对特定请求有效的对象。
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(typeof(someclass), someObject);
}
如果您需要在中间件中访问 someObject 的实例。只需将依赖项作为附加参数添加到 Invoke 方法
public async Task Invoke(HttpContext context, IYourDependency someObject)
{
await _requestDelegate(context);
}
希望对您有所帮助
不应在运行时为每个请求配置依赖注入,而应在整个应用程序的应用程序启动时配置。
对于每个请求实例,使用 HttpContext.Items
管理请求数据是更好的方法。它是一个键值存储,用于单个 HTTP 请求中的共享对象。
在您的中间件中,您可以将对象添加到 HttpContext.Items
集合中:
context.Items.Add("someObjectKey", someObject);
然后在控制器中(或任何有 HttpContext 的地方),你可以获得对象:
if (context.Items.TryGetValue("someObjectKey", out object objSomeObject)
&& objSomeObject is SomeObjectType someObject)) {
// Do anything with your object here
}
如果你真的想使用 DI,你可以创建一个 helper class with scoped lifetime 获取当前 HttpContext
with IHttpContextAccessor
并以类型安全的方式提供你的对象方式。
public class SomeObjectAccessor
{
private readonly IHttpContextAccessor _httpContextAccessor;
public SomeObjectAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public SomeObject Object {
get
{
if (_httpContextAccessor.HttpContext?.Items != null && _httpContextAccessor.HttpContext.Items.TryGetValue("someObjectKey", out object objSomeObject))
return objSomeObject as SomeObject;
return null;
}
}
}
或者 class 也可以充当工厂并在首次访问时基于 HttpContext 创建对象,那么您就不会使用 HttpContext.Items
。但这取决于这里的用例。