Skip to content

Instantly share code, notes, and snippets.

@ArtemAvramenko
Last active December 18, 2019 14:08
Show Gist options
  • Save ArtemAvramenko/7d6f602547bc6465ce25e78ed27c436d to your computer and use it in GitHub Desktop.
Save ArtemAvramenko/7d6f602547bc6465ce25e78ed27c436d to your computer and use it in GitHub Desktop.
JSON localization to C# objects
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
// In TypeScript:
//
// type Strings = {
// readonly [P in keyof StringsLocalization]: StringsLocalization[P][0];
// };
private string localizationJson = @"{
'aProp': [ 'AAA', 'ЯЯЯ' ],
'bProp': [ 'BBB', 'БББ' ]
}".Replace("'", "\"");
public Form1()
{
InitializeComponent();
}
private static string ToCamelCase(string text)
{
if (text != null)
{
var upperCount = 0;
while (upperCount < text.Length && char.IsUpper(text, upperCount))
{
upperCount++;
}
if (upperCount > 1 && upperCount < text.Length && char.IsLower(text, upperCount))
{
upperCount--;
}
if (upperCount > 0)
{
text = text.Substring(0, upperCount).ToLowerInvariant() + text.Substring(upperCount);
}
}
return text;
}
private void Form1_Load(object sender, EventArgs e)
{
var json = JObject.Parse(localizationJson);
var stringsList = new List<Strings>();
for (var lang = 0; lang < 2; lang++)
{
stringsList.Add(new Strings());
}
var type = typeof(Strings);
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var prop in props)
{
if (!prop.CanWrite && prop.PropertyType == typeof(string))
{
var field = type.GetField($"<{prop.Name}>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
var jsonName = ToCamelCase(prop.Name);
var values = json[jsonName]?.Children();
if (values == null)
{
throw new InvalidOperationException($"'{jsonName}' property is not specified in JSON");
}
var lang = 0;
foreach (var value in values)
{
field.SetValue(stringsList[lang++], value.Value<string>());
}
}
}
}
var strings = stringsList[1];
Text = strings.BProp;
}
}
public class Strings
{
public string AProp { get; }
public string BProp { get; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment