RSCG – Strings.ResourceGenerator
| name | Strings.ResourceGenerator |
| nuget | https://www.nuget.org/packages/Strings.ResourceGenerator/ |
| link | https://github.com/biggik/Strings.ResourceGenerator |
| author | Birgir Kristmannsson |
Generating strongly typed string resources – with parameter and Localization
This is how you can use Strings.ResourceGenerator .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="TestData\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Strings.ResourceGenerator" Version="0.7.0" OutputItemType="Analyzer" ReferenceOutputAssembly="false" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
The code that you will use is
using Strings.ResourceGenerator.Examples.Resources;
Console.WriteLine("Hello, World!");
Console.WriteLine(Countries.Goodbye("World"));
Console.WriteLine(Countries.IT.Goodbye("Mondo"));
{
"config": {
"public": true,
"namespace": "Strings.ResourceGenerator.Examples.Resources"
},
"strings": [
{
"key": "Goodbye",
"values": [
{
"value": "Goodbye {within@string}"
},
{
"locale": "it",
"value": "Ciao {within@string}"
}
]
}
]
}
The code that is generated is
// <auto-generated/>
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Strings.ResourceGenerator.Examples.Resources
{
// Strings.ResourceGenerator v0.7.0.0 by Status ehf - Generated 2025-08-01 15:26:22 (UTC)
// Generated from: D:\gth\RSCG_Examples\v2\rscg_examples\Strings.ResourceGenerator\src\EmbedDemo\TestData\Countries.json, D:\gth\RSCG_Examples\v2\rscg_examples\Strings.ResourceGenerator\src\EmbedDemo\TestData\Countries.json
// 1 string with interpolation parameters
/// <summary>
/// Generated string accessor class for Countries
/// Configuration []
/// Namespace : Strings.ResourceGenerator.Examples.Resources
/// Public : True
/// Prefix :
/// Const : False
/// ExcludeCoverage : True
/// ExcludeCoverageMessage : Auto-generated from string resources
/// </summary>
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Auto-generated from string resources")]
public static class Countries
{
// Lazy initializers for each locale
private static readonly Lazy<IGeneratedLocalizerForCountries> _neutral = new Lazy<IGeneratedLocalizerForCountries>(() => InitializeLocalizerFor("Neutral"));
private static readonly Lazy<IGeneratedLocalizerForCountries> _it = new Lazy<IGeneratedLocalizerForCountries>(() => InitializeLocalizerFor("IT"));
private static IGeneratedLocalizerForCountries InitializeLocalizerFor(string locale)
{
if (locale == "IT")
{
return new GeneratedLocalizerForCountriesIT();
}
else
{
return new GeneratedLocalizerForCountriesNeutral();
}
}
private static IGeneratedLocalizerForCountries Current
{
get
{
if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.ToUpper() == "IT")
{
return _it.Value;
}
else
{
return _neutral.Value;
}
}
}
/// <summary>
/// Accessor for the 'neutral' locale
/// </summary>
public static IGeneratedLocalizerForCountries Neutral => _neutral.Value;
/// <summary>
/// Accessor for the 'it' locale
/// </summary>
public static IGeneratedLocalizerForCountries IT => _it.Value;
#region String accessors
/// <summary>
/// Neutral: Goodbye {within} <br/>
/// IT: Ciao {within}
/// </summary>
public static string Goodbye(string within) => Current.Goodbye(within);
#endregion
/// <summary>
/// Format the string identified by <paramref name="name"/> with the given parameters
/// </summary>
public static string Format(string name, params object[] args)
{
return args == null || args.Length == 0 ? name : string.Format(name, args);
}
/// <summary>
/// Unescape unnecessary escapes when string is not used as part of code
/// </summary>
public static string Unescape(string value)
{
return value.Replace("\\", "");
}
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters
/// </summary>
public static string GetString(string name, params object[] args) => Current.GetString(name, args);
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters, or empty string if not found
///
/// </summary>
public static string GetStringOrEmpty(string name, params object[] args) => Current.GetStringOrEmpty(name, args);
#region IGeneratedLocalizerForCountries
/// <summary>
/// Interface IGeneratedLocalizerForCountries for string access to Countries resources
/// </summary>
public interface IGeneratedLocalizerForCountries
{
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters
/// </summary>
string GetString(string name, params object[] args);
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters, or empty string if not found
/// </summary>
string GetStringOrEmpty(string name, params object[] args);
/// <summary>
/// Goodbye {within}
/// </summary>
string Goodbye(string within);
}
#endregion
#region GeneratedLocalizerForCountriesBase
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Auto-generated from string resources")]
private abstract class GeneratedLocalizerForCountriesBase
{
#region Generic string lookup (by dictionary)
private readonly Lazy<Dictionary<string, string>> lookup;
protected Dictionary<string, string> Lookup => lookup.Value;
protected GeneratedLocalizerForCountriesBase()
{
lookup = new Lazy<Dictionary<string, string>>(() => InitializeLookupResources());
}
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters
/// </summary>
public string GetString(string name, params object[] args)
{
if (lookup.Value.ContainsKey(name))
{
var s = lookup.Value[name];
return args == null || args.Length == 0 ? s : string.Format(s, args);
}
throw new ArgumentException($"Lookup value {name} is not found in localized resources in Countries");
}
/// <summary>
/// Get the string identified by <paramref name="name"/> formatted with the specified parameters, or empty string if not found
/// </summary>
public string GetStringOrEmpty(string name, params object[] args)
{
try
{
return GetString(name, args);
}
catch (ArgumentException)
{
return "";
}
}
protected abstract Dictionary<string, string> InitializeLookupResources();
#endregion
}
#endregion
#region GeneratedLocalizerForCountriesIT
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Auto-generated from string resources")]
private class GeneratedLocalizerForCountriesIT : GeneratedLocalizerForCountriesBase, IGeneratedLocalizerForCountries
{
#region Generic string lookup (by dictionary)
protected override Dictionary<string, string> InitializeLookupResources() =>
new Dictionary<string, string>
{
{ "Goodbye", "Ciao {within}" },
};
#endregion
#region String accessors
public string Goodbye(string within) => $"Ciao {within}";
#endregion
}
#endregion
#region GeneratedLocalizerForCountriesNeutral
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Auto-generated from string resources")]
private class GeneratedLocalizerForCountriesNeutral : GeneratedLocalizerForCountriesBase, IGeneratedLocalizerForCountries
{
#region Generic string lookup (by dictionary)
protected override Dictionary<string, string> InitializeLookupResources() =>
new Dictionary<string, string>
{
{ "Goodbye", "Goodbye {within}" },
};
#endregion
#region String accessors
public string Goodbye(string within) => $"Goodbye {within}";
#endregion
}
#endregion
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Strings.ResourceGenerator