容器对 .net 5 web 应用程序和测试项目有不同的规则

问题描述

我有一个使用 DryIoc 的小型 .net 5 WebApi 应用程序。我现在正在尝试为此应用程序设置 xUnit 测试套件,但集成测试立即失败,因为其中一个注册具有多个构造函数,即使我对两个容器使用相同的规则并以相同的顺序运行相同的注册作为应用程序。

应用程序的注册工作正常,因为容器为工厂方法设置了 ConstructorWithResolvableArguments,但它不是从我们代码中的任何位置设置的。我知道我可以轻松地将该规则添加到用于测试的容器中,但我不明白为什么以完全相同的方式设置的容器似乎具有不同的规则,而且我担心可能存在其他差异可能会影响测试。

在应用中,容器是这样设置的:

Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new DryIocServiceProviderFactory(Startup.CreateContainer()))
            .ConfigureWebHostDefaults(...);

StartUp.cs

...
public static IContainer CreateContainer() => new Container(DiConfiguration.SetRules);

public void ConfigureContainer(IContainer container)
{
    container.RegisterCoreDependencies();

    // Site specific registrations
    container.ConfigureDomain();
}

DiConfiguration.cs

public static class DiConfiguration
{
    public static Rules SetRules(Rules rules)
    {
        rules = rules.WithAutoConcreteTypeResolution();
        rules = rules.WithVariantGenericTypesInResolve();

        return rules;
    }

    public static void RegisterCoreDependencies(this IContainer container)
    {
        // dependency registrations,not much to see here,nothing clever 
        // just basic registrations e.g.

        container.Register<IFoo,Foo>();
    }

在测试套件中,我像这样设置容器:

public class Test
{
    private object _sut;

    public Test()
    {
        var container = new Container(DiConfiguration.SetRules); // <--- Same rules as the app
        container.RegisterCoreDependencies(); // <--- fails here
        container.ConfigureDomain();

        _sut = container.Resolve<Bar>();
    }

    [Fact]
    public void Some_Test_Here()
    {
        ...
    }
}

如您所见,所有容器注册代码都被抽象为一个共享库(DiConfiguration 类)。测试调用 RegisterCoreDependencies 失败。我不明白为什么这两种情况的规则不同,可能是应用程序中的 DryIocServiceProviderFactory 调用引入了一些额外的默认值吗? (DryIocServiceProviderFactoryDryIoc.Microsoft.DependencyInjection 包的一部分)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)