我正在.Net Core 2.1中创建一个Azure Web作业(通过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类型。使 确保绑定支持参数类型。如果您正在使用 绑定扩展(例如Azure存储,ServiceBus,计时器等) 确保您已在中调用扩展的注册方法 您的启动代码(例如builder.AddAzureStorage(), builder.AddServiceBus(),builder.AddTimers()等)。
我对.Net Core非常陌生,尤其是DI模式。我认为这就是问题所在。我还看到了许多示例,这些示例说明如何从Main
函数内部而不是从像这样的静态辅助函数内部实现和使用配置。如何从静态函数中正确实现配置?
答案 0 :(得分:0)
请考虑更改方法,而不要尝试注入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
对其进行排名。在设置过程中从中获取所需的信息,并在服务集合中进行注册,以便在明确需要时可将其用于注入。