.NET Core 2.2 Azure Function v2依赖关系注入

时间:2019-03-27 13:07:46

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

我在使用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时,我发现null的实现类型为ITestService,我认为这是为什么它无法解析的原因。就像我提到的那样,这完全可以工作几天。功能等的版本未更改。任何关于如何使它再次工作的想法将不胜感激。

更新

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

它显然将类型分配给实现类型,但是当需要将其注入到构造函数中时,由于相同的失败而无法激活异常。

3 个答案:

答案 0 :(得分:5)

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

为了在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

答案 1 :(得分:2)

在您的代码中尝试一下:

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

答案 2 :(得分:1)

一起去

  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"));
  }
}

}