Search code examples
c#.net-corelocalizationconsole-application

Setting static culture for .NET 6 console application


I'm trying to statically set the culture of a .NET 6 console application with dependency injection.

I've tried setting the ThreadCurrentCulture but later in my injected service I get the current culture and it's back to the original.

var cultureInfo = new CultureInfo("en-GB");
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
CultureInfo.CurrentCulture = cultureInfo;`

I've also tried AddLocalization and setting the DefaultCulture from the RequestLocalizationMiddleware

services.AddLocalization();
services.Configure<RequestLocalizationOptions>(options =>
{
    options.SetDefaultCulture("en-GB");
    options.AddSupportedUICultures("en-GB");
    options.FallBackToParentUICultures = true;
});

My startup.cs file

try
{
    var host = CreateHostBuilder(args).UseSerilog().Build();

     await host.Services.GetService<TestGenerator>().ExecuteAsync(args);
}
catch (Exception ex)
{
    Log.Fatal(ex, "An unhandled exception occurred during startup");
    Log.CloseAndFlush();
    Environment.Exit(-1);
}
finally
{
    Log.CloseAndFlush();
}

static IHostBuilder CreateHostBuilder(string[] args)
{
    var hostBuilder = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, builder) =>
        {
            builder.SetBasePath(Directory.GetCurrentDirectory());
        })
        .ConfigureServices((context, services) =>
        {
            ConfigureServices(services);
        });

    return hostBuilder;
}

static IServiceCollection ConfigureServices(IServiceCollection services)
{
    var cultureInfo = new CultureInfo("en-GB");
    CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
    CultureInfo.CurrentCulture = cultureInfo;

    var config = LoadConfiguration();

    // Initialize Serilog Logger

    Serilog.Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(config)
        .CreateLogger();

    // Add access to generic IConfigurationRoot

    services.AddSingleton(config);

    services.AddLocalization();
    services.Configure<RequestLocalizationOptions>(options =>
    {
        options.SetDefaultCulture("en-GB");
        options.AddSupportedUICultures("en-GB");
        options.FallBackToParentUICultures = true;
    });

    // Add services

    services.AddHttpClient();
    services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
    
    // Register Generators

    services.AddTransient<TestGenerator>();

    return services;
}

static IConfiguration LoadConfiguration()
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

    return builder.Build();
}

Solution

  • The culture was being set correctly by the following code:

    var cultureInfo = new CultureInfo("en-GB");
    CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
    CultureInfo.CurrentCulture = cultureInfo;
    

    But the CultureInfo was being overwritten by user settings, using the second parameter of CultureInfo solved this.

    var cultureInfo = new CultureInfo("en-GB", false);
    

    See: CultureInfo changes based on computer settings