0

我已经阅读了几个关于这个主题的指南,但没有成功。以下指南给了我很多关于我在官方文档中根本无法理解或找到的设置的提示:

https://codetraveler.io/2021/05/28/creating-azure-functions-using-net-5/

但我仍然在努力寻找一些东西来让它运行。

这是我在本地运行时收到的消息:

未找到工作职能。尝试公开您的工作类别和方法。如果您正在使用绑定扩展(例如 Azure 存储、ServiceBus、计时器等),请确保您已在启动代码中调用了扩展的注册方法(例如 builder.AddAzureStorage()、builder.AddServiceBus( )、builder.AddTimers() 等)。有关详细输出,请使用 --verbose 标志运行 func。

此消息包含我怀疑丢失但我不知道如何解决的内容:ServiceBus 部分。我不确定该函数是否有足够的信息来连接到 ServiceBus。它在配置文件中,但我不知道函数在哪里知道要使用配置的哪一部分。

这是我的功能:

public class MyFunction
{
    private readonly IService1 service;

    public MyFunction(IService1 service)
    {
        this.service = service;
    }

    [FunctionName("Function1")]
    public async Task ProcessMessage([ServiceBusTrigger("topic", "subscription", Connection = "ServiceBusConnectionString")] Message message)
    {
        await service.Process(message);
    }
}

这是我的 appsettings.json 配置文件:

{
  "ConnectionStrings": {
    "ServiceBusConnectionString": "Endpoint=sb://****.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=******"
  }
}

一些 local.settings.json (我想它可以在本地机器上运行)

{
  "IsEncrypted": false,
  "AzureWebJobsStorage": "UseDevelopmentStorage=true",
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
  }
}

程序类:

public class Program
{
    public static Task Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true)
            .Build();

        var builder = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .ConfigureServices((context, services) =>
            {
                services.AddTransient<IService1, service>();
            });
        
        var host = builder.Build();
        return host.RunAsync();
    }
}

我还修改了项目文件以包含:

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
  </PropertyGroup>

和:

  <ItemGroup>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

还添加了一些 Nuget 包:

<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.5.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="4.2.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.0.4" OutputItemType="Analyzer" />

哦,伙计……这是一个巨大的设置!我希望未来的版本可以让它变得更容易!!!

4

1 回答 1

1

查看您的函数代码,我有根据地猜测您正在混合进程内和进程外代码。

要解决这个问题。按着这些次序。

  1. 进程外/隔离进程模型不应使用对Microsoft.Azure.WebJobs.*包的任何引用,例如Microsoft.Azure.WebJobs.Extensions.ServiceBus. 相反,您应该引用Microsoft.Azure.Functions.Worker.Extensions.ServiceBus包。

  2. 使用Function属性而不是FunctionName属性。FunctionName来自Microsoft.Azure.WebJobs我们不应该在进程外/隔离进程功能应用程序中使用的那个。

更改后您的功能代码将如下所示。

public class MyFunction
{
    private readonly IService1 service;
    private readonly ILogger<MyFunction> logger;

    public MyFunction(IService1 service, ILogger<MyFunction> logger)
    {
        this.service = service ?? throw new ArgumentNullException(nameof(service));
        this.logger = logger?? throw new ArgumentNullException(nameof(logger));
    }

    [Function("Function1")]
    public async Task ProcessMessage([ServiceBusTrigger("mytopic",
        "mysubscription", 
        Connection = "ServiceBusConnectionString")] object message)
    {
        logger.LogInformation($"ServiceBus OOP function processed: {message}");
        await service.Process(message);
    }
}

ServiceBusTrigger属性的Connection属性值是用于指定服务总线连接字符串的应用设置条目的名称。对于本地运行,您应该将其保存在local.settings.json文件中,在该Values部分内。您可以添加一个新条目(在现有FUNCTIONS_WORKER_RUNTIME条目之后),如下所示。

{
  "Values": {
    "ServiceBusConnectionString": "PutYourServiceBusConnStringHere"
  }
} 

当您必须在 prod 中运行它时,您将转到您的函数应用程序资源并在Settings -> Configuration下添加一个新的应用程序设置条目。设置条目的名称将是ServiceBusConnectionString。函数运行时将读取此值并使用该值。

我强烈建议您在 Visual Studio 中创建一个新的“azure functions”项目并选择独立进程模型和服务总线触发器。这将为您创建一个新项目,其中包含工作服务总线触发器所需的所有最小部分。

于 2021-09-25T05:10:50.983 回答