Scrumboard.Tools.Localization 1.1.0

dotnet add package Scrumboard.Tools.Localization --version 1.1.0
                    
NuGet\Install-Package Scrumboard.Tools.Localization -Version 1.1.0
                    
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="Scrumboard.Tools.Localization" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Scrumboard.Tools.Localization" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Scrumboard.Tools.Localization" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Scrumboard.Tools.Localization --version 1.1.0
                    
#r "nuget: Scrumboard.Tools.Localization, 1.1.0"
                    
#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.
#:package Scrumboard.Tools.Localization@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Scrumboard.Tools.Localization&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Scrumboard.Tools.Localization&version=1.1.0
                    
Install as a Cake Tool

Description

This tool gives you easy and convenient access to localized text that makes adding localization in your products much easier.

How to download

Install a NuGet package using following command:

dotnet add package Scrumboard.Tools.Localization

Use examples

IMPORTANT Only json format for localizations is supported

First thing you have to do is go into your .csproj where you want to generate localization structure and add your template file in your project.

In our case the template file will be English.json:

<ItemGroup>
    <AdditionalFiles Include="English.json" />
</ItemGroup>

Properties example 1.1

English.json:

{
    "Hello": "Hello",
    "Bye": "Bye"
}

French.json:

{
    "Hello": "Bonjour",
    "Bye": "Au revoir"
}

Lang.cs:

[ExtractFrom("English.json")]
partial class Lang {} // The class must be partial

IMPORTANT You cannot specify nested paths as a template file such as: Localizations/English.json. If you have to, then you need to change your template file including to this <AdditionalFiles Include="Localizations/English.json" />.

Usage:

// Load english
Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.HelloKey);

Console.WriteLine("=======");

// Load french
Lang.Load(File.ReadAllText("French.json"));
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.HelloKey);

Output:

Hello
Hello
=======
Bonjour
Hello

Properties example 1.2

There is also a style variation that you can change in attribute:

Lang.cs:

[ExtractFrom("English.json", IsAdditionalsPostfixStyle = false)] // The default value is true
partial class Lang {}

Usage:

Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.Keys.Hello); // Here's the difference

Console.WriteLine("=====================");

Lang.Load(File.ReadAllText("French.json"));
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.Keys.Hello); // And here

Nested properties example 1.1

English.json:

{
    "Colors": {
        "Orange": "Orange",
        "Yellow": "Yellow",
        "Purple": "Purple"
    }
}

Deutsch.json:

{
    "Colors": {
        "Orange": "Orange",
        "Yellow": "Gelb",
        "Purple": "Lila"
    }
}

Lang.cs:

[ExtractFrom("English.json")]
partial class Lang {}

Usage:

Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Colors.Orange);
Console.WriteLine(Lang.Colors.Yellow);
Console.WriteLine(Lang.Colors.Purple);
Console.WriteLine(Lang.Colors.OrangeKey);
Console.WriteLine(Lang.Colors.YellowKey);
Console.WriteLine(Lang.Colors.PurpleKey);

Console.WriteLine("=====================");

Lang.Load(File.ReadAllText("Deutsch.json"));
Console.WriteLine(Lang.Colors.Orange);
Console.WriteLine(Lang.Colors.Yellow);
Console.WriteLine(Lang.Colors.Purple);
Console.WriteLine(Lang.Colors.OrangeKey);
Console.WriteLine(Lang.Colors.YellowKey);
Console.WriteLine(Lang.Colors.PurpleKey);

Output:

Orange
Yellow
Purple
Colors.Orange
Colors.Yellow
Colors.Purple
=====================
Orange
Gelb
Lila
Colors.Orange
Colors.Yellow
Colors.Purple

Nested properties example 1.2

For nested properties different style would look like this: Lang.cs:

[ExtractFrom("English.json", IsAdditionalsPostfixStyle = false)]
partial class Lang {}

Usage:

Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Colors.Orange);
Console.WriteLine(Lang.Colors.Yellow);
Console.WriteLine(Lang.Colors.Purple);
Console.WriteLine(Lang.Colors.Keys.Orange); //
Console.WriteLine(Lang.Colors.Keys.Yellow); // Here's the difference
Console.WriteLine(Lang.Colors.Keys.Purple); //

Console.WriteLine("=====================");

Lang.Load(File.ReadAllText("Deutsch.json"));
Console.WriteLine(Lang.Colors.Orange);
Console.WriteLine(Lang.Colors.Yellow);
Console.WriteLine(Lang.Colors.Purple);
Console.WriteLine(Lang.Colors.Keys.Orange); //
Console.WriteLine(Lang.Colors.Keys.Yellow); // And here
Console.WriteLine(Lang.Colors.Keys.Purple); //

Formatted strings example 1.1

Sometimes translating only words is not enough and inconvenient to use formating. So this tool also supports formatted strings:

English.json:

{
    "Greeting": "Hello, {0}!"
}

Spanish.json:

{
    "Greeting": "Hola, {0}!"
}

Lang.cs:

[ExtractFrom("English.json")]
partial class Lang {}

Usage:

Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Greeting("John"));

Console.WriteLine("============");

Lang.Load(File.ReadAllText("Spanish.json"));
Console.WriteLine(Lang.Greeting("John"));

Output:

Hello, John!
============
Hola, John!

Formatted strings example 1.2

By default the generator would name arguments in the method as arg0, arg1, arg2, etc. But you can give a meaningful name for arguments:

English.json:

{
    "Greeting": "Hello, {0:name}!"
}

Now generator would generate this:

public static string Greeting(string name) { ... }

instead of:

public static string Greeting(string arg0) { ... }

IMPORTANT The showed syntax above is not supported on not template files, if you add this to other localizations file it would throw an exception. Arguments names must be only be added in template file.

This would throw an exception during runtime:

{
    "Greeting": "Hola, {0:name}!"
}

This wouldn't:

{
    "Greeting": "Hola, {0}!"
}

IMPORTANT You do not have to specify the name every time when you use a specific argument, but the argument cannot have more than one unique name.

This usage is acceptable:

{
    "Saying": "Hello, {0:name}. Bye {0}!"
}

This as well:

{
    "Saying": "Hello, {0:name}. Bye {0:name}!"
}

Even this:

{
    "Saying": "Hello, {0}. Bye {0:name}!"
}

But this one is not:

{
    "Saying": "Hello, {0:name}. Bye {0:otherName}!"
}

IMPORTANT Two different arguments cannot have the same argument name

This usage is acceptable:

{
    "Saying": "Hello, {0:name}. Bye {1:otherName}!"
}

This one is not:

{
    "Saying": "Hello, {0:name}. Bye {1:name}!"
}

IMPORTANT If in some other localization file there is no enough arguments used it's okay it would ignore passed values, but if the formatted string uses more than in the template file it would throw an exception when you get the localized string.

Template file:

{
    "Greeting": "Hello, {0:name}!"
}

This wouldn't throw an exception:

{
    "Greeting": "Bonjour!"
}

But this one would:

{
    "Greeting": "Hallo {0} und {1}!"
}

Not fully translated example

If some of localizations may not be fully translated you can use your template file translations as placeholders for missing ones:

English.json:

{
    "Hello": "Hello",
    "Bye": "Bye"
}

French.json:

{
    "Hello": "Bonjour"
}

Lang.cs:

[ExtractFrom("English.json")]
partial class Lang {}

Usage:

Lang.Load(File.ReadAllText("English.json"));
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.Bye);

Console.WriteLine("=======");

Lang.Load(File.ReadAllText("French.json"));
Lang.Load(File.ReadAllText("English.json"), clearBeforeLoad: false); // This argument tells not to clear previously loaded strings and add missing ones
Console.WriteLine(Lang.Hello);
Console.WriteLine(Lang.Bye);

Output:

Hello
Bye
=======
Bonjour
Bye

IMPORTANT If some key is not found a getter would return #Key#

IMPORTANT If some other localization has extra properties, they will be loaded, but you won't be able to access them through C# properties and this behaviour should be avoided

Thread-safe example

If you work with multiple threads you may need to access localized strings from them.

This behaviour is supported and you only need to specify it in the attribute:

Lang.cs:

[ExtractFrom("English.json", ThreadSafe = true)] // Default value is false
partial class Lang {}

IMPORTANT It may use slightly more resources.

Providers

There's also LocalizedStringProvider delegate that takes no arguments and returns string.

It was introduced as a ongoing provider to get current localized string value. See LocalizedStringProvider documentation for use examples.

There are few ways how to get provider.

  • Use CreateProvider method:
var provider = Lang.CreateProvider(Lang.HelloKey);
  • Use property:
// if IsAdditionalsPostfixStyle == true
var provider = Lang.HelloProvider;
// if IsAdditionalsPostfixStyle == false
var provider = Lang.Providers.Hello;
  • Or create it from lambda:
var provider = () => Lang.Get(Lang.HelloKey);

Generated documentation

The generator also adds documentation to the methods. If you don't want to add documentation to the generated class you can change it.

Lang.cs:

[ExtractFrom("English.json", GenerateDocumentation = false)] // Default value is true
partial class Lang {}

Generated methods

  • bool Add(string key, string value)
  • bool Remove(string? key)
  • bool Contains(string? key)
  • string Get(string? key)
  • string GetOr(string? key, string defaultValue)
  • void Clear()
  • LocalizedStringProvider CreateProvider(string? key)
  • void Load(string jsonString, bool clearBeforeLoad = true)
  • void Load(Func<string> jsonProvider, bool clearBeforeLoad = true)
  • async Task LoadAsync(Func<Task<string>> jsonProvider, bool clearBeforeLoad = true)
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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.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.1.0 118 7/31/2026
1.0.0 103 7/30/2026