IncaTechnologies.LocalizationFramework 1.0.1

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package IncaTechnologies.LocalizationFramework --version 1.0.1
NuGet\Install-Package IncaTechnologies.LocalizationFramework -Version 1.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IncaTechnologies.LocalizationFramework" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add IncaTechnologies.LocalizationFramework --version 1.0.1
#r "nuget: IncaTechnologies.LocalizationFramework, 1.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install IncaTechnologies.LocalizationFramework as a Cake Addin
#addin nuget:?package=IncaTechnologies.LocalizationFramework&version=1.0.1

// Install IncaTechnologies.LocalizationFramework as a Cake Tool
#tool nuget:?package=IncaTechnologies.LocalizationFramework&version=1.0.1

IncaTechnologies.LocalizationFramework

What does it do?

I created this piece of software to manage localization more easily then using resource file. The general idea is to have xml files (*.incaloc) that contains the localized text and a C# class that retrieve the text when needed.

How to use it?

The main two classes of the framework are IncaLocReader and IncLocGenerator. The first one is used to retrieve the localized text, the second one to generate .incaloc files that will contain the localized text.

How to use IncaReader?

IncaLocReader is the default concrete implementation of IIncaLocReader. It can be customized such that the created version can work in a new way or it can be personalized by overriding its methods and properties.

To use the default implementation your project must embed .incaloc files as a resource that reflects the properties that has to be localized. This file must be an xml file that is named as [NameSpace].[Class].incaloc, the content must match the following pattern:

<?xml version="1.0" encoding="utf-8"?>
<IncaTehcnologies NameSpace="MyNameSpace" Class="MyClass">
  <Localize Property="FirstProperty">
    <en-EN>Text</en-EN>
    <fr-FR>Texte</fr-FR>
    <es-ES>Texto</es-ES>
  </Localize>
  <Localize Property="SecondProperty">
    <en-EN>...</en-EN>
    <fr-FR>...</fr-FR>
    <es-ES>...</es-ES>
  </Localize>
</IncaTehcnologies>

Thus, the root element must be IncaTchnologies and it has two attributes NameSpace and Class. Inside this root element, there are contained as many Localize elements as are needed. Every Localize element has a Property attribute that points to the property that has to be localized. It contains elements named after the culture codes, the languages, for which the localization is avaliable. In the snippet are included codes for English, Spanish and French but any culture code can be included.

IncaLocReader has been created to work with MVVM design pattern and it might be incorporeted in your code like this:

public abstract class _ViewModelBase
{
    protected virtual string GetText([CallerMemberName] string? propertyName = null)
    {
        return IncaLocService.IncaLocReader.GetText(new IncaLocParameters(
            nameSpace: this.GetType().Namespace,
            classIdentifier: this.GetType().Name,
            propertyIdentifier: propertyName));
    }
}

public class MyViewModel : _ViewModelBase
{
    public string? FirstProperty => GetText();

    public string? SecondProperty => GetText();
}

The GetText(IncaLocParameters param) method of IncaLocReader will automatically look for an .incaloc file embedded in the project whose name matches the invoker class and retrieve the text correspondent to the culture specified in the property IncaLocReader.CurrentCulture.

In the snippet, IncaLocService is used. It is simply a utility class that returns a singleton instance of IncaLocReader. It is not required to use this class to get an instance of IncaLocReader.

How to use IncaLocGenerator?

So far it looks like that use IncaLocReader requires quite a work since .incaloc files must be generated end embedded to the project. Here is where IncaLocGenerator comes into place. As for the reader, it can be customized and personalized. It has a method that generates .incaloc files but its direct usage is not particularly useful since the method must know all the properties (including namespaces and classes) for the files to be generated.

This object is ment to be used mainly in a tool combined with the IncaLocalizeAttribute. The tool has already been created and it is installed (locally) automatically when this framework is installed via Nuget package. If for some reason the installation fails, it is possible to install the tool directly from dotnet client. Once installed, it is possible to call the tool from the dotnet client (by default is installed locally in the directory of the solution and it can be invoked only from that directory or subdirectories):

dotnet inca-loc [-Diagnostic] [-Input <String>] [-Output <String>] [-Generator <String>] [-Cultures <String>]

Otherwise, if Visual Studio is used for development, it can be invoked inside the Package Manager Console via:

Invoke-Localization [-Diagnostic] [-Input <String>] [-Output <String>] [-Generator <String>] [-Cultures <String>] [<CommonParameters>]

In both cases the tool will look inside all the .cs files in a project folder and automatically generates the .incaloc file for every property that is decorated with IncaLocalizeAttribute. It also automatically embeds the file to the project as a resource.

Example:

public class MyViewModel : _ViewModelBase
{
    [IncaLocalize]
    public string? FirstProperty => GetText();

    [IncaLocalize]
    public string? SecondProperty => GetText();
}

Call Invoke-Localization and the followiong file will be created in the folder .\MyProject\Localization .

<?xml version="1.0" encoding="utf-8"?>
<IncaTehcnologies NameSpace="MyNameSpace" Class="MyClass">
  <Localize Property="FirstProperty">
    <en-EN></en-EN>
  </Localize>
  <Localize Property="SecondProperty">
    <en-EN></en-EN>
  </Localize>
</IncaTehcnologies>

If cultures where specified by invoking, for example:

Invoke-Localization -Cultures "en-US, it-IT"

The .incaloc file would be:

<?xml version="1.0" encoding="utf-8"?>
<IncaTehcnologies NameSpace="MyNameSpace" Class="MyClass">
  <Localize Property="FirstProperty">
    <en-US></en-US>
    <it-IT></it-IT>
  </Localize>
  <Localize Property="SecondProperty">
    <en-US></en-US>
    <it-IT></it-IT>
  </Localize>
</IncaTehcnologies>

The same results can be achieved invoking the tool form the dotnet client as:

PS: C:\MyCoolProject\MyProject> dotnet inca-loc -Cultures "en-US, it-IT"

Author Remarks

This project is tailor made on my needings but I thought that maybe someone else might be interested in a similar solution for the localization, or better for the support of multiple languages in their own projects. I also used this project to study more in depth how dotnet tools works, how Nuget packages works, how to write commandlet, how to write analyzers and how code generation works. My ultimate goal was not only to create a framework that I needed but I was also interested in finding out if I was able to create a similar experience to the one provided by the Microsoft.EntityFrameworkCore.Tools and CommunityToolkit.Mvvm.

In the next update (if ever there will be one), I would like to use code generators in order to create programmatically the properties that has to be localized. This is the result I would like to get:

public partial class MyViewModel : _ViewModelBase
{
    [IncaAutoLocalize]
    string? FirstProperty;

    [IncaAutoLocalize]
    string? SecondProperty;
}

//Generated
partial class MyViewModel
{
    protected virtual string GetText([CallerMemberName] string? propertyName = null)
    {
        return IncaLocService.IncaLocReader.GetText(new IncaLocParameters(
            nameSpace: this.GetType().Namespace,
            classIdentifier: this.GetType().Name,
            propertyIdentifier: propertyName));
    }

    public string? FirstProperty => GetText();

    public string? SecondProperty => GetText();

}

Or something like this at least.

I actually explored a lot of possible solution to get around this project and I ended up with different approaches than the ones used in the framework that inspired me the most. Nonetheless I am pretty happy with the results I got.

If anyone wants to contribute, give advise or point out a better strategy to achieve what this framework does, you are very welcome sir. You can do it through GitHub at any time.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.9 40 5/29/2024
1.0.8 101 2/21/2024
1.0.7 240 10/18/2023
1.0.6 121 10/14/2023
1.0.2 238 3/2/2023
1.0.1 221 3/1/2023
1.0.0 250 3/1/2023