在运行时将请求范围内的对象注入asp.net核心

时间:2019-04-23 08:32:01

标签: asp.net-core dependency-injection .net-core structuremap

我在ASP.NET Core管道中有一个中间件,可以像这样在运行时注入对象

public async Task Invoke(HttpContext context)
{
 _container.Inject(someObject);
 await _requestDelegate(context);
}

我现在面临的问题是,对于每个请求,它都会注入一个实例,并使我的容器膨胀。 如果我做_container.GetAllInstances<SomeType>(),我将获得100多个对象。有什么方法可以将作用域内的对象注入到请求中,并在请求完成后丢弃该对象?

2 个答案:

答案 0 :(得分:1)

不应在运行时为每个请求配置依赖关系注入,而应在整个应用程序的应用程序启动时对其进行配置。

对于每个请求实例,使用HttpContext.Items管理请求数据是一种更好的方法。这是一个键值存储,用于在单个HTTP请求中共享对象。

在中间件中,您可以将对象添加到HttpContext.Items集合中: context.Items.Add("someObjectKey", someObject);

然后在Controller(或任何具有HttpContext的地方)中,可以获取对象:

if (context.Items.TryGetValue("someObjectKey", out object objSomeObject) 
    && objSomeObject is SomeObjectType someObject)) {
    // Do anything with your object here
}

如果您真的想使用DI,则可以创建一个具有作用域生存期的帮助器类,该类可以使用HttpContext获取当前的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;
        }
    }
}

或者,该类也可以充当工厂,并在首次访问时基于HttpContext创建对象,然后您就不会使用HttpContext.Items。但这取决于这里的用例。

答案 1 :(得分:0)

不清楚您要做什么。在运行时为每个请求注入对象的目​​的是什么?

您可以使用ServicesCollection以var FID = Request.Form["FID"].Split(','); var FQTY = Request.Form["FQty"].Split(','); for(int i = 0; i < FID.Length; ++i) { String query = "INSERT INTO gah.orders VALUES ('" + m_OrderID + "','" + FID[i] + "', '" + FQTY[i] + "')"; insD(db, query); } 方法设置DI,并使用内置的ConfigureServices方法注入将对特定请求有效的对象。

AddScoped

如果您需要访问中间件中someObject的实例。只需将依赖项作为附加参数添加到Invoke方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped(typeof(someclass), someObject);
}

我希望这对您有帮助