Introduction
ILocalization is the facade where localization is managed.
/// <summary>Localization settings and query providers</summary>
public interface ILocalization
{
/// <summary>Fallback cultures provider</summary>
IProvider<string, string[]> FallbackCultureProvider { get; set; }
/// <summary>File configuration and providers</summary>
ILocalizationFiles Files { get; set; }
/// <summary>Files query. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizationFile>> FileQuery { get; set; }
/// <summary>Files query. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizationFile>> FileQueryCached { get; set; }
/// <summary>Line configuration and providers</summary>
ILocalizationLines Lines { get; set; }
/// <summary>Lines query. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<IEnumerable<KeyValuePair<string, MarkedText>>>> LineQuery { get; set; }
/// <summary>Lines query. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<IEnumerable<KeyValuePair<string, MarkedText>>>> LineQueryCached { get; set; }
/// <summary>Template formats</summary>
ITemplateFormats TemplateFormats { get; set; }
/// <summary>Queries and caches rules</summary>
IProvider<PluralRuleInfo, IPluralRule[]> PluralRuleProvider { get; set; }
/// <summary>Localization file parse error handlers</summary>
IList<ILocalizationErrorHandler> ErrorHandlers { get; set; }
/// <summary>Localization linfo info provider, non-cached. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string culture, string key), ILocalizationLinesInfo> LocalizationLinesInfo { get; set; }
/// <summary>Localization linfo info provider, cached. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string culture, string key), ILocalizationLinesInfo> LocalizationLinesInfoCached { get; set; }
/// <summary>Localization linfo infos query, non-cached. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizationLinesInfo>> LocalizationLinesInfosQuery { get; set; }
/// <summary>Localization linfo infos query, cached. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizationLinesInfo>> LocalizationLinesInfosQueryCached { get; set; }
/// <summary>Localized text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string culture, string key), ILocalizedText> LocalizedText { get; set; }
/// <summary>Localized text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string culture, string key), ILocalizedText> LocalizedTextCached { get; set; }
/// <summary>Localized text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<((string culture, IFormatProvider format), string key), ILocalizedText> FormatLocalizedText { get; set; }
/// <summary>Localized text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<((string culture, IFormatProvider format), string key), ILocalizedText> FormatLocalizedTextCached { get; set; }
/// <summary>Localized texts query. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizedText>> LocalizedTextsQuery { get; set; }
/// <summary>Localized texts query, cached. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(string? culture, string? key), IEnumerable<ILocalizedText>> LocalizedTextsQueryCached { get; set; }
/// <summary>Localizable text provider. Input argument is 'Key'. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string, ILocalizableText> LocalizableText { get; set; }
/// <summary>Localizable text provider. Input argument is 'Key'. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string, ILocalizableText> LocalizableTextCached { get; set; }
/// <summary>Localizable texts query. Input argument is 'Key', and 'null' for all texts. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string?, IEnumerable<ILocalizableText>> LocalizableTextsQuery { get; set; }
/// <summary>Localizable texts query. Input argument is 'Key', and 'null' for all texts. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string?, IEnumerable<ILocalizableText>> LocalizableTextsQueryCached { get; set; }
/// <summary>Localizable text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(ICultureProvider cultureProvider, string key), ILocalizingText> LocalizingText { get; set; }
/// <summary>Localizable text provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(ICultureProvider cultureProvider, string key), ILocalizingText> LocalizingTextCached { get; set; }
/// <summary>Localizable file provider. Input argument is 'Key'. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string, ILocalizable<ILocalizationFile>> LocalizableFile { get; set; }
/// <summary>Localizable file provider. Input argument is 'Key'. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string, ILocalizable<ILocalizationFile>> LocalizableFileCached { get; set; }
/// <summary>Localizable files query. Input argument is 'Key', and 'null' for all files. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string?, IEnumerable<ILocalizable<ILocalizationFile>>> LocalizableFilesQuery { get; set; }
/// <summary>Localizable files query. Input argument is 'Key', and 'null' for all files. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<string?, IEnumerable<ILocalizable<ILocalizationFile>>> LocalizableFilesQueryCached { get; set; }
/// <summary>Localizable file provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(ICultureProvider cultureProvider, string key), ILocalizing<ILocalizationFile>> LocalizingFile { get; set; }
/// <summary>Localizable file provider. Uses fallback cultures from <see cref="FallbackCultureProvider"/>.</summary>
IProvider<(ICultureProvider cultureProvider, string key), ILocalizing<ILocalizationFile>> LocalizingFileCached { get; set; }
}
Localization.Default contains default configured localization singleton.
// Get default localization
ILocalization localization = Localization.Default;
Localization.CreateDefault() creates new localization context with default settings
// Create localization
ILocalization localization = Localization.CreateDefault();
new Localization() constructs new localization context.
// Create localization
Localization localization = new Localization()
.AddFileSystem(LocalizationFileSystem.ApplicationRoot)
.AddFileFormats(LocalizationFileFormatYaml.Instance, LocalizationFileFormatXml.Instance, LocalizationFileFormatJson.Instance)
.AddFilePatterns(LocalizationFilePatterns.ResourcesFolder) // "Resources/{Key}", "Resources/{Culture}/{Key}"
.AddFileSystemWithPattern(LocalizationFileSystemEmbedded.AppDomain, LocalizationFilePatterns.ResourcesEmbedded) // "*/*.Resources.{Key}", "*/*.Resources.{Culture}.{Key}", "*/{Key}", "*/{Key}.{Culture}"
.AddResourceManagerProvider();
.AddLine(culture, key, templateFormat, text, pluralRules?, plurals?) adds a line explicitly.
ILocalization localization = new Localization()
.AddLine("", "Namespace.Apples", "BraceNumeric", "You've got {0} apple(s).")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got an apple.", "Unicode.CLDR40", "0:cardinal:one:en")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got {0} apples.", "Unicode.CLDR40", "0:cardinal:other:en")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on omena.", "Unicode.CLDR40", "0:cardinal:one:fi")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on {0} omenaa.", "Unicode.CLDR40", "0:cardinal:other:fi");
ITemplateFormatPrintable printable = localization.LocalizableText["Namespace.Apples"];
WriteLine(printable.Print(CultureInfo.GetCultureInfo("en"), new object[] { 2 })); // You've got 2 apples.
WriteLine(printable.Print(CultureInfo.GetCultureInfo("fi"), new object[] { 2 })); // Sinulla on 2 omenaa.
Localization.Default is configured to search for localization resources in following paths.
ApplicationRoot └── Resources/ ├── <Key> └── <Culture>/ └── <Key>
.AddFilePatterns(patterns) adds more file patterns where localization resources are searched from. Pattern with "{Culture}" is applied to all but invariant culture "", and pattern without "{Culture}" is applied to invariant culture "".
ILocalization localization =
Localization.CreateDefault()
.AddFilePatterns("Localization/{Key}", "Localization/{Culture}/{Key}");
Wilcards '?', '*' and '**' can be used in file pattern.
ILocalization localization =
Localization.CreateDefault()
.AddFilePatterns("Localization/**/{Key}", "Localization/**/{Culture}/{Key}");
Localization file can be dropped into "Resources/", for example "Resources/Namespace.l.yaml".
TemplateFormat: BraceNumeric
PluralRules: Unicode.CLDR41
English:
- Culture: en
Items:
- Key: Namespace.Apples
Cases:
- Text: "You've got an apple."
Plurals: "0:cardinal:one"
- Text: "You've got {0} apples."
Plurals: "0:cardinal:other"
Finnish:
- Culture: fi
Items:
- Key: Namespace.Apples
Cases:
- Text: "Sinulla on yksi omena."
Plurals: "0:cardinal:one"
- Text: "Sinulla on {0} omenaa."
Plurals: "0:cardinal:other"
Copy to Output Directory property should be assigned to Copy always, or Build Action to Embedded resource.
LocalizableTextCached is provider that returns localizable text that can localize to different cultures.
// Get localizable text
ILocalizedText text = localization.LocalizableTextCached["Namespace.Apples"];
// Create arguments
object[] arguments = { 2 };
// Print
WriteLine(text.Print(CultureInfo.GetCultureInfo("fi"), arguments)); // "Sinulla on 2 omenaa."
LocalizingTextCached is provider that returns localizing text that localizes automatically to assigned culture.
// Create localization (Reads "Resources/Namespace.l.yml")
ILocalization localization = new Localization()
.SetFallbackCultureProvider(FallbackCultureProvider.Invariant)
.AddFileSystem(LocalizationFileSystem.ApplicationRoot)
.AddFilePatterns("Resources/{Key}", "Resources/{Culture}/{Key}")
.AddFileFormats(LocalizationFileFormatYaml.Instance, LocalizationFileFormatXml.Instance, LocalizationFileFormatJson.Instance);
// Get text that uses current culture
ILocalizedText text = localization.LocalizingTextCached[(CultureProvider.CurrentCulture.Instance, "Namespace.Apples")];
// Assign current culture
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fi");
// Create arguments
object[] arguments = { 2 };
// Print with current culture
WriteLine(text.Print(arguments)); // "Sinulla on 2 omenaa."
LocalizedTextCached is provider that returns a text that is localized to a specific culture.
// Create localization (Reads "Resources/Namespace.l.yml")
ILocalization localization = new Localization()
.SetFallbackCultureProvider(FallbackCultureProvider.Invariant)
.AddFileSystem(LocalizationFileSystem.ApplicationRoot)
.AddFilePatterns("Resources/{Key}", "Resources/{Culture}/{Key}")
.AddFileFormats(LocalizationFileFormatYaml.Instance, LocalizationFileFormatXml.Instance, LocalizationFileFormatJson.Instance);
// Get text that uses specific culture
ILocalizedText text = localization.LocalizedTextCached[("fi", "Namespace.Apples")];
// Assign current culture to english (ignored)
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en");
// Create arguments
object[] arguments = { 2 };
// Print with the assigned culture "fi"
WriteLine(text.Print(arguments)); // "Sinulla on 2 omenaa."
.Localize(text, key) decorates 'text' to localize to the language issued in the 'formatProvider' parameter. The 'text' is used as fallback if localization is not found for the 'key'.
// Create text
ITemplateText text = new TemplateText("You've got {0} apple(s).", TemplateFormat.BraceNumeric);
// Decorate text to localize to language in 'formatProvider'
text = Localization.Default.Localize(text, "Namespace.Apples");
// Print
object[] arguments = { 2 };
WriteLine(text.Print(null, arguments)); // "You've got {0} apples."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("en"), arguments)); // "You've got 2 apples."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("fi"), arguments)); // "Sinulla on 2 omenaa."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("sv"), arguments)); // "Du har 2 äpplen."
.Localize(text, key, cultureProvider) decorates 'text' to localize to the active language provided by the assigned 'cultureProvider'.
// Create text
ITemplateText text = new TemplateText("You've got {0} apple(s).", TemplateFormat.BraceNumeric);
// Get active culture provider (CurrentThread)
ICultureProvider cultureProvider = CultureProvider.Default;
// Decorate text to localize to the active culture
text = Localization.Default.Localize(text, "Namespace.Apples", cultureProvider);
// Print
object[] arguments = { 2 };
cultureProvider.Culture = "en";
WriteLine(text.Print(formatProvider: null, arguments)); // "You've got 2 apple(s)."
cultureProvider.Culture = "sv";
WriteLine(text.Print(formatProvider: null, arguments)); // "Du har 2 äpplen."
cultureProvider.Culture = "fi";
WriteLine(text.Print(formatProvider: null, arguments)); // "Sinulla on 2 omenaa."
Full Example
Full example
using System.Globalization;
using Avalanche.Localization;
using Avalanche.Template;
using static System.Console;
class localization_index
{
public static void Run()
{
{
// <01>
// Get default localization
ILocalization localization = Localization.Default;
// </01>
}
{
// <02>
// Create localization
ILocalization localization = Localization.CreateDefault();
// </02>
}
{
// <03>
ILocalization localization = new Localization()
.AddLine("", "Namespace.Apples", "BraceNumeric", "You've got {0} apple(s).")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got an apple.", "Unicode.CLDR40", "0:cardinal:one:en")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got {0} apples.", "Unicode.CLDR40", "0:cardinal:other:en")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on omena.", "Unicode.CLDR40", "0:cardinal:one:fi")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on {0} omenaa.", "Unicode.CLDR40", "0:cardinal:other:fi");
ITemplateFormatPrintable printable = localization.LocalizableText["Namespace.Apples"];
WriteLine(printable.Print(CultureInfo.GetCultureInfo("en"), new object[] { 2 })); // You've got 2 apples.
WriteLine(printable.Print(CultureInfo.GetCultureInfo("fi"), new object[] { 2 })); // Sinulla on 2 omenaa.
// </03>
}
{
// <04>
ILocalization localization =
Localization.CreateDefault()
.AddFilePatterns("Localization/{Key}", "Localization/{Culture}/{Key}");
// </04>
}
{
// <04B>
ILocalization localization =
Localization.CreateDefault()
.AddFilePatterns("Localization/**/{Key}", "Localization/**/{Culture}/{Key}");
// </04B>
}
{
ILocalization localization = new Localization()
.AddLine("", "Namespace.Apples", "BraceNumeric", "You've got {0} apple(s).")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got an apple.", "Unicode.CLDR40", "0:cardinal:one:en")
.AddLine("en", "Namespace.Apples", "BraceNumeric", "You've got {0} apples.", "Unicode.CLDR40", "0:cardinal:other:en")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on omena.", "Unicode.CLDR40", "0:cardinal:one:fi")
.AddLine("fi", "Namespace.Apples", "BraceNumeric", "Sinulla on {0} omenaa.", "Unicode.CLDR40", "0:cardinal:other:fi");
// <05>
// Get localizable text
ILocalizedText text = localization.LocalizableTextCached["Namespace.Apples"];
// Create arguments
object[] arguments = { 2 };
// Print
WriteLine(text.Print(CultureInfo.GetCultureInfo("fi"), arguments)); // "Sinulla on 2 omenaa."
// </05>
}
{
// <06>
// Create localization (Reads "Resources/Namespace.l.yml")
ILocalization localization = new Localization()
.SetFallbackCultureProvider(FallbackCultureProvider.Invariant)
.AddFileSystem(LocalizationFileSystem.ApplicationRoot)
.AddFilePatterns("Resources/{Key}", "Resources/{Culture}/{Key}")
.AddFileFormats(LocalizationFileFormatYaml.Instance, LocalizationFileFormatXml.Instance, LocalizationFileFormatJson.Instance);
// Get text that uses current culture
ILocalizedText text = localization.LocalizingTextCached[(CultureProvider.CurrentCulture.Instance, "Namespace.Apples")];
// Assign current culture
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fi");
// Create arguments
object[] arguments = { 2 };
// Print with current culture
WriteLine(text.Print(arguments)); // "Sinulla on 2 omenaa."
// </06>
}
{
// <07>
// Create localization (Reads "Resources/Namespace.l.yml")
ILocalization localization = new Localization()
.SetFallbackCultureProvider(FallbackCultureProvider.Invariant)
.AddFileSystem(LocalizationFileSystem.ApplicationRoot)
.AddFilePatterns("Resources/{Key}", "Resources/{Culture}/{Key}")
.AddFileFormats(LocalizationFileFormatYaml.Instance, LocalizationFileFormatXml.Instance, LocalizationFileFormatJson.Instance);
// Get text that uses specific culture
ILocalizedText text = localization.LocalizedTextCached[("fi", "Namespace.Apples")];
// Assign current culture to english (ignored)
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en");
// Create arguments
object[] arguments = { 2 };
// Print with the assigned culture "fi"
WriteLine(text.Print(arguments)); // "Sinulla on 2 omenaa."
// </07>
}
{
// <08>
// Create text
ITemplateText text = new TemplateText("You've got {0} apple(s).", TemplateFormat.BraceNumeric);
// Decorate text to localize to language in 'formatProvider'
text = Localization.Default.Localize(text, "Namespace.Apples");
// Print
object[] arguments = { 2 };
WriteLine(text.Print(null, arguments)); // "You've got {0} apples."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("en"), arguments)); // "You've got 2 apples."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("fi"), arguments)); // "Sinulla on 2 omenaa."
WriteLine(text.Print(formatProvider: CultureInfo.GetCultureInfo("sv"), arguments)); // "Du har 2 äpplen."
// </08>
}
{
// <09>
// Create text
ITemplateText text = new TemplateText("You've got {0} apple(s).", TemplateFormat.BraceNumeric);
// Get active culture provider (CurrentThread)
ICultureProvider cultureProvider = CultureProvider.Default;
// Decorate text to localize to the active culture
text = Localization.Default.Localize(text, "Namespace.Apples", cultureProvider);
// Print
object[] arguments = { 2 };
cultureProvider.Culture = "en";
WriteLine(text.Print(formatProvider: null, arguments)); // "You've got 2 apple(s)."
cultureProvider.Culture = "sv";
WriteLine(text.Print(formatProvider: null, arguments)); // "Du har 2 äpplen."
cultureProvider.Culture = "fi";
WriteLine(text.Print(formatProvider: null, arguments)); // "Sinulla on 2 omenaa."
// </09>
}
}
}