.NET Core 2.2 Функция Azure v2 Внедрение зависимостей - PullRequest
6 голосов
/ 27 марта 2019

У меня проблема с регистрацией синглтона с использованием Microsoft.Extensions.DependencyInjection.Я создал Startup класс (который определенно работает) и создал ITestService с реализацией.

Синглтон вводится в конструктор функции.Изначально у меня не было проблем с этой реализацией, однако через пару дней функция перестала работать, потому что она не может разрешить ITestService.Я понятия не имею, почему.

вот класс Startup

using Microsoft.Azure.WebJobs.Hosting;

[assembly: WebJobsStartup(typeof(Startup))]
namespace Test.Functions
{
    using System;

    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;

    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("local.settings.json", true, true)
                .AddEnvironmentVariables()
                .Build();

            builder.Services.AddSingleton<ITestService>(new TestService("test string"));
        }
    }
}

А вот функция

public class TestFunction
{
    private readonly ITestService testService

    public TestFunction(ITestService testService)
    {
        this.testService = testService ?? throw new ArgumentNullException(nameof(testService));
    }

    [FunctionName(nameof(TestFunction))]
    public void Run([ServiceBusTrigger("test", Connection = "ServiceBusConnection")]Message message, ILogger log)
    {
        ////use test service here
    }
}

Когда я отлаживаю запуск и смотрю на Services Я вижу, что тип реализации null для ITestService, поэтому я предполагаю, что он не будет разрешен.Как я уже говорил, это работало в течение пары дней.Версия функций и т. Д. Не изменилась.Буду очень признателен за любые идеи, как заставить это работать снова.

update

Я попытался упростить это еще больше и создал другой фиктивный интерфейс с реализацией, которая имеетконструктор без параметров.Я добавил его, используя: builder.AddSingleton<ITestService2, TestService2>()

Он явно назначил тип типу реализации, но когда пришло время вставить его в конструктор, произошел сбой с тем же исключением.

Ответы [ 3 ]

5 голосов
/ 27 марта 2019

Существует регрессия в последней версии хоста функции, которая прервала внедрение зависимостей.

Чтобы обойти это в среде Azure, вы можете заблокировать конкретную версию хоста функций, установивдля приложения FUNCTIONS_EXTENSION_VERSION установлено значение 2.0.12342.0.

Если вы запускаете узел функции локально с использованием пакета azure-functions-core-tools NPM, обязательно используйте 2.4.419 в качестве последней версииверсия (2.4.498) приводит к той же проблеме.Вы можете установить это явно с помощью следующего:

npm i -g azure-functions-core-tools@2.4.419

См. Эту проблему GitHub для получения дополнительной информации.

2 голосов
/ 27 марта 2019

Попробуйте это в своем коде:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ITestService, TestService>();
}
1 голос
/ 27 марта 2019

Попробуй с этим

  builder.Services.AddSingleton<ITestService>(s => new TestService("test string"));

Здесь используется IServiceProvider, чтобы предоставить конструктору параметр string.

РЕДАКТИРОВАТЬ:

Попробуйте изменить код на приведенный ниже и установить Willezone.Azure.WebJobs.Extensions.DependencyInjection

Это добавляет метод расширения AddDependencyInjection и позволяет выполнять традиционный вызов метода ConfigureServicesпри запуске приложения net core.

using Microsoft.Azure.WebJobs.Hosting;

 [assembly: WebJobsStartup(typeof(Startup))]
   namespace Test.Functions
{
using System;

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

public class Startup : IWebJobsStartup
{
    public void Configure(IWebJobsBuilder builder)
    {
        var configuration = new ConfigurationBuilder()
            .SetBasePath(Environment.CurrentDirectory)
            .AddJsonFile("local.settings.json", true, true)
            .AddEnvironmentVariables()
            .AddDependencyInjection(ConfigureServices)
            .Build();

    }
  private void ConfigureServices(IServiceCollection services)
  {
    services.AddSingleton<ITestService>(s => new TestService("test string"));
  }
}

}

...