简体   繁体   English

在自托管的.net core 2.2应用程序上正确使用IsDevelopement()

[英]Proper use of IsDevelopement() on self hosted .net core 2.2 application

I have a self-hosted .NET core 2.2 console app that does not use the web host builder as I do not need HTTP endpoints for this service. 我有一个自托管的.NET Core 2.2控制台应用程序,该应用程序不使用Web主机构建器,因为我不需要此服务的HTTP端点。

I'm trying to leverage the environment variable through the IsDevelopment() method of the hosting environment but it always comes back as Production . 我正在尝试通过托管环境的IsDevelopment()方法来利用环境变量,但是它总是以Production形式返回。

The following is how I've setup my host builder. 以下是我设置主机构建器的方式。 I have an environment variable called ASPNETCORE_ENVIRONMENT with a value of Development which leads me to ask two questions. 我有一个名为ASPNETCORE_ENVIRONMENT的环境变量,其值为Development ,这使我提出两个问题。

  1. What is the proper way to have this set when building my own host so that I can conditionally add user secrets to my configuration when building the host? 在构建自己的主机时进行设置的正确方法是什么,以便在构建主机时可以有条件地向配置中添加用户密码?
  2. Second question is if I can use a different environment variable other than ASPNETCORE_ENVIRONMENT since my app is not an ASP.NET core application? 第二个问题是,因为我的应用程序不是ASP.NET核心应用程序,是否可以使用ASPNETCORE_ENVIRONMENT以外的其他环境变量?

I realize I could probably write code just before building the HostBuilder that explicitly looks for an environment variable and set the environment manually, but ASP.NET Core seems to hook this up behind the scenes so I wanted to see if there was a way to get a similar behavior when I'm not using the web host builder. 我意识到我可能可以在构建HostBuilder之前编写代码,该HostBuilder明确寻找环境变量并手动设置环境,但是ASP.NET Core似乎将其隐藏在幕后,所以我想看看是否有一种获取方法当我不使用Web Host Builder时,会发生类似的行为。

private static IHost BuildEngineHost(string[] args)
{
    var engineBuilder = new HostBuilder()
        .ConfigureAppConfiguration((hostContext, config) =>
        {
            config.SetBasePath(Directory.GetCurrentDirectory());
            config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            config.AddEnvironmentVariables();
            if(hostContext.HostingEnvironment.IsDevelopment())
                config.AddUserSecrets<EngineOptions>();
        })
        .ConfigureServices((hostContext, services) =>
        {
            services.Configure<EngineOptions>(hostContext.Configuration.GetSection("EngineOptions"));
            services.AddHostedService<EtlEngineService>();
        })
        .ConfigureLogging((hostContext, logging) =>
        {
            logging.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
        });
    return engineBuilder.Build();
}

UPDATE: The following is needed to configure the host before configuration the application 更新:在配置应用程序之前,需要以下配置主机

.ConfigureHostConfiguration(config =>
{
    config.AddCommandLine(args);
    config.AddEnvironmentVariables();
})

This is called before .ConfigureAppConfiguration() and is loaded from any variable called "Environment" which means I don't have to use ASPNET_ENVIRONMENT. 这是在.ConfigureAppConfiguration()之前调用的,并且是从任何称为“环境”的变量加载的,这意味着我不必使用ASPNET_ENVIRONMENT。

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2 https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2

What is the proper way to have this set when building my own host so that I can conditionally add user secrets to my configuration when building the host? 在构建自己的主机时进行设置的正确方法是什么,以便在构建主机时可以有条件地向配置中添加用户密码?

The proper way is to not have all the lines of code you currently have in your BuildEngineHost method. 正确的方法是不要在BuildEngineHost方法中拥有当前拥有的所有代码行。 If you're using ASP.Net Core 2.2, those settings you've wrote are already set for you. 如果您使用的是ASP.Net Core 2.2,则已经为您设置了编写的那些设置。 In your Program.cs file you should just have this: 在您的Program.cs文件中,您应该仅具有以下内容:

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

When you look at CreateDefaultBuilder method implementation on GitHub you will see what you're trying to do is already done by default. 当您查看GitHub上的 CreateDefaultBuilder方法实现时,默认情况下您将尝试执行的操作已经完成。 This is the implementation of CreateDefaultBuilder : 这是CreateDefaultBuilder的实现:

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
    var builder = new WebHostBuilder();

    if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
    {
        builder.UseContentRoot(Directory.GetCurrentDirectory());
    }
    if (args != null)
    {
        builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
    }

    builder.ConfigureAppConfiguration((hostingContext, config) =>
    {
        var env = hostingContext.HostingEnvironment;

        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

        if (env.IsDevelopment())
        {
            var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
            if (appAssembly != null)
            {
                config.AddUserSecrets(appAssembly, optional: true);
            }
        }

        config.AddEnvironmentVariables();

        if (args != null)
        {
            config.AddCommandLine(args);
        }
    })
    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddEventSourceLogger();
    }).
    UseDefaultServiceProvider((context, options) =>
    {
        options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
    });

    ConfigureWebDefaults(builder);

    return builder;
}

Anyway if you don't want to use this implementation so to answer to your 2nd question you need to use add this line: 无论如何,如果您不想使用此实现,因此要回答第二个问题,则需要使用以下行:

config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

Just after this line: 在此行之后:

config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

env variable is a type IHostingEnvironment that need to be injected in your BuildEngineHost method. env变量是一种IHostingEnvironment类型,需要注入到BuildEngineHost方法中。

I was able to have the hosting environment initialized with the correct values by calling ConfigureHostConfiguration() before AppConfiguration which properly sets the environment values in the host which I came across in the following doc from Microsoft. 我可以通过在AppConfiguration之前调用ConfigureHostConfiguration()初始化具有正确值的托管环境,从而在我从以下Microsoft文档中找到的主机中正确设置环境值。

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2 https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2

private static IHost BuildEngineHost(string[] args)
{
    var engineBuilder = new HostBuilder()
        .ConfigureHostConfiguration(config =>
        {
            config.AddEnvironmentVariables();
            config.AddCommandLine(args);
        })
        .ConfigureAppConfiguration((hostContext, config) =>
        {
            config.SetBasePath(Directory.GetCurrentDirectory());
            config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            config.AddEnvironmentVariables();
            if(hostContext.HostingEnvironment.IsDevelopment())
                config.AddUserSecrets<EngineOptions>();
        })
        .ConfigureServices((hostContext, services) =>
        {
            services.Configure<EngineOptions>(hostContext.Configuration.GetSection("EngineOptions"));
            services.AddHostedService<EtlEngineService>();
        })
        .ConfigureLogging((hostContext, logging) =>
        {
            logging.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
        });
    return engineBuilder.Build();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 自托管 Net Core 3 应用程序不采取端口设置 - Self-hosted Net Core 3 application does not take port settings 自托管 .NET 核心控制台应用程序中的 Startup.cs - Startup.cs in a self-hosted .NET Core Console Application 自托管 ASp.net 核心 2.2 应用程序,未找到视图“索引”。 搜索了以下位置 - Self hosted ASp.net core 2.2 app, The view 'Index' was not found. The following locations were searched 如何在 ASP.NET Core 2.2 中使用来自不同托管项目的共享 SignalR Hub - How to use shared SignalR Hub from different hosted project in ASP.NET Core 2.2 如何在自托管的.net核心mvc应用程序中运行长时间运行或重复运行的任务? - How should I run long-running or recurring taks in a self-hosted .net core mvc application? 如何将外部域绑定到 .NET Core 3.1 Kestrel 自托管应用程序? - How to bind external domain to .NET Core 3.1 Kestrel self-hosted application? 如何使用正确的连接字符串 .net 核心控制台应用程序 - How to use proper connection string .net core console application 在 .NET Core 2.2 MVC 应用程序中创建路由 - Creating a routing in .NET Core 2.2 MVC application 如何使用托管在 .Net framework 4.6 应用程序中的登录页面对 .Net Core 3.1 上的 IdentityServer4 应用程序进行身份验证? - How to use login page hosted in .Net framework 4.6 application to authenticate for IdentityServer4 application on .Net Core 3.1? Net Core 2.2 MVC WebApi中的JWT“自我”身份验证 - JWT “self” authentication in Net Core 2.2 MVC WebApi
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM