Объект области видимости запроса Inject во время выполнения ядра asp.net - PullRequest
1 голос
/ 23 апреля 2019

У меня есть промежуточное ПО в конвейере ASP.NET Core, где я внедряю объект во время выполнения, как это

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

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что для каждого запроса он внедряет экземпляр этого и раздувает мой контейнер. Если я сделаю _container.GetAllInstances<SomeType>(), я получу 100+ объектов. Есть ли способ, которым мы можем внедрить объект, ограниченный областью запроса, и избавиться от объекта, когда запрос завершится?

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Внедрение зависимостей следует настраивать не во время выполнения для каждого запроса, а при запуске приложения для всего приложения.

Для экземпляров по запросу лучше использовать данные запроса с использованием HttpContext.Items. Это хранилище Key-Value, предназначенное для общих объектов в рамках одного 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, вы можете создать вспомогательный класс с ограниченным временем жизни, который получает текущий 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. Но это зависит от варианта использования здесь.

0 голосов
/ 23 апреля 2019

Непонятно, что вы пытаетесь сделать. Какова цель внедрения объекта во время выполнения для каждого запроса?

Вы устанавливаете свой DI в методе ConfigureServices с использованием ServicesCollection и используете встроенный метод AddScoped для внедрения объекта, который будет действителен для конкретного запроса.

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

если вам нужен доступ к экземпляру someObject в вашем промежуточном программном обеспечении. Просто добавьте зависимость в качестве дополнительного параметра в метод Invoke

public async Task Invoke(HttpContext context, IYourDependency someObject)
{
    await _requestDelegate(context);
}

Надеюсь, это поможет

...