Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模拟和解决AspNetCore与TestServer集成测试中的Autofac依赖关系_C#_Asp.net Core_Integration Testing_Autofac_Asp.net Core Testhost - Fatal编程技术网

C# 模拟和解决AspNetCore与TestServer集成测试中的Autofac依赖关系

C# 模拟和解决AspNetCore与TestServer集成测试中的Autofac依赖关系,c#,asp.net-core,integration-testing,autofac,asp.net-core-testhost,C#,Asp.net Core,Integration Testing,Autofac,Asp.net Core Testhost,我正在使用aspnetcore2.2 以下(更多)是此处的文档: 我使用的是Autofac,我的Startup类有以下方法: public void ConfigureServices(IServiceCollection services) public void ConfigureContainer(ContainerBuilder containerBuilder) //this is where things can be registered directly with autofa

我正在使用aspnetcore2.2 以下(更多)是此处的文档:

我使用的是Autofac,我的Startup类有以下方法:

public void ConfigureServices(IServiceCollection services)
public void ConfigureContainer(ContainerBuilder containerBuilder) //this is where things can be registered directly with autofac and runs after ConfigureServices
public void Configure(...) //the method called by runtime
我使用Autofac的方式,正如其文档所推荐的那样,是使用类似于这样的
Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseKestrel()
            .ConfigureServices(services => services.AddAutofac())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .ConfigureAppConfiguration((builderContext, config) =>
            {
                var env = builderContext.HostingEnvironment;
                config
                    .AddJsonFile("appsettings.json", false, true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true)
                    .AddEnvironmentVariables();
            });
}
如您所见,我想为
IEventStoreManager
使用
MockEventStoreManager
实现,因此这是应该由容器解决的实现。然而,这并没有像预期的那样工作,myService解决的是原始实现,真实的实现,而不是模拟的实现

有人知道我怎样才能达到我想要的吗

更新1: 经过更多的调查后,我不得不在github AspNetCore上创建一个问题,因为扩展方法在ConfigureContainer之前执行,因此我无法真正重写autofac依赖项,也无法稍后检索autofac容器。

更新2: 仅供参考,Startup.cs就是这样的。正如您所看到的,除了mvc之外,所有依赖项都注册在autofac的容器中

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

// This is where things can be registered directly with autofac and runs after ConfigureServices, so it will override it
public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<EventStoreManager>().As<IEventStoreManager>();
}
public void配置服务(IServiceCollection服务)
{
服务
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
//在这里,可以直接向autofac注册并在ConfigureServices之后运行,因此它将覆盖它
公共void配置容器(ContainerBuilder生成器)
{
builder.RegisterType().As();
}

我想做的是在测试中使用
MockEventStoreManager
实现
IEventStoreManager
,因此我需要以一种好的方式覆盖(从测试项目中)Autofac的注册。

有两个选项:

  • 在testserver中自定义依赖项的实现 计划

  • 实现并手动注册一个类似于“Moq”的依赖项的模拟实现


在容器生成器中注册模拟实现,以便使用

/。。。
.ConfigureServices(服务=>services.AddAutofac())
.ConfigureTestContainer(生成器=>{
builder.RegisterType().As();
})
//...
这应该避免获得由
Startup.ConfigureContainer
添加的实际实现

如果多个组件公开同一服务,Autofac将使用最后注册的组件作为该服务的默认提供程序

参考文献


ConfigureTestContainer
启动后被调用。ConfigureContainer
因此最后一次向mock注册将是该服务的默认提供程序。

除了Nkosi的优秀功能之外,我想提一提的是,
ConfigureTestContainer
在.NET Core 3.0之后不适用于通用主机。然而,有一个问题。不幸的是,它依赖于已在.NET 5.0中删除的弃用的
IStartpConfigureContainerFilter

这意味着当前在.NET 5.0中,当使用通用主机时,无法在集成测试中模拟外部DI容器注入的依赖项


幸运的是,ASP.NET团队的David Fowler。

流中的原始
IEventStoreManager
注册在哪里
ConfigureServices
或直接使用
ConfigureContainer
中的容器?在
ConfigureContainer
中,使用autofac container就像
ConfigureTestServices
一样,有一个
ConfigureTestContainer
可用于直接操作容器。检查更新的答案。我在testserver项目中有一个接口的自定义实现。实际上,它在内部使用Moq,而不是使用与外部系统的真正连接。问题是,在测试时,我无法告诉我的应用程序要使用的具体实现是模拟的实现,而不是在Startup.cs的ConfigureContainer上注册的实现。换句话说,我无法从TestServerFor Asp.Net Core 3.0+或通用托管
服务覆盖autofac的容器。AddAutofac()
不起作用。来自Autofac代码文档:“仅适用于ASP.NET 3.0之前的托管。这不适用于ASP.NET CORE 3.0+或通用托管。”
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

// This is where things can be registered directly with autofac and runs after ConfigureServices, so it will override it
public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<EventStoreManager>().As<IEventStoreManager>();
}
//...
.ConfigureServices(services => services.AddAutofac())
.ConfigureTestContainer<ContainerBuilder>(builder => {
    builder.RegisterType<MockEventStoreManager>().As<IEventStoreManager>();
})
//...