C# 为IHostingEnvironment使用自定义名称

C# 为IHostingEnvironment使用自定义名称,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,我们正在运行ASP.NET内核,并急切地使用IHostingEnvironment 由于我们组织中的约定,我们的环境名称与默认IHostingEnvironment实现的名称不匹配 为了解决这个问题,我们采用了以下扩展方法: public static class HostingEnvironmentExtensions { public static bool IsProd(this IHostingEnvironment env) => env.IsEnvironmen

我们正在运行ASP.NET内核,并急切地使用IHostingEnvironment

由于我们组织中的约定,我们的环境名称与默认IHostingEnvironment实现的名称不匹配

为了解决这个问题,我们采用了以下扩展方法:

public static class HostingEnvironmentExtensions
{
        public static bool IsProd(this IHostingEnvironment env) => env.IsEnvironment("prod");            

        public static bool IsTest(this IHostingEnvironment env) => env.IsEnvironment("test");                 
}
这很好,但感觉有点危险,因为
IsProduction
istaging
的默认方法现在无法按预期的方式工作


处理环境名称不同于ASP.NET核心默认值的正确方法是什么?

您可以通过创建自己的实现来解决这个问题。我创建了自己的
IWorkingEnvironment
界面,如下所示:

public interface IWorkingEnvironment
{
    string EnvironmentName { get; set; }
}
以及我自己的“已知”环境名称:

public static class EnvironmentNames
{
    public static readonly string Local = nameof(Local);

    public static readonly string Dev = nameof(Dev);

    public static readonly string Test = nameof(Test);

    public static readonly string Prod = nameof(Prod);
}
然后是
IWorkingEnvironment
上的扩展方法:

public static class WorkingEnvironmentExtensions
{
    public static bool IsLocal(this IWorkingEnvironment environment)
    {    
        return environment.EnvironmentName == EnvironmentNames.Local;
    }

    public static bool IsDev(this IWorkingEnvironment environment)
    {    
        return environment.EnvironmentName == EnvironmentNames.Dev;
    }

    // etc...
}
public class AspNetWorkingEnvironment : IWorkingEnvironment
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public AspNetWorkingEnvironment(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public string EnvironmentName => _hostingEnvironment.EnvironmentName;
}
然后,我使用ASP.NET
IHostingEnvironment
实现了
IWorkingEnvironment

public static class WorkingEnvironmentExtensions
{
    public static bool IsLocal(this IWorkingEnvironment environment)
    {    
        return environment.EnvironmentName == EnvironmentNames.Local;
    }

    public static bool IsDev(this IWorkingEnvironment environment)
    {    
        return environment.EnvironmentName == EnvironmentNames.Dev;
    }

    // etc...
}
public class AspNetWorkingEnvironment : IWorkingEnvironment
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public AspNetWorkingEnvironment(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public string EnvironmentName => _hostingEnvironment.EnvironmentName;
}
现在,我们需要做的就是在依赖项注入容器中将
AspNetWorkingEnvironment
注册为
IWorkingEnvironment
(使用单例生存期)的实现:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IWorkingEnvironment, AspNetWorkingEnvironment>();

    // etc...
}
public void配置服务(IServiceCollection服务)
{
services.AddSingleton();
//等等。。。
}

最干净的方法是扩展实现IHostingEnvironment的您自己的类型,并将其注入控制器和服务中

但是,如果您坚持依赖内置方法,您可以(有点危险地)覆盖
环境名称
类型中的
字符串
值以匹配您的自定义值:

public Startup(IHostingEnvironment env)
{
    var envNameType = typeof(EnvironmentName);

    envNameType.GetField(EnvironmentName.Development).SetValue(null, "dev");
    envNameType.GetField(EnvironmentName.Production).SetValue(null, "prod");
    envNameType.GetField(EnvironmentName.Staging).SetValue(null, "stag");

    // given that current environment name == "prod", both would evaluates to 'true'
    var isInProd = env.IsEnvironment("prod");
    var isProd = env.IsProduction();

    // ...
}
在内部,内置的
IsEnvironment()
方法依赖于该
EnvironmentName
中的值来确定环境名称


请参见

谢谢您的回复。就像你自己说的,这是一种疯狂的科学家方法,基本上没有“正确的方法”谢谢。我真的希望能够使用IHostingEnvironment,因为这意味着新开发人员不需要了解要使用哪个接口,但我认为这是目前(缺乏)HostingEnvironment可配置性的最佳方法