Culture- and Language-Handling
Quino uses the standard .NET
CultureInfo.CurrentUICulture for the default language and
CultureInfo.CurrentCulture for default formatting (e.g. times, dates, and currencies). Many fields have been marked as obsolete and are no longer used by Quino.
The default languages in Quino have changed from "en-US" and "de-CH" to "en and "de", respectively.
The reasoning behind this is that, while a requested language should be as specific as possible, a supported language should be as general as possible. The standard culture mechanisms and behavior (e.g. .NET Resources) "fall back" to a parent language when a more-specific language cannot be found. If an application claims to only support "en-US", then a request for "en-GB" fails. If the supported language is "en", then any request to a language in the "en" family (e.g. "en-US", "en-GB", "en-AU") will use "en".
An application that supports "en-US" and "de-CH" has, therefore, a more limited palette of languages that it can support.
Quino code runs in the context of a user, who has a list of preferred languages, in decreasing order of preference. This context can last the entire duration of an application (e.g. a standalone application like a console or desktop application) or last as long as a web request.
The application itself has a list of languages that it supports, as well as resources and metadata that defines text in these languages. The resources are standard .NET Resources with the standard fallback mechanism (i.e. a request for "en-US" can be satisfied by "en"). The metadata uses
DynamicString objects, which encapsulate a map from language codes (e.g. "en" or "de") to strings.
During application startup or at the beginning of a web request, the
ILanguageResolver determines the language to use for a given set of requested languages. In ASP.NET Core, the requested languages come from the HTTP headers provided by the browser. In standalone applications, the
IRequestedLanguageCalculator provides the requested languages. The
ILanguageInitializer is responsible for coordinating this during application startup.
The rest of Quino uses the following singletons to work with languages.
IDynamicStringFallbackCalculator: Comes into play when a request is made for a language that is not directly supported. For example, if the application supports "en" and "de", then a request for "en-US" will ask this singleton how to resolve the request.
IDynamicStringFactory: Creates a dynamic string to describe a given object. The default implementation uses .NET Attributes.
ILanguageResolver: Determines the culture to use from a list of available cultures and a list of requested/preferred cultures.
IRequestedLanguageCalculator: Provides the sequence of languages from which to choose during initial resolution (web requests do not use this).
ILanguageInitializer: Integrates language-selection into the application startup.
ICaptionCalculator: Extracts a single caption for a culture from a given object. Appications should use the
IDynamicStringFactoryin most cases, instead.
An application can control fallback by registering custom
ILanguageResolver implementations (though this is almost certainly not necessary).