【问题标题】:Intermittent dependency injection failure间歇性依赖注入失败
【发布时间】:2019-04-25 20:43:20
【问题描述】:

尝试在 .net core 2.1 azure 函数应用程序中解析服务时,我在本地看到以下间歇性异常。它似乎仅在函数同时处理多个消息并且仅使某些消息失败时才会发生。

'System.Private.CoreLib:执行函数时出现异常:FunctionOne。 Microsoft.Extensions.DependencyInjection:尝试激活“XXX.Service2”时,无法解析“Microsoft.Extensions.Configuration.IConfiguration”类型的服务。

当服务与函数在同一个项目中时,一切正常。只有当我将它移到另一个项目时才会发生这种情况。我创建的另一个项目只是一个简单的 .net 标准 2.0 项目,其中仅包含此服务和对 Microsoft.Extensions.Configuration nuget 的引用。

我知道这个实现使用了一个反模式的服务定位器,但我仍然想了解为什么会发生这个异常。

[FunctionName("FunctionOne")]
public static void Run(
    [QueueTrigger(_queue, Connection = _storageConnection)]
    string queueItem,
    ILogger trace)
{
    // Startup
    var services = Startup.GetServices();

    // Services
    var service = services.GetService<IService2>();
}
public static class Startup
{
    public static Func<IServiceProvider> GetServices = CreateServices;

    public static IConfiguration GetConfiguration()
    {
        return new ConfigurationBuilder()
             .AddEnvironmentVariables()
             .Build();
    }

    private static IServiceProvider CreateServices()
    {
        var services = new ServiceCollection();

        var config = GetConfiguration();

        services
            .AddSingleton(config)
            .AddSingleton<IService2, Service2>();

        return services.BuildServiceProvider();
    }
}
public class Service2 : IService2
{
    public Service2(IConfiguration configuration)
    {
    }
}
public interface IService2
{
}

【问题讨论】:

    标签: c# azure dependency-injection azure-functions


    【解决方案1】:

    尝试将其作为 IConfigurationRoot 而不是 IConfiguration 注入:

    public HomeController(IConfigurationRoot configuration
        , IService2 service)
    {
        _mailService = service;
        _to = configuration["emailAddress.Support"];
    }
    

    在这种情况下,行

    services.AddSingleton(provider => Configuration);
    

    等价于

    services.AddSingleton<IConfigurationRoot>(provider => Configuration);
    

    因为类上的 Configuration 属性是这样声明的,并且注入将通过匹配它注册为的任何类型来完成。我们可以很容易地复制它,这可能会更清楚:

    试试这个,看看是否有帮助。

    【讨论】:

      【解决方案2】:

      这似乎是运行时版本 2.0.12408.0 中引入的“功能”。 2.0.12382.0 不会发生这种情况。

      【讨论】:

      • 这不是使用 DI 功能,而只是构建服务提供者并直接在函数中使用的静态类和方法。我们很快就会有文档提供有关如何使用实际功能执行上述操作的指导。您上面的代码没有使用任何特定于函数的东西。
      • 是的,这不使用 DI 功能,但不管异常只发生在较新版本的运行时。
      猜你喜欢
      • 2017-09-16
      • 2012-08-13
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多