【问题标题】:.NET Core 2.2 Azure Function v2 Dependency Injection.NET Core 2.2 Azure Function v2 依赖注入
【发布时间】:2023-03-03 01:28:01
【问题描述】:

我在使用 Microsoft.Extensions.DependencyInjection 注册单身人士时遇到问题。我创建了一个Startup 类(肯定可以工作)并创建了一个带有实现的ITestService

单例被注入到函数的构造函数中。最初我对此实现没有任何问题,但是,几天后该函数失败,因为它无法解析ITestService。我不知道为什么。

这里是 Startup

using Microsoft.Azure.WebJobs.Hosting;

[assembly: WebJobsStartup(typeof(Startup))]
namespace Test.Functions
{
    using System;

    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;

    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("local.settings.json", true, true)
                .AddEnvironmentVariables()
                .Build();

            builder.Services.AddSingleton<ITestService>(new TestService("test string"));
        }
    }
}

这里是函数

public class TestFunction
{
    private readonly ITestService testService

    public TestFunction(ITestService testService)
    {
        this.testService = testService ?? throw new ArgumentNullException(nameof(testService));
    }

    [FunctionName(nameof(TestFunction))]
    public void Run([ServiceBusTrigger("test", Connection = "ServiceBusConnection")]Message message, ILogger log)
    {
        ////use test service here
    }
}

当我调试启动并查看Services 时,我看到ITestService 的实现类型是null,我认为这就是它无法解决的原因。就像我提到的那样,这完全工作了几天。功能版本等没有改变。任何如何让这项工作再次发挥作用的想法将不胜感激。

更新

我试图进一步简化这一点,并创建了另一个具有无参数构造函数的实现的虚拟接口。我使用以下方法添加了它: builder.AddSingleton&lt;ITestService2, TestService2&gt;()

它显然将类型分配给实现类型,但是当将其注入构造函数时它失败了,同样无法激活异常。

【问题讨论】:

  • 你用 services.BuildServiceProvider() 试过了吗
  • @Azzy 我确实尝试过,但没有解决问题。

标签: c# .net-core azure-functions


【解决方案1】:

最新版本的函数宿主中有一个回归,它破坏了依赖注入。

为了在 Azure 环境中解决此问题,您可以通过将 FUNCTIONS_EXTENSION_VERSION 应用程序设置设置为 2.0.12342.0 来锁定函数宿主的特定版本。

如果您使用 azure-functions-core-tools NPM 包在本地运行函数主机,请务必使用 2.4.419,因为最新版本 (2.4.498) 会导致相同的问题。您可以使用以下命令显式安装:

npm i -g azure-functions-core-tools@2.4.419

有关更多背景信息,请参阅此GitHub issue

【讨论】:

    【解决方案2】:

    在你的代码中试试这个:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<ITestService, TestService>();
    }
    

    【讨论】:

    • 关于投票者。建议是正确的。查看文档:docs.microsoft.com/en-us/dotnet/api/…。解释为什么是反对票应该是一个很好的做法。
    • @AzzyElvul 看起来对builder.Services.AddSingleton&lt;ITestService&gt;(new TestService("test string")); 的调用也是正确的,该建议可能只是无法回答最初的问题...
    • 我没有投反对票,但是如果您注意到 TestService 将字符串作为参数,那么您的解决方案将无法正常工作
    • 不幸的是,这不起作用,因为在启动时依赖关系TestService 需要一个字符串值来满足构造函数。
    【解决方案3】:

    试试这个

      builder.Services.AddSingleton<ITestService>(s => new TestService("test string"));
    

    这使用IServiceProvider 以便向构造函数提供string 参数。

    编辑:

    尝试将您的代码更改为以下代码并安装Willezone.Azure.WebJobs.Extensions.DependencyInjection

    这添加了扩展方法AddDependencyInjection,并允许您在网络核心应用程序启动中执行传统的ConfigureServices 方法调用。

    using Microsoft.Azure.WebJobs.Hosting;
    
     [assembly: WebJobsStartup(typeof(Startup))]
       namespace Test.Functions
    {
    using System;
    
    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    
    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("local.settings.json", true, true)
                .AddEnvironmentVariables()
                .AddDependencyInjection(ConfigureServices)
                .Build();
    
        }
      private void ConfigureServices(IServiceCollection services)
      {
        services.AddSingleton<ITestService>(s => new TestService("test string"));
      }
    }
    

    }

    【讨论】:

    • 我试过了,但结果还是一样。这实际上很有意义,因为这是我使用 Autofac 时所做的。
    • @AnotherDev 很奇怪。我们全面使用这种方法并且效果很好。
    • 该扩展方法实际上挂起构建器对象,因此 builder.AddDependencyInjection(ConfigureService)。我试过了,还是没有骰子
    猜你喜欢
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2021-10-23
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    相关资源
    最近更新 更多