添加到 DotNet 8 中的 Azure Functions v4 的对象为空或 Null

问题描述 投票:0回答:1

我将我的 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
或任何其他对象添加到我的函数中而不使该对象为空?

c# .net azure-functions azure-webjobs .net-8.0
1个回答
0
投票

我认为依赖注入与 .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"

本地应在

local.settings.json
中设置。部署时,应在 Azure Function Azure 资源的配置中将其设置为环境变量。


如何找出解决方案:

  • 只需在 Visual Studio 中使用 .NET 8 隔离模式创建一个新的 Azure Function 项目
  • 使函数触发的类和方法不
    static
  • 在 DI 中配置
    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()
  • 创建记录器
© www.soinside.com 2019 - 2024. All rights reserved.