首页 > 解决方案 > 为什么部分封闭的泛型在函数中运行时起作用,但在直接调用 ServiceCollection 时不起作用?

问题描述

我刚刚尝试使用 dotnet 3.1、v3 Azure 函数和 MS DependencyInjection 包的 3.1.8 首次使用部分封闭的通用 DI 注册——在撰写本文时都是最新的。

当设置为构造函数依赖项时,类型会按预期解析。但是,当我直接在容器上调用 GetService<> 时,我得到一个ArgumentException

提供的泛型参数的数量不等于泛型类型定义的数量

如果我在运行时看到这个错误,我会断定不支持部分封闭的泛型,但事实并非如此,我不知道为什么。

public interface IMyInterface<TypeA, TypeB>
{

}

public class MyClass<TypeA> : IMyInterface<TypeA, MyConcreteTypeB>
{
}

services.AddSingleton(typeof(IMyInterface<,>), typeof(MyClass<>));

var myObject = services
   .BuildServiceProvider()
   .GetService<IMyInterface<MyConcreteTypeA, MyConcreteTypeB>>();

myObject.Should().Be().OfType<MyClass<MyConcreteTypeA>>();

我无法将上面的(粗略)代码作为单元测试运行,但我可以将其解析IMyInterface<MyConcreteTypeA, MyConcreteTypeB>为 Azure 函数中的构造函数参数。

更新:

工作示例:https ://github.com/mr-panucci/sandbox

标签: c#asp.net.net.net-coreazure-functions

解决方案


这是个有趣的问题。它在 Function 构造函数中起作用的原因是因为 Function Host 在内部使用DryIoc作为 DI 容器,实现了Microsoft.DependencyInjection. DryIoc 容器反过来支持解析部分封闭的泛型类型。您可以在此处探索 Function Host DI 接线。

现在解决您的单元测试问题,在此处模拟 Function host 的相同行为:

  1. 将 nuget DryIoc.Microsoft.DependencyInjection添加到您的测试项目中。
  2. 更新测试代码如下:
services.AddSingleton(typeof(IMyInterface<,>), typeof(MyClass<>));

var myObject = DryIocAdapter.Create(services).BuildServiceProvider() // using DryIoc.Microsoft.DependencyInjection;
                 .GetService<IMyInterface<MyConcreteTypeA, MyConcreteTypeB>>();

myObject.Should().Be().OfType<MyClass<MyConcreteTypeA>>();

推荐阅读