Azure WebJobs 从静态函数中访问配置

Azure WebJobs access configuration from within a static function

我正在 .net core 3.1 中创建一个网络作业。在这个项目中,我有一个计时器激活的功能,它应该读取队列 Q1 中的消息数量,如果为空,则将消息放入 Q2 并触发对 API.[=26= 的休息调用]

为了检查 API 中有多少消息,我需要访问我的 appsettings.json 中的 AzureWebJobsStorage,然后是也在 url 中的 url设置。

Program.cs

class Program
    {
        static async Task Main()
        {
            var builder = new HostBuilder();
            builder.ConfigureWebJobs(b =>
                {
                    b.AddAzureStorageCoreServices();
                    b.AddAzureStorage();
                    b.AddTimers();
                });
            builder.ConfigureLogging((context, b) =>
                {
                    b.AddConsole();
                });
            builder.ConfigureAppConfiguration((context, b) => 
            {
                b.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
            });
            builder.ConfigureServices((context, services) =>
            {
                var mySettings = new MySettings
                {
                    AzureWebJobsStorage = context.Configuration.GetValue<string>("AzureWebJobsStorage"),
                    AzureWebJobsDashboard = context.Configuration.GetValue<string>("AzureWebJobsDashboard"),
                    url = context.Configuration.GetValue<string>("url"),
                };
                services.AddSingleton(mySettings);
            });
            var host = builder.Build();
            using (host)
            {
                await host.RunAsync();
            }
        }
    }

Fuctions.cs

public class Functions
    {
public static void UpdateChannels([QueueTrigger("Q1")] string message, ILogger logger)
        {
            logger.LogInformation(message);
        }

        public static void WhatIsThereToUpdate([QueueTrigger("Q2")] string message, ILogger logger)
        {
            logger.LogInformation(message);
        }

        public static void CronJob([TimerTrigger("0 * * * * *")] TimerInfo timer, [Queue("Q2")] out string message, ILogger logger, MySettings mySettings)
        {
            message = null;
            // Get the connection string from app settings
            string connectionString = mySettings.AzureWebJobsStorage;
            logger.LogInformation("Connection String: " + connectionString);
            // Instantiate a QueueClient which will be used to create and manipulate the queue
            QueueClient queueClient = new QueueClient(connectionString, "Q1");
            if (queueClient.Exists())
            {
                QueueProperties properties = queueClient.GetProperties();

                // Retrieve the cached approximate message count.
                int cachedMessagesCount = properties.ApproximateMessagesCount;

                // Display number of messages.
                logger.LogInformation($"Number of messages in queue: {cachedMessagesCount}");

                if (cachedMessagesCount == 0)
                    message = "Hello world!" + System.DateTime.Now.ToString(); //here I would call the REST API as well
            }

            logger.LogInformation("Cron job fired!");
        }
    }

appsettings.json

{
  "AzureWebJobsStorage": "constr",
  "AzureWebJobsDashboard": "constr",
  "url": "url"
}

我的设置

public class MySettings
    {
        public string AzureWebJobsStorage { get; set; }
        public string AzureWebJobsDashboard { get; set; }
        public string url { get; set; }
    }

然而,当我 运行 这样做时,我得到以下错误:

Error indexing method 'Functions.CronJob' Microsoft.Azure.WebJobs.Host.Indexers.FunctionIndexingException: Error indexing method 'Functions.CronJob' ---> System.InvalidOperationException: Cannot bind parameter 'mySettings' to type MySettings. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

除了上面代码中显示的内容外,我还尝试使用 ConfigurationManagerEnvironment.GetEnvironmentVariable,当我尝试读取值时,这两种方法都给了我 null。例如 ConfigurationManager.AppSettings.GetValues("AzureWebJobsStorage").

我也尝试将IConfiguration注册为服务services.AddSingleton(context.Configuration);并将其注入参数(而不是MySettings),但它也给了我同样的绑定错误。

我真的在这里不知所措,我搜索了 SO 档案试图找到解决方案,我想我尝试了我看到的一切给人们带来积极的结果,但不幸的是我没有其他人那么幸运海报。

非常感谢任何指导。

编辑以添加我的包

如果它对任何人有帮助,我正在使用以下内容

Azure.Storage.Queues (12.4.0)

Microsoft.Azure.WebJobs.Extensions (3.0.6)

Microsoft.Azure.WebJobs.Extensions.Storage (4.0.2)

Microsoft.Extensions.Logging.Console (3.1.7)

使用DI时,建议使用non-static方法和构造函数注入。

这里是 Functions.cs:

public class Functions
{
    private readonly MySettings mySettings;

    public Functions(MySettings _mySettings)
    {
        mySettings = _mySettings;
    }

    public void ProcessQueueMessage([TimerTrigger("0 */1 * * * *")] TimerInfo timer, [Queue("queue")] out string message, ILogger logger)
    {
        message = null;
        string connectionString = mySettings.AzureWebJobsStorage;
        logger.LogInformation("Connection String: " + connectionString);
    }
}

其他 .cs 文件中没有代码更改。

测试结果如下: