Skip to content

garcipat/json-migration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JsonMigration

Build Status Deployment Status

JsonMigration is a .NET library for migrating JSON objects between different versions during deserialization. It allows you to define migrations that transform outdated JSON structures to the latest version, making it easy to evolve your data contracts over time.

How it works

You define migration classes implementing the IJsonMigration<T> interface, and register them with your service collection. When a JSON document is loaded, all necessary migrations are applied in sequence to bring the object up to date.

Example

Suppose you have an outdated JSON file:

{
  "Version": 1,
  "NumberProperty1": 11,
  "StringProperty1": "AAA1",
  "ArrayProperty1": ["A", "B", "C"],
  "SubProperty1": { "SubStringProperty1": "AAA", "SubNumberProperty": 111 },
  "DictionaryProperty1": { "Key1": 11, "Key2": 22, "Key3": 33 }
}

You define a migration to map the old properties to the new ones:

internal class MigrationV1 : IJsonMigration<TestJsonObject>
{
  public int Version => 2;
  public JsonObject Migrate(JsonObject rawJson)
  {
    rawJson.SetProperty("NumberProperty", rawJson.GetValueByPath("NumberProperty1"));
    rawJson.SetProperty("StringProperty", rawJson.GetValueByPath("StringProperty1"));
    rawJson.SetProperty("ArrayProperty", rawJson.GetValueByPath("ArrayProperty1"));
    rawJson.SetProperty("SubProperty", rawJson.GetValueByPath("SubProperty1"));
    rawJson.SetProperty("SubProperty.SubStringProperty", rawJson.GetValueByPath("SubProperty1.SubStringProperty1"));
    rawJson.SetProperty("DictionaryProperty", rawJson.GetValueByPath("DictionaryProperty1"));
    return rawJson;
  }
}

You register the migration and document in your service configuration:

var services = new ServiceCollection()
  .AddLogging()
  .AddJsonDocument<TestJsonDocument, TestJsonObject>(jsonDoc => jsonDoc
    .UseMigration<MigrationV1>());

Dependency Injection

The document and its migrations are registered with the dependency injection (DI) container. You can inject your document into any service or controller where you need to work with the migrated data. When the document is resolved from DI, all necessary migrations are applied automatically.

For example, in a service:

public class MyService
{
  private readonly TestJsonDocument _jsonDoc;

  public MyService(TestJsonDocument jsonDoc)
  {
    _jsonDoc = jsonDoc;
  }

  public void DoSomething()
  {
    var content = _jsonDoc.GetContent();
    // Use the migrated content here
  }
}

Example JSON Document using JsonDocumentBase

Suppose you have a class inheriting from JsonDocumentBase<T>:

public class TestJsonDocument : JsonDocumentBase<TestJsonObject>
{
    public TestJsonDocument(IEnumerable<IJsonMigration<TestJsonObject>> migrations, ILogger<TestJsonDocument> logger)
        : base("Resources/outdated.json", new JsonSerializerOptions { WriteIndented = true }, migrations, logger)
    {
    }
}

And the JSON file it loads (e.g., Resources/outdated.json):

{
  "Version": 1,
  "NumberProperty1": 11,
  "StringProperty1": "AAA1",
  "ArrayProperty1": ["A", "B", "C"],
  "SubProperty1": { "SubStringProperty1": "AAA", "SubNumberProperty": 111 },
  "DictionaryProperty1": { "Key1": 11, "Key2": 22, "Key3": 33 }
}

After loading and migration, the resulting object will have the following structure:

{
  "Version": 2,
  "NumberProperty": 11,
  "StringProperty": "AAA1",
  "ArrayProperty": ["A", "B", "C"],
  "SubProperty": { "SubStringProperty": "AAA", "SubNumberProperty": 111 },
  "DictionaryProperty": { "Key1": 11, "Key2": 22, "Key3": 33 }
}

About

Library to migrate json from version to version. Within dependency injection or as a json converter.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 3

  •  
  •  
  •  

Languages