Как получить доступ к моей конфигурации из статической функции в .Net Core 2.1? - PullRequest
0 голосов
/ 18 июня 2019

Я создаю веб-задание Azure в .Net Core 2.1 (через «консольное» приложение в Visual Studio).В этом проекте у меня есть статическая функция, которая читает сообщения из очереди.В этой функции мне нужно использовать строки подключения (из моей конфигурации) для записи в базу данных.Это мои настройки:

Program.cs

class Program
{
    static void Main(string[] args)
    {
        var builder = new HostBuilder();
        builder.ConfigureWebJobs(b =>
        {
            b.AddAzureStorageCoreServices();
            b.AddAzureStorage();
        });
        builder.ConfigureAppConfiguration((hostContext, config) =>
        {
            var conf = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();
            config.AddConfiguration(conf);
            config.AddEnvironmentVariables();
        })
        builder.ConfigureLogging((context, b) =>
        {
            b.AddConsole();
        });
        var host = builder.Build();
        using (host)
        {
            host.Run();
        }
    }
}

Functions.cs

public class Functions
{
    public static void ProcessQueueMessage([QueueTrigger("myqueue")] string message, ILogger logger, IConfiguration configuration)
    {
        logger.LogInformation(message);
        logger.LogInformation(configuration.GetConnectionString("MyDatabase"));
    }
}

appsettings.json

{
  "ConnectionStrings": {
    "MyDatabase": "foo",
    "AzureWebJobsDashboard": "foo2",
    "AzureWebJobsStorage": "foo3"
  }
}

Однако, когда я запускаю это, я получаю следующую ошибку:

Ошибка индексации метода 'Functions.ProcessQueueMessage'

Невозможно привязать параметр 'configuration' к типу IConfiguration.Убедитесь, что параметр Type поддерживается привязкой.Если вы используете привязки расширений (например, хранилище Azure, ServiceBus, таймеры и т. Д.), Убедитесь, что вы вызвали метод регистрации расширений в своем коде запуска (например, builder.AddAzureStorage (), builder.AddServiceBus (), builder.AddTimers () и т.И я считаю, что это проблема.Я также вижу много примеров того, как реализовать и использовать конфигурацию из функции Main, но не из статической вспомогательной функции, подобной этой.Как правильно реализовать мою конфигурацию из моей статической функции?

1 Ответ

0 голосов
/ 19 июня 2019

Попробуйте изменить подход и не пытаться внедрять IConfiguration

создать класс для хранения желаемых настроек

public class MyOptions {
    public string MyDatabase { get; set; }
}

Измените настройку, чтобы также использовать ConfigureServices и извлечьтребуемая конфигурация для заполнения объекта настроек и добавления его в коллекцию сервисов

var builder = new HostBuilder();
builder
    .ConfigureWebJobs(b => {
        b.AddAzureStorageCoreServices();
        b.AddAzureStorage();
    })
    .ConfigureAppConfiguration(config => { //not using context so no need for it really
        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();
        config.AddEnvironmentVariables();
    })
    //...ADDITION HERE
    .ConfigureServices((context, services) => {
        //configuration should be available by now, so access what you need.
        var connectionString = context.Configuration.GetConnectionString("MyDatabase");
        //If null you have the option to fail early, otherwise carry on.
        var myOptions = new MyOptions {
            MyDatabase = connectionString;
        };
        services.AddSingeton(myOptions);
    }
    .ConfigureLogging((context, b) => {
        b.AddConsole();
    });

//...

Таким образом, на этом этапе вы сможете добавить свой объект в качестве зависимости к функции

public class Functions {
    public static void ProcessQueueMessage(
        [QueueTrigger("myqueue")] string message, 
        ILogger logger, 
        MyOptions options) {
        logger.LogInformation(message);
        logger.LogInformation(options.MyDatabase);
    }
}

Лично я считаю, что попытка получить доступ к IConfiguration вне стартапа доставляет больше хлопот, чем стоит, и даже оценила бы его с помощью анти-паттерна поиска сервисов и введения IServiceProvider.Получите то, что вам нужно от него во время установки, зарегистрируйте это в сервис-коллекции, чтобы оно было доступно для внедрения там, где это необходимо.

...