Ресурс с ограниченной областью внедрения зависимостей, созданный несколько раз

#.net #dependency-injection

#.net #внедрение зависимостей

Вопрос:

Этот вопрос опубликован, чтобы помочь другим (ответ тоже опубликован).

У нас есть приложение Azure Functions, которое использует внедрение зависимостей (стандартное для Microsoft).

Мы видим, что класс зарегистрирован как Scoped созданный несколько раз в рамках одного запроса.

 public class MyStrategy : IMyStrategy
{
  public MyStrategy(IUnitOfWork unitOfWork, ISomeRepository someRepository) { ... }
}

public class UnitOfWork: IUnitOfWork
{
  public UnitOfWork(ApplicationDbContext dbContext) { ... }
}

public class SomeRepository: ISomeRepository
{
  public SomeRepository(ApplicationDbContext dbContext) { ... }
}
 

При IMyStrategy вводе мы видим, что DbContext в UnitOfWork не является тем же экземпляром, что и в SomeRepository — даже если все они зарегистрированы с помощью services.AddScoped .

Для нас это означает, что новые объекты, добавленные в ApplicationDbContext via SomeRepository , не сохраняются в БД при ApplicationDbContext.SaveChangesAsync вызове из нашего UnitOfWork (потому что мы добавляем к одному экземпляру и вызываем Save для другого).

Ответ №1:

Проблема возникла из-за того, что расширение Microsoft AddHttpClient<T1, T1> для IServiceCollection использовалось в функциональном приложении Azure.

Это известная проблема в .NET Core 3.1 framework. В двоичные файлы уже включено исправление, но оно скрыто за флагом функции. Чтобы устранить проблему, добавьте следующий параметр в свое приложение Azure Functions.

 "AzureWebJobsFeatureFlags": "EnableEnhancedScopes"
 

Комментарии:

1. ваше решение сработало для нас. Не могли бы вы подробнее рассказать о том, как использование AddHttpClient<T1, T1> вызывает эту проблему?

2. Я думаю, это так же просто, как это была ошибка в фреймворке, которая была исправлена MS, но активирована с помощью флага функции, потому что они не были уверены, как изменение кода повлияет на существующие приложения, и они не хотели вносить серьезные изменения в второстепенный выпуск. Я ожидаю, что поведение по умолчанию было изменено в .net 5/6.