【问题标题】:Turn `ReloadOnChange` off in config source for WebApplicationFactory在 WebApplicationFactory 的配置源中关闭 `ReloadOnChange`
【发布时间】:2022-04-27 23:51:39
【问题描述】:

这既是一个问题,也是一个答案。我已经解决了我的问题,但似乎有点不对。

我最初的问题是在 bitbucket 管道中运行我的 asp.net 核心集成测试导致System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached. 一些解决方案要求通过sysctl 更改某些设置,但那是restricted by bitbucket,所以这不是一个选项我。

these stackoverflow answers 所述,解决此问题的第二种方法是关闭reloadOnChange

我现在的新问题是,我们如何最好为测试WebApplicationFactory做到这一点?

一个对我有用的解决方案,它是最少的代码,似乎完全是 hack。我遍历所有JsonConfigurationSource 并将ReloadOnChange 设置为false

完整解决方案:

public class TestApplicationFactory : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureAppConfiguration(config =>
        {
            foreach (var source in config.Sources)
            {
                if (source is JsonConfigurationSource)
                {
                    var jsonConfigSource = (JsonConfigurationSource) source;
                    jsonConfigSource.ReloadOnChange = false;
                }
            }
        });
    }
}

另一个我没有尝试过的解决方案可能是override CreateWebHostBuilder()。但是,default one 似乎需要更多代码和大量复制和粘贴。

我错过了什么吗?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: c# asp.net-core bitbucket-pipelines


    【解决方案1】:

    刚刚在 Linux 容器中运行集成测试时遇到了这个问题,并按照之前的建议关闭了 WebApplicationFactory 中的 ReloadOnChange。不幸的是,这并没有解决问题,集成测试仍然失败并出现同样的错误:

    System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached.
    

    我还尝试将 xUnit 配置为按顺序而不是并行运行集成测试,但这也不起作用。

    对我有用的解决方案是在运行集成测试的容器中设置适当的环境变量:

    export ASPNETCORE_hostBuilder__reloadConfigOnChange=false
    

    【讨论】:

    【解决方案2】:

    builder.ConfigureAppConfiguration 用于配置您的(主)应用程序。

    您可以使用builder.ConfigureHostConfiguration(请参阅docs)显式配置要为主机读取的文件。

    builder.ConfigureHostConfiguration((hostingContext, config) =>
    {
        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false);
    });
    

    主机配置已加载。从 3.0 开始的 ASP.NET Core 是基于 Generic host(而不是之前版本的 Web Host)构建的。

    【讨论】:

    • 你是说这只适用于 ASP.NET Core 3.0?我使用的是 2.2,但在 2.2 的文档中没有看到 ConfigureHostConfiguration
    • 如上所述,通用主机用作 ASP.NET Core 3.0 的默认主机机制。在此之前,WebHost(WebHostBuilder 类)用于引导 ASP.NET Core 应用程序。 WebHostBuilder 也(仍然)适用于 .NET Core 3.0(即,如果您已迁移),但通过 tempate 创建的新应用程序使用 `Host.CreateDefaultBuilder(...)`/HostBuilder
    • 谢谢,如果我迁移到 3.0,答案会起作用吗?你知道在 2.2 中做类似事情的方法吗?我可以在我的问题中澄清我正在使用的堆栈
    【解决方案3】:

    您可以通过使用WithWebHostBuilderConfigureAppConfiguration 扩展方法来做到这一点,而无需从WebApplicationFactory 继承:

    var webAppFactory = new WebApplicationFactory<Startup>().WithWebHostBuilder(webHostBuilder =>
    {
        webHostBuilder.ConfigureAppConfiguration((hostingContext, configBuilder) =>
            configBuilder.Sources.Where(s => s is FileConfigurationSource).ToList()
                .ForEach(s => ((FileConfigurationSource)s).ReloadOnChange = false));
    });
    

    这完成了与您最初的想法相同的事情(这对我帮助很大!),但更紧凑,不需要单独的类定义。

    【讨论】:

    • 很高兴它对您有很大帮助。谢谢你的建议。我使用了一个类,因为我在多个地方重用了TestApplicationFactory,并且不想重复代码。
    【解决方案4】:

    我刚刚遇到了同样的问题。

    将环境变量DOTNET_hostBuilder:reloadConfigOnChange 设置为false 修复了它。

    当您使用通用主机时,此解决方案适用于 net6。对于其他主机,可以尝试将 DOTNET_ 前缀替换为 ASPNETCORE_

    为了简单起见,我在创建 WebApplicationFactory 之前将其设置在我的代码中

    Environment.SetEnvironmentVariable("DOTNET_hostBuilder:reloadConfigOnChange", "false");
    

    【讨论】:

    • 感谢您的回答...虽然可能是针对不同的 dotnet 版本,但 Ben 的回答似乎已经与此类似:stackoverflow.com/a/69433780/2088345。不过我从来没有尝试过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    相关资源
    最近更新 更多