Почему мой EF Core DbContext не связан DI?

У меня есть приложение-функция Azure с функцией, которая запускается по триггеру BLOB-объектов. Я доказал, что эта функция может запускаться через портал Azure и реагирует на этот триггер большого двоичного объекта без проблем... или, по крайней мере, так и было.

Теперь, когда я добавил функциональность, которая использует EF Core (2.2.4), он дает мне следующую ошибку, как при локальной отладке, так и при публикации в Azure:

Microsoft.Azure.WebJobs.Host: Ошибка индексации метода "ParseThings". Microsoft.Azure.WebJobs.Host: невозможно связать параметр context с типом AvastusContext. Убедитесь, что параметр Type поддерживается привязкой. Если вы используете привязки расширений (например, хранилище Azure, ServiceBus, таймеры и т. Д.), Убедитесь, что вы вызвали метод регистрации расширений в своем коде запуска (например, builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers() и т. д.).

у меня есть Startup Класс, как указано в документации Azure Function App здесь, и следуют их примеру до буквы, кроме следующей строки вместо их настроенных примеров служб:

[assembly: FunctionsStartup(typeof(AvstFunctionApp.Startup))]

namespace AvstFunctionApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddDbContext<AvastusContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("AvastusDb")));
        }
    }
}

И начало моей функции:

public static class ParseThings
{
    [FunctionName("ParseThings")]
    public static void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log, AvastusContext context)

Я могу подтвердить, что AddDbContext Линия получает удар в отладчике, так что, возможно, за кулисами происходит какая-то ошибка, или я делаю что-то невероятно глупое.

Вещи, которые я пробовал, которые не сработали, включают в себя:

  • Добавление .BuildServiceProvider(true) к AddDbContext линия
  • С помощью WebJobsStartup вместо недавно объявленной FunctionsStartup
  • Переход на.NET Core 2.2.0
  • Изменение класса Function и Run метод от статического к экземпляру
  • Исправление некорректного пространства имен введенного AvastusContext

Стоит также отметить, что в этом проекте Function App есть две другие функции, у которых, похоже, нет серьезных проблем, и я смог заставить работать инъекцию зависимостей, используя аналогичный метод с EF Core для другого (ASP.NET Core MVC) проект в этом решении.

Заранее благодарю за любую помощь, которую может оказать каждый!

PS Я нахожу невероятно странным, что в более поздних версиях.NET Core, приложений-функций Azure и EF Core более поздних версий не было ничего описывающего эту ситуацию, что наводит меня на мысль, что это может быть простой ошибкой. Надеюсь, что нет.

2 ответа

Возможно , вы можете попробовать внедрить IServiceProvider в свою функцию вместо AvastusContext, как я ввел в класс репозитория ниже:

private readonly IServiceProvider serviceProvider;

        public SomeRepository(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }
    
        using var context = this.serviceProvider.GetService<XYZDBContext>(); 

Это предоставит вам объект контекста. Кроме того, не уверен, почему вы пытаетесь получить доступ к контексту в функции напрямую, для хорошей практики определите класс контекста и поддерживайте репозиторий для выполнения любых операций CRUD в коде.

Startup.cs вы можете добавить дополнительные конфигурации, например:

builder.Services.AddDbContext<XYZDBContext>(
            options =>
            {
                options.UseSqlServer(
                    conn,
                    sqlServerOptionsAction:
                    sqlOptions =>
                    {
                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
                    });
            }, ServiceLifetime.Transient);

эта конфигурация отлично работает в моем текущем решении. Попробуйте это.

Приложение-функция не может разрешать dbcontext в функциях, поскольку оно может разрешать только BindingContext. Вам необходимо создать пользовательские привязки для использования dbcontext непосредственно в приложении-функции.

Другой способ получить dbcontext, введенный через DI, - передать его конструктору и использовать переменную уровня класса в функции.

      public class ParseThings
{
    private AvastusContext _context;
    public ParseThings(AvastusContext context){
        _context = context;
    }

    [FunctionName("ParseThings")]
    public void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log){
      // use _context here
    }
}

Если он по-прежнему не решается, вы можете проверить, правильно ли настроен functionsStartup.

Другие вопросы по тегам