Devlooped.Dynamically
1.0.0-alpha
Prefix Reserved
See the version list below for details.
dotnet add package Devlooped.Dynamically --version 1.0.0-alpha
NuGet\Install-Package Devlooped.Dynamically -Version 1.0.0-alpha
<PackageReference Include="Devlooped.Dynamically" Version="1.0.0-alpha" />
paket add Devlooped.Dynamically --version 1.0.0-alpha
#r "nuget: Devlooped.Dynamically, 1.0.0-alpha"
// Install Devlooped.Dynamically as a Cake Addin #addin nuget:?package=Devlooped.Dynamically&version=1.0.0-alpha&prerelease // Install Devlooped.Dynamically as a Cake Tool #tool nuget:?package=Devlooped.Dynamically&version=1.0.0-alpha&prerelease
Create record types from dynamic data with a compatible structural shape.
Usage
Create records for your data types:
public record Point(int X, int Y);
public record Line(Point Start, Point End);
public record Drawing(Line[] Lines);
This project will generate a Dynamically
class with a factory method to create instances
of those records from a data object with a compatible shape, such as:
var data = new
{
Lines = new[]
{
new
{
Start = new { X = 50, Y = 0 },
End = new { X = 0, Y = 100 },
},
new
{
Start = new { X = 50, Y = 0 },
End = new { X = 0, Y = 100 },
}
}
};
Drawing drawing = Dynamically.Create<Drawing>(data);
In adition to a dynamic object (or an ExpandoObject, for example), you can also pass in objects from other strongly typed values that come from a different assembly, but that has the same structure. This allows fast in-memory object mapping without any serialization or extra allocations.
The factory works too for Newtonsoft.Json deserialized objects, for example:
// elsewhere, you got an in-memory Json.NET object model, perhaps with:
dynamic data = JsonConvert.DeserializeObject(json);
// Subsequently, you can turn it into your strongly-typed records:
Drawing drawing = Dynamically.Create<Drawing>(data);
How It Works
This package analyzes (at compile-time) the shape of your records and creates a factory that create instances from a dynamic object. For this, it just accesses the properties of the dynamic object and passes them to the record constructor (or its properties). This means that the data must have (at least) the expected values for the conversion to succeed.
The static Dynamically.Create
generic method is also generated at compile time
and contains a switch statement that dispatches to the correct factory based on
the generic argument specified.
In addition, if the records are partial, you also get static Create
and
CreateMany
static methods on the record type itself, for added convenience,
such as:
partial record Drawing
{
public static Drawing Create(dynamic value);
public static List<Drawing> CreateMany(dynamic value);
}
Limitations
This package is not meant to be a full-fledged object mapper. For that, you can use AutoMapper, for example, which is much more flexible and has excelent performance characteristics. This package does provide very fast in-memory object mapping that is far faster and cheaper than going through any sort of serialization.
As mentioned, the provided factories do not provide backwards-compatibility: if you add a property or constructor argument to the record, the factory will fail for payloads without it.
Sponsors
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CSharp (>= 4.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.