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