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.


  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; }



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)})]


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 = "")]


This generator also generates ToComplex and FromComplex mapping methods for you.


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;


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;


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>();


⚠ 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).