Klaus Gütter
Klaus Gütter

Reputation: 12007

How to detect globalization-invariant mode

.NET Core/6/7 supports a globalization-invariant mode which alters the behavior regarding globalization in many ways.

How can a library detect if it is running in this mode and adjust its behaviour accordingly?

The only solution I came up so far is to use the fact, that since .NET 6 creating a culture which is not the invariant culture in this mode will (according to this document) throw a CultureNotFoundException.

bool IsGlobalizationInvariantModeEnabled()
{
  try
  {
    _ = new CultureInfo("en-US");
    return false;
  }
  catch (CultureNotFoundException)
  {
    return true;
  }
}

I do not like the solution because it abuses exceptions and also assumes that the "en-US" culture is always available if the globalization-invariant mode is not activated.

Is there a better way?

Upvotes: 5

Views: 1427

Answers (1)

Guru Stron
Guru Stron

Reputation: 143098

It seems there is no public API for this. You can try analyzing corresponding AppContext switch and environment variable:

var isInvariantGLob = GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");

static bool GetBooleanConfig(string switchName, string envVariable, bool defaultValue = false)
{
    if (!AppContext.TryGetSwitch(switchName, out bool ret))
    {
        string? switchValue = Environment.GetEnvironmentVariable(envVariable);
        ret = switchValue != null 
            ? (switchValue.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) || switchValue.Equals("1")) 
            : defaultValue;
    }
 
    return ret;
}

Basically the same is done internally - in GlobalizationMode.

UPD

Created an API proposal to expose GlobalizationMode publicly.

UPD2

As explained in the discussion to the API proposal, this method is not actually reliable for AOT/trimming scenarios:

The switch is not reliable way to detect invariant mode in the presence of trimming. Trimming can hardcode the app to "always invariant mode" or "never invariant mode". The switch is ignored in that case.

So the exception approach similar to yours was suggested (though based on the discussion it has it's own edge cases):

private static bool IsGlobalizationInvariantModeEnabled()
{
    try
    {
        return CultureInfo.GetCultureInfo("en-US").NumberFormat.CurrencySymbol == "¤";
    }
    catch (CultureNotFoundException)
    {
        return true;
    }
}

Upvotes: 5

Related Questions