Skip to content

Complexes

Leonardo Porro edited this page Jan 27, 2023 · 23 revisions

A complex is a type that contains a set of members and a constructor. It is usually a .NET class but it extends to any other structure that can represent a set of member->value pairs (i.e.: members, properties), such as:

  • Anonymous classes, are handled just as regular ones.
  • Dictionary<string, object>, each key-pair value represents a member,
  • JsonObject where each value node represents a member.
  • Any other custom type that can hold a set of member _name _-> value pairs.

Complexes can be seen as an abstraction of a regular object, and they can be extended to handle custom types.

Members

Members are variables associated with the complex type. They can be represented by propertes for .NET classes, key-value pairs for Dictionary<string, object>) or any other slot that can contain named values for custom types. A member should have a name and a getter and setter that changes depending on the handled type. Property getters and setters for .NET classes, indexer[] for Dictionary<string, object> or any other accessor for custom types. Members can be renamed, ignored, removed and custom code may be added to getters and setters, also they can hold annotations.

Configuration

Customize constructor

Specify an expression used to build a new instance.

Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
      opts.Type<Invoice>().Constructor(c => new Invoice(1));
   });
});

Exclude members (Type)

Ignore the specified members in all map operation for the any type combination.

Annotated configuration
public class TargetEntity
{
   public string Text1 { get; set; }

   [NotMapped]
   public string Text2 { get; set; }
}
Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
       opts.Type<TargetEntity>().Member(m => m.Text2).Exclude();
   });
});

Exclude members (Map)

Ignore the specified members in all map operations for the given type combination.

Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
        config.Type<Invoice>().FromType<InvoiceDTO>().Member(m => m.InvoiceType).Exclude();
   });
});

Map a member from a given source member

Map a member from a different member name and type.

Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
        config.Type<User>().FromType<UserDTO>()
               .Member(u => u.Id).FromMember(u => u.Key)
   });
});

Map a member from a given source expression

Ignore the specified members in all map operations for the given type combination.

Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
        config.Type<Invoice>().FromType<InvoiceDTO>().Member(m => m.InvoiceType).Exclude();
   });
});

Customize accessors

Fluent configuration
services.AddDbContext<MainDbContext>(cfg =>
{
   ...
   cfg.UseMapping(opts => {
       opts.Type<TargetEntity>()
           .Member(m => m.Value)
           .Setter((@this, value, mapContext) =>
               {
                    @this.Value = value + 1;
               });

       opts.Type<SourceEntity>()
           .Member(m => m.Value)
           .Getter((@this, mapContext) =>
              {
                   return @this.Value + 1;
              });
   });
});