Flattening generator
Sometimes your data source contains a flattened version of your complex domain classes. For example, the class Person
contains the Address
property and it contains the Town
property. But your data source contains AddressTown
column. If you needed an internal class to process such source data, you had to write it manually. You can now use the Flattening generator for this.
Installation
dotnet add package Kros.Generators.Flattening
How to use it
You define partial class and marke it with the Flatten
attribute.
[Flatten(SourceType = typeof(Person))]
public partial class PersonFlat
{
}
And that’s it. The generator will generate a partial class for you, which will contain all the necessary properties.
Another example
You have the following domain classes and value objects.
public class Document
{
public Contact Owner { get; set; }
public Contact Collaborator { get; set; }
public string Name { get; set; }
}
public class Contact
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string Street { get; set; }
}
And you want a flattened class, but with some exceptions.
[Flatten(SourceType = typeof(Document))]
[FlattenPropertyName(SourcePropertyName = "Owner.Address.City", Name = "Town")]
[FlattenPropertyName(SourcePropertyName = "Collaborator.Address", Name = "")]
public partial class DocumentFlat
{
}
The generated class will look like this:
public partial class DocumentFlat
{
public string OwnerName { get; set; }
public string OwnerAddressTown { get; set; }
public string OwnerAddressStreet { get; set; }
public string CollaboratorName { get; set; }
public string CollaboratorCity { get; set; }
public string CollaboratorStreet { get; set; }
public string Name { get; set; }
}
Settings
Skip
You may not want to generate some properties into the output flattened class. To do this, you can use the Skip
parameter and define a list of properties to be ignored.
[Flatten(SourceType = typeof(Document),
Skip = new string[] { nameof(Document.Collaborator)})]
DoNotFlatten
If you do not want to flatten any of the properties, use the parameter to do so DoNotFlatten
.
[Flatten(SourceType = typeof(Document),
DoNotFlatten = new string[] { nameof(Document.Owner) })]
Rename outup property
If you want to rename the output property, use the FlattenPropertyName
attribute.
[FlattenPropertyName(SourcePropertyName = "Owner.Address.City", Name = "Town")]
[FlattenPropertyName(SourcePropertyName = "Collaborator.Address", Name = "")]
Mapping
This generator also generates ToComplex
and FromComplex
mapping methods for you.
ToComplex
Allows you to map a flat instance to its complex domain form.
DocumentFlat flat = new()
{
OwnerAddressTown = "Wichita, KS 67202",
OwnerAddressStreet = "1938 Roosevelt Road",
OwnerName = "Jill A. Spurgeon",
CollaboratorCity = "8282 Koprivnica",
CollaboratorStreet = "Kolodvorska 28",
CollaboratorName = "Christine M. Dudley",
Name = "new document"
};
Document document = flat.ToComplex();
Or simply use the implicit conversion.
Document document = flat;
FromComplex
It allows you to create a flattened instance of your complex domain class.
DocumentFlat flat = DocumentFlat.FromComplex(document);
Or simply use the explicit conversion.
DocumentFlat flat = (DocumentFlat)document;
IEnumerable.ToComplex
It is possible to convert an entire collection of flattened instances to a collection of complex objects.
IEnumerable<DocumentFlat> flatDocuments = LoadData();
IEnumerable<Document> documents = flatDocuments.ToComplex<DocumentFlat, Document>();
Limitation
⚠ Mapping methods are generated only if all types contain a public parameterless constructor or a constructor that has the same parameters as the properties (case insensitive).