File Localization
This article explains the different ways to acquire localized file resources.
.FileQueryCached[(culture, key)] queries files by 'key' and 'culture'. Best match is first, least last.
// Get files localized to a language
IEnumerable<ILocalizationFile> files = Localization.Default.FileQueryCached[(culture: "fi", key: "image")].ToArray();
// Print file names
foreach (var file in files)
WriteLine($"\"{file.Culture}\": {file.FileName}"); // "fi":Resources/fi/image.png, "": Resources/image.png
.LocalizableFileCached[key] gets a localizable file handle that can be localized to different cultures.
// Get file
ILocalizable<ILocalizationFile> localizable = Localization.Default.LocalizableFileCached[key: "image"];
// Localize to "fi"
ILocalized<ILocalizationFile> file_fi = localizable.Localize("fi")!;
// Print file name
WriteLine($"\"{file_fi.Culture}\": {file_fi.Value.FileName}"); // "fi":Resources/fi/image.png
.LocalizingFileCached[(cultureProvider, key)] gets a file handle that localizes to the language in the assigned 'cultureProvider'.
// Get cultrue provider
ICultureProvider cultureProvider = new CultureProvider("en");
// Get automatically localizing file
ILocalizing<ILocalizationFile> localizing = Localization.Default.LocalizingFileCached[(cultureProvider, key: "image")];
// Assign another language
cultureProvider.Culture = "fi";
// Localize to "fi"
ILocalized<ILocalizationFile> file_fi = localizing.Value!;
// Print file name
WriteLine($"\"{file_fi.Culture}\": {file_fi.Value.FileName}"); // "fi":Resources/fi/image.png
IFileLocalizer localizes files to the assigned 'namespace' and 'name' parameter.
// Get cultrue provider
ICultureProvider cultureProvider = new CultureProvider("en");
// Create file localizer
IFileLocalizer localizer = new FileLocalizer(Localization.Default, cultureProvider, @namespace: null);
// Assign another language
cultureProvider.Culture = "fi";
// Get localized file(s)
ILocalized<ILocalizationFile[]> files = localizer["image"]!;
foreach (var file in files.Value)
WriteLine($"\"{file.Culture}\": {file.FileName}"); // "fi":Resources/fi/image.png, "": Resources/image.png
ILocalized<T>
/// <summary>Resource that is localized to specific culture.</summary>
public interface ILocalized : ILocalizationKeyProvider, ICultureProvider, ILocalizationErrorProvider
{
}
/// <summary>Resource that is localized to specific culture.</summary>
/// <typeparam name="T">Resource type</typeparam>
public interface ILocalized<out T> : ILocalized
{
/// <summary>Resource value</summary>
T Value { get; }
}
ILocalizing<T>
/// <summary>Resource that localizes to the current culture in an assigned <see cref="ICultureProvider"/>.</summary>
public interface ILocalizing : ILocalizationKeyProvider
{
/// <summary>Culture and fallback cultures provider</summary>
ICultureProvider CultureProvider { get; set; }
}
/// <summary>Resource that localizes to the current culture in an assigned <see cref="ICultureProvider"/>.</summary>
/// <typeparam name="T">Resource type</typeparam>
public interface ILocalizing<out T> : ILocalizing
{
/// <summary>Resource localized to culture from <see cref="ILocalizing.CultureProvider"/> or to default value.</summary>
ILocalized<T>? Value { get; }
}
ILocalizer<T>
/// <summary>Base interface for localizer.</summary>
public interface ILocalizer
{
/// <summary>Namespace prefix</summary>
string? Namespace { get; set; }
/// <summary>Resource Type</summary>
Type ResourceType { get; }
/// <summary>Applicable actice culture provider</summary>
ICultureProvider CultureProvider { get; set; }
/// <summary>
/// Get localized resource for <paramref name="name"/>.
///
/// If <see cref="ILocalizer.Namespace"/> or <paramref name="name"/> is null, then counter part is used as key without separator '.'.
/// </summary>
ILocalized? this[string? name] { get; }
}
/// <summary><typeparamref name="T"/> localizer.</summary>
/// <typeparam name="T">Resource type</typeparam>
public interface ILocalizer<out T> : ILocalizer
{
/// <summary>
/// Get localized resource for <paramref name="name"/>.
///
/// If <see cref="ILocalizer.Namespace"/> or <paramref name="name"/> is null, then counter part is used as key without separator '.'.
/// </summary>
new ILocalized<T>? this[string? name] { get; }
}
/// <summary><typeparamref name="T"/> for <typeparamref name="Namespace"/>.</summary>
/// <typeparam name="T">Resource type</typeparam>
/// <typeparam name="Namespace">Key namespace</typeparam>
public interface ILocalizer<T, Namespace> : ILocalizer<T> { }
/// <summary><typeparamref name="T"/> localizer for <typeparamref name="Namespace"/> using <typeparamref name="CultureProvider"/>.</summary>
/// <remarks>This interfaces is typically used with dependency injection.</remarks>
/// <typeparam name="T">Resource type</typeparam>
/// <typeparam name="Namespace">Key namespace</typeparam>
/// <typeparam name="CultureProvider">Culture provider type. Type must have a parameterless constructor.</typeparam>
public interface ILocalizer<T, Namespace, CultureProvider> : ILocalizer<T, Namespace> where CultureProvider : ICultureProvider { }
IFileLocalizer
/// <summary>Text localizer</summary>
public interface IFileLocalizer : ILocalizer<ILocalizationFile[]> { }
/// <summary>Text localizer</summary>
public interface IFileLocalizer<Namespace> : IFileLocalizer, ILocalizer<ILocalizationFile[], Namespace> { }
/// <summary>Text localizer</summary>
public interface IFileLocalizer<Namespace, CultureProvider> : IFileLocalizer<Namespace>, ILocalizer<ILocalizationFile[], Namespace, CultureProvider> where CultureProvider : ICultureProvider { }
ILocalizationFile
/// <summary>Localization resource, typically a file.</summary>
public interface ILocalizationFile : ILocalizationFileName, ILocalizationKeyProvider, ICultureProvider
{
/// <summary>File format.</summary>
ILocalizationFileFormat FileFormat { get; set; }
/// <summary>Try open <paramref name="stream"/> to resource.</summary>
/// <exception cref="Exception">On unexpected error.</exception>
bool TryOpen([NotNullWhen(true)] out Stream? stream);
}
Full Example
Full example
using Avalanche.Localization;
using static System.Console;
class filelocalization
{
public static void Run()
{
{
// <01>
// Get files localized to a language
IEnumerable<ILocalizationFile> files = Localization.Default.FileQueryCached[(culture: "fi", key: "image")].ToArray();
// Print file names
foreach (var file in files)
WriteLine($"\"{file.Culture}\": {file.FileName}"); // "fi":Resources/fi/image.png, "": Resources/image.png
// </01>
}
{
// <02>
// Get file
ILocalizable<ILocalizationFile> localizable = Localization.Default.LocalizableFileCached[key: "image"];
// Localize to "fi"
ILocalized<ILocalizationFile> file_fi = localizable.Localize("fi")!;
// Print file name
WriteLine($"\"{file_fi.Culture}\": {file_fi.Value.FileName}"); // "fi":Resources/fi/image.png
// </02>
}
{
// <03>
// Get cultrue provider
ICultureProvider cultureProvider = new CultureProvider("en");
// Get automatically localizing file
ILocalizing<ILocalizationFile> localizing = Localization.Default.LocalizingFileCached[(cultureProvider, key: "image")];
// Assign another language
cultureProvider.Culture = "fi";
// Localize to "fi"
ILocalized<ILocalizationFile> file_fi = localizing.Value!;
// Print file name
WriteLine($"\"{file_fi.Culture}\": {file_fi.Value.FileName}"); // "fi":Resources/fi/image.png
// </03>
}
{
// <04>
// Get cultrue provider
ICultureProvider cultureProvider = new CultureProvider("en");
// Create file localizer
IFileLocalizer localizer = new FileLocalizer(Localization.Default, cultureProvider, @namespace: null);
// Assign another language
cultureProvider.Culture = "fi";
// Get localized file(s)
ILocalized<ILocalizationFile[]> files = localizer["image"]!;
foreach (var file in files.Value)
WriteLine($"\"{file.Culture}\": {file.FileName}"); // "fi":Resources/fi/image.png, "": Resources/image.png
// </04>
}
}
}