IExtensionConfigProvider не инициализируется и не связывается с Microsoft.Azure.WebJobs v3 - PullRequest
0 голосов
/ 01 сентября 2018

Мы используем внедрение зависимостей в нашей функции Azure (v2 на netstandard20), используя привязку параметров с IExtensionConfigProvider. После обновления Microsoft.NET.Sdk.Functions с версии 1.0.13 до 1.0.19 (что привело к обновлению Microsoft.Azure.Webjobs.Host до версии 3) это больше не работает. Я больше не могу достичь точки останова в моей функции IExtensionConfigProvider.Initialize. Та же версия Functions SDK прекрасно работает для примера проекта с целевой платформой net462, для которой он использует Microsoft.Azure.WebJobs v2.

Вот ошибка, которую выдает во время выполнения:

Ошибка индексации метода 'Function1.Run'. Microsoft.Azure.WebJobs.Host: Невозможно привязать параметр 'customThing' к типу CustomType. Убедитесь, что Тип параметра поддерживается привязкой.

А вот код для примера приложения:

    public static class Function1
{
    [FunctionName("ThisFunction")]
    public static async Task Run(
        [TimerTrigger("0 */1 * * * *")]TimerInfo timer,
        [Inject(typeof(CustomType))] CustomType customThing,
        ExecutionContext context)
    {
        Console.WriteLine(customThing.GetMessage());
    }
}

public class CustomType
{
    public string GetMessage() => "Hi";
}

[Binding]
[AttributeUsage(AttributeTargets.Parameter)]
public class InjectAttribute : Attribute
{
    public Type Type { get; }
    public InjectAttribute(Type type) => Type = type;
}

public class InjectConfiguration : IExtensionConfigProvider
{
    private IServiceProvider _serviceProvider;

    public void Initialize(ExtensionConfigContext context)
    {
        var services = new ServiceCollection();
        services.AddSingleton<CustomType>();
        _serviceProvider = services.BuildServiceProvider(true);

        context
            .AddBindingRule<InjectAttribute>()
            .BindToInput<dynamic>(i => _serviceProvider.GetRequiredService(i.Type));
    }
}

1 Ответ

0 голосов
/ 03 сентября 2018

С изменениями, внесенными в v3 в DI и моделью расширения для создания расширения (реализация IExtensionConfigProvider является расширением), теперь вам сначала нужно создать класс запуска, используя [сборка: WebJobsStartup] атрибут сборки и реализация интерфейса IWebJobsStartup . Там вы можете добавить свои собственные сервисы в компоновщик через builder.Services и зарегистрировать класс провайдера конфигурации вашего расширения:

[assembly: WebJobsStartup(typeof(WebJobsExtensionStartup ), "A Web Jobs Extension Sample")]
namespace ExtensionSample
{
    public class WebJobsExtensionStartup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
             //Don't need to create a new service collection just use the built-in one
             builder.Services.AddSingleton<CustomType>();                 

             //Registering an extension
             builder.AddExtension<InjectConfiguration>(); 
        }
    } 
}

Затем в вашем IExtensionConfigProvider вы можете внедрить любые зависимости с помощью инъекций конструктора, например, binding, bindingproviders или любую другую пользовательскую зависимость. В вашем случае вы можете просто получить ссылку на встроенный IServiceProvider :

public class InjectConfiguration : IExtensionConfigProvider
{
    private IServiceProvider _serviceProvider;

    public InjectConfiguration(IServiceProvider serviceProvider)
    {
       _serviceProvider = serviceProvider;
    }

    public void Initialize(ExtensionConfigContext context)
    {         
        context
            .AddBindingRule<InjectAttribute>()
            .BindToInput<dynamic>(i => _serviceProvider.GetRequiredService(i.Type));
    }
}

Чтобы хост загружал расширение, оно должно быть зарегистрировано в файле bin / extensions.json , в функциях JavaScript или Java с помощью команды установки расширений func. В C # SDK 1.0.19 просматривает время сборки для классов, связанных с WebJobsStartup атрибутом сборки в текущем проекте функции или любой зависимостью ( ProjectReference или PackageReference ) текущего проекта и создает соответствующий файл extensions.json.

...