tutorial net mvc introducción español asp c# asp.net-core asp.net-core-mvc

c# - introducción - asp.net core vs asp.net mvc



Cómo obtener el entorno de alojamiento de desarrollo/preparación/producción en ConfigureServices (9)

¿Cómo obtengo el entorno de alojamiento de desarrollo / preparación / producción en el método ConfigureServices en el inicio?

public void ConfigureServices(IServiceCollection services) { // Which environment are we running under? }

El método ConfigureServices solo toma un único parámetro IServiceCollection .


TL; DR

Establezca una variable de entorno llamada ASPNETCORE_ENVIRONMENT con el nombre del entorno (por ejemplo, Production ). Luego haz una de dos cosas:

  • Inyecte IHostingEnvironment en Startup.cs , luego use eso ( env aquí) para verificar: env.IsEnvironment("Production") . ¡No verifique usando env.EnvironmentName == "Production" !
  • Utilice clases de Startup separadas o funciones individuales Configure / ConfigureServices . Si una clase o las funciones coinciden con estos formatos, se utilizarán en lugar de las opciones estándar en ese entorno.
    • Startup{EnvironmentName}() (clase completa) || ejemplo: StartupProduction()
    • Configure{EnvironmentName}() || ejemplo: ConfigureProduction()
    • Configure{EnvironmentName}Services() || ejemplo: ConfigureProductionServices()

Explicación completa

Los documentos de .NET Core describen cómo lograr esto . Utilice una variable de entorno llamada ASPNETCORE_ENVIRONMENT que esté configurada en el entorno que desee, entonces tiene dos opciones.

Comprobar nombre del entorno

De los documentos :

El servicio IHostingEnvironment proporciona la abstracción central para trabajar con entornos. Este servicio es proporcionado por la capa de alojamiento ASP.NET y puede inyectarse en su lógica de inicio a través de Inyección de dependencias. La plantilla del sitio web ASP.NET Core en Visual Studio utiliza este enfoque para cargar archivos de configuración específicos del entorno (si están presentes) y para personalizar la configuración de manejo de errores de la aplicación. En ambos casos, este comportamiento se logra haciendo referencia al entorno especificado actualmente llamando a EnvironmentName o IsEnvironment en la instancia de IHostingEnvironment pasa al método apropiado.

NOTA: env.EnvironmentName No se recomienda verificar el valor real de env.EnvironmentName !

Si necesita verificar si la aplicación se está ejecutando en un entorno en particular, use env.IsEnvironment("environmentname") ya que ignorará correctamente las mayúsculas y minúsculas (en lugar de verificar si env.EnvironmentName == "Development" por ejemplo).

Usa clases separadas

De los documentos :

Cuando se inicia una aplicación ASP.NET Core, la clase Startup se usa para iniciar la aplicación, cargar su configuración, etc. ( obtenga más información sobre el inicio de ASP.NET ). Sin embargo, si existe una clase llamada Startup{EnvironmentName} (por ejemplo StartupDevelopment ), y la variable de entorno ASPNETCORE_ENVIRONMENT coincide con ese nombre, entonces esa clase de Startup se usa en su lugar. Por lo tanto, puede configurar Startup para el desarrollo, pero tener una StartupProduction separada que se usaría cuando la aplicación se ejecute en producción. O viceversa.

Además de utilizar una clase de Startup completamente separada basada en el entorno actual, también puede realizar ajustes en la configuración de la aplicación dentro de una clase de Startup . Los métodos Configure() y ConfigureServices() admiten versiones específicas del entorno similares a la clase Startup sí, de la forma Configure{EnvironmentName}() y Configure{EnvironmentName}Services() . Si define un método ConfigureDevelopment() , se llamará en lugar de Configure() cuando el entorno esté configurado para el desarrollo. Del mismo modo, se llamaría ConfigureServices() en lugar de ConfigureServices() en el mismo entorno.


El entorno de alojamiento proviene de la variable de entorno ASPNET_ENV, que está disponible durante el inicio utilizando el método de extensión IHostingEnvironment.IsEnvironment, o uno de los métodos de conveniencia correspondientes de IsDevelopment o IsProduction. Guarde lo que necesita en Startup () o en la llamada ConfigureServices:

var foo = Environment.GetEnvironmentVariable("ASPNET_ENV");


En Dotnet Core 2.0, el constructor de inicio solo espera un parámetro IConfiguration.

public Startup(IConfiguration configuration) { Configuration = configuration; }

¿Cómo leer el entorno de alojamiento allí? Lo guardo en Program-class durante ConfigureAppConfiguration (uso BuildWebHost completo en lugar de WebHost.CreateDefaultBuilder):

public class Program { public static IHostingEnvironment HostingEnvironment { get; set; } public static void Main(string[] args) { // Build web host var host = BuildWebHost(args); host.Run(); } public static IWebHost BuildWebHost(string[] args) { return new WebHostBuilder() .UseConfiguration(new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("hosting.json", optional: true) .Build() ) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; // Assigning the environment for use in ConfigureServices HostingEnvironment = env; // <--- 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, builder) => { builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); builder.AddConsole(); builder.AddDebug(); }) .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }) .UseStartup<Startup>() .Build(); }

Ant luego lo lee en ConfigureServices así:

public IServiceProvider ConfigureServices(IServiceCollection services) { var isDevelopment = Program.HostingEnvironment.IsDevelopment(); }


En la aplicación .NET Core 2.0 MVC / Microsoft.AspNetCore.All v2.0.0, puede tener una clase de inicio específica para el medio ambiente como se describe en @vaindil, pero no me gusta ese enfoque.

También puede inyectar IHostingEnvironment en el constructor StartUp . No necesita almacenar la variable de entorno en la clase Program .

public class Startup { private readonly IHostingEnvironment _currentEnvironment; public IConfiguration Configuration { get; private set; } public Startup(IConfiguration configuration, IHostingEnvironment env) { _currentEnvironment = env; Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { ...... services.AddMvc(config => { // Requiring authenticated users on the site globally var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); config.Filters.Add(new AuthorizeFilter(policy)); // Validate anti-forgery token globally config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); // If it''s Production, enable HTTPS if (_currentEnvironment.IsProduction()) // <------ { config.Filters.Add(new RequireHttpsAttribute()); } }); ...... } }


Esto se puede lograr sin propiedades adicionales o parámetros de método, como sigue:

public void ConfigureServices(IServiceCollection services) { IServiceProvider serviceProvider = services.BuildServiceProvider(); IHostingEnvironment env = serviceProvider.GetService<IHostingEnvironment>(); if (env.IsProduction()) DoSomethingDifferentHere(); }


Quería obtener el medio ambiente en uno de mis servicios. ¡Es realmente facil de hacer! Simplemente lo inyecto al constructor así:

private readonly IHostingEnvironment _hostingEnvironment; public MyEmailService(IHostingEnvironment hostingEnvironment) { _hostingEnvironment = hostingEnvironment; }

Ahora más adelante en el código puedo hacer esto:

if (_hostingEnvironment.IsProduction()) { // really send the email. } else { // send the email to the test queue. }


Si necesita probar esto en algún lugar de su base de código que no tenga fácil acceso al entorno IHosting, otra forma fácil de hacerlo es así:

bool isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";


por los docs.microsoft.com/en-us/aspnet/core/fundamentals/environments

Configure y ConfigureServices admiten versiones específicas del entorno del formulario Configure {EnvironmentName} y Configure {EnvironmentName} Servicios:

Puedes hacer algo como esto ...

public void ConfigureProductionServices(IServiceCollection services) { ConfigureCommonServices(services); //Services only for production services.Configure(); } public void ConfigureDevelopmentServices(IServiceCollection services) { ConfigureCommonServices(services); //Services only for development services.Configure(); } public void ConfigureStagingServices(IServiceCollection services) { ConfigureCommonServices(services); //Services only for staging services.Configure(); } private void ConfigureCommonServices(IServiceCollection services) { //Services common to each environment }


puede acceder fácilmente a él en ConfigureServices, simplemente consérvelo en una propiedad durante el método de Inicio que se llama primero y lo pasa, luego puede acceder a la propiedad desde ConfigureServices

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) { ...your code here... CurrentEnvironment = env; } private IHostingEnvironment CurrentEnvironment{ get; set; } public void ConfigureServices(IServiceCollection services) { string envName = CurrentEnvironment.EnvironmentName; ... your code here... }