我将我的 Azure Functions 项目从 dotnet 6 升级到 dotnet 8,并开始使用 dotnet-isolated 而不是 dotnet。我注意到添加到函数签名后所有有效的对象都不再有效。例如,
[FunctionName("FunctionName")]
public static async Task Run([TimerTrigger("45 0 0 * * *")]TimerInfo myTimer, [DurableClient] IDurableOrchestrationClient starter, Binder binder, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed with frequency: {myTimer}");
await csvFileCreater(binder).ConfigureAwait(false);
log.LogInformation($"FunctionName - completed.");
}
private static async Task<string> csvFileCreater(Binder binder)
{
string csvFileName = CommonUtils.GenerateCSVFileName();
var attributes = new Attribute[]
{
new BlobAttribute($"containerName/{csvFileName}"),
new StorageAccountAttribute("AzureWebsJobsStorage")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
writer.Write($"ColumnName ");
}
return csvFileName;
}
从上面的示例代码中,
Binder
和ILogger
对象都不为空,在我的项目中已成功使用。
但是,升级到 dotnet 8 后,这两个对象都变成了 null。我找到了日志记录的解决方法,并通过将日志记录添加到我的
program.cs
文件中启用了日志记录:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices((appBuilder, services) =>
{
var config = appBuilder.Configuration;
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddSingleton<Binder, Binder>();
services.AddHttpClient();
})
.ConfigureLogging(logging =>
{
logging.Services.Configure<LoggerFilterOptions>(options =>
{
LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (defaultRule is not null)
{
options.Rules.Remove(defaultRule);
}
});
})
.Build();
host.Run();
如何将
Binder
或任何其他对象添加到我的函数中而不使该对象为空?
我认为依赖注入与 .NET 8 Azure Functions 中的静态方法的工作方式不同。我不知道如何让它与静态方法一起工作。
无论如何,您需要进行一些更改,因为隔离模式是基于完全不同的 NuGet 包集工作的。
进程内模式使用这些NuGet:
Microsoft.Azure.WebJobs.Extensions.DurableTask
Microsoft.NET.Sdk.Functions
隔离模式用途:
Microsoft.Azure.Functions.Worker.Sdk
Microsoft.Azure.Functions.Worker
Microsoft.Azure.Functions.Worker.Extensions.DurableTask
❗ 不要忘记设置环境变量:
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
本地应在
中设置。部署时,应在 Azure Function Azure 资源的配置中将其设置为环境变量。local.settings.json
如何找出解决方案:
static
Binder
Binder
所以,你应该这样定义你的函数:
// IMPORTANT: Class is not `static`
public class Function1
{
private readonly Binder _binder;
// Dependency Injection of the `Binder` instance via constructor
public Function1(Binder binder)
{
_binder = binder;
}
// IMPORTANT: Class method is not `static`
[Function("FunctionName")]
public async Task Run(
[TimerTrigger("45 0 0 * * *")] TimerInfo myTimer,
// This is how you inject the `DurableTaskClient`
[DurableClient] DurableTaskClient client,
// You also need to inject standard `FunctionContext`
FunctionContext functionContext)
{
// Create a logger
ILogger logger = functionContext.GetLogger("FunctionName");
// Use the `Binder` injected via constructor and saved to a field
var guid = _binder.Id;
logger.LogInformation("Guid: {guid}", guid);
}
}
// Sample class
public class Binder
{
public Guid Id { get; } = Guid.NewGuid();
}
主机和 DI 配置如下所示:
// Program.cs
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
// The only custom line added
services.AddSingleton<Binder>();
})
.Build();
在我的例子中:
Binder
使用依赖注入通过构造函数注入DurableTaskClient
和 FunctionContext
传递给该方法executionContext.GetLogger()