.net-core - 无法使用 DI 内部函数与 .net core Azure Web 作业中的 ServiceBusTrigger 参数绑定(bind)服务实现

标签 .net-core dependency-injection azureservicebus azure-webjobs azure-servicebus-queues

我有一个 .net core 控制台应用程序,我将部署为 Azure Web 作业。该作业的目的是监听 Azure 服务总线队列中的新消息。我已使用包含 [ServiceBusTrigger] 属性的函数设置监听器。我构建了一个虚拟实现,它只从队列中读取最新消息 - 这可以正常工作 - 消息从服务总线队列正确传递到我的函数。

当我尝试进入下一个级别并向要由 DI 注入(inject)的函数添加接口(interface)参数时,出现错误。

Microsoft.Azure.WebJobs.Host.Indexers.FunctionIndexingException: 'Error indexing method 'Functions.ProcessMeasurementData'' InvalidOperationException: Cannot bind parameter 'service' to type IProcessMeasurementService. 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.).

这是我的职责。如果我删除参数 IProcessMeasurementService 服务,它可以从 Visual Studio 2019 本地运行(我还没有尝试将其作为 Web 作业部署到 azure),并在新项目添加到 Azure 服务总线队列时拾取新项目。

public class Functions
{
    public static async Task ProcessMeasurementData(
        [ServiceBusTrigger("process-measurement-data-queue", Connection = "AzureWebJobsServiceBus")] Message message,
    IProcessMeasurementService service)
    {
        try
        {

            var measurements = JsonConvert
                .DeserializeObject<List<CreateMeasurementInput>>
                    (Encoding.UTF8.GetString(message.Body));

            await service.DoStuff(measurements);

            // log.LogInformation(message.ContentType);
        }
        catch (Exception e)
        {

            throw;
        }
    }

我认为我正确注册了服务,如下所示:

            {
                // Register application services
                services.AddSingleton<IProcessMeasurementService, ProcessMeasurementService>();
            });

这是我的主要功能。

        static void Main(string[] args)
    {
        var builder = new HostBuilder();

        builder.ConfigureAppConfiguration((builder) =>
        {
            builder

                .AddJsonFile("appsettings.json", false, true)
                .AddEnvironmentVariables();
        });


        builder.ConfigureWebJobs(b =>
        {
            b.AddServiceBus(x =>
            {
                x.MessageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
                {
                    AutoComplete = false
                };
            });

            b.AddAzureStorageCoreServices();
        });

        builder.ConfigureServices(services =>
        {
            services.AddOptions();

            // Register application services
            services.AddSingleton<IProcessMeasurementService, ProcessMeasurementService>();
        });

        var host = builder.Build();

        using (host)
        {
            host.Run();
        }
    }

通过谷歌搜索,感觉问题可能与我的 nuget 软件包版本有关。我尝试添加一个名为“host.json”的文件,以防这是 ​​azure 函数版本与扩展库冲突的已知问题。但它什么也没做。我实际上并没有使用 AzureFunctions(我的意思是无服务器函数),但现阶段我正在捕获救命稻草。

有人知道问题出在哪里吗?

这是 host.json,以防万一出现问题。

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  }
}

这是我安装的 nuget 版本

<PackageReference Include="Microsoft.Azure.ServiceBus" Version="4.1.2" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.16" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="4.1.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Sources" Version="3.0.16" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />

最佳答案

从静态函数方法更改为实例成员,并通过构造函数注入(inject)将服务直接注入(inject)到函数类中。

public class Functions {

    private readonly  IProcessMeasurementService service;

    public Functions (IProcessMeasurementService service) {
        this.service = service;
    }

    public async Task ProcessMeasurementData(
        [ServiceBusTrigger("process-measurement-data-queue", Connection = "AzureWebJobsServiceBus")] Message message) 
    {
        try {

            var measurements = JsonConvert
                .DeserializeObject<List<CreateMeasurementInput>>
                    (Encoding.UTF8.GetString(message.Body));

            await service.DoStuff(measurements);

            // log.LogInformation(message.ContentType);
        } catch (Exception e) {
            //...    
            throw;
        }
    }
}

关于.net-core - 无法使用 DI 内部函数与 .net core Azure Web 作业中的 ServiceBusTrigger 参数绑定(bind)服务实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60695024/

相关文章:

c# - 如何允许需要 Authorization header 的缓存 API 端点?

javascript - 模块 'ngRoute' 不可用

c# - 为什么将人工引发的Transient Error异常作为AggregateException处理?

azure - 代理连接是如何计算的?

c# - 是否可以在没有管理权限策略的情况下将 MassTransit 3 与 Azure 服务总线结合使用?

c# - Microsoft Visual Studio 2019 : The project file cannot be opened. 无法定位 .NET SDK

asp.net - 针对整个框架的项目的asp.net core 2.0 docker镜像

c# - 如何覆盖在某些测试中使用 IWebHostBuilder.ConfigureTestServices 模拟的服务

c# - Unity Bootstrapper (Unity.Mvc), Unity 3, MVC 5, EF6 接收错误 : Parameterless Public Constructor on Controller

javascript - 如何将使用 $scope 的函数包含/注入(inject)到 angularjs 的 Controller 中?