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

Container has different rules for .net 5 web app and test project

我有一个使用 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()
    {
        ...
    }
}

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

DryIocServiceProviderFactory 将覆盖现有容器规则以符合 MS.DI 容器。这是代码:https://github.com/dadhi/DryIoc/blob/5e3f1f7edfe237f69ba33c9166d17e284ca4781a/src/DryIoc.Microsoft.DependencyInjection/DryIocAdapter.cs#L97

这里详细介绍了如何覆盖规则:

private static Rules WithMicrosoftDependencyInjectionRules(Rules rules) 
{ 
    rules = rules.Clone(cloneMade: true);

    rules._settings |= Settings.TrackingDisposableTransients;
    rules._settings &= ~Settings.ThrowOnRegisteringDisposableTransient;
    rules._settings &= ~Settings.VariantGenericTypesInResolvedCollection;
    rules._factorySelector = SelectLastRegisteredFactory;
    rules._made._factoryMethod = DryIoc.FactoryMethod.ConstructorWithResolvableArguments;
 
    return rules; 
}