Models and Mapping

Due to the complexity of software systems, a key concept in projects is Mapping, which means how one or more Entities in the Data Transform Object (DTO) or other View Model can be mapped to a new structure . This is very simple and best implemented in the AUA framework. The programmer can easily map their models to other models. The AUA framework infrastructure allows you to easily do any mapping with complex configuration. Using conversion functions you can fetch directly your DTO from database. The AUA framework includes IMapFrom and IHaveCustomMappings. You can easily map fields and collections together.

IMapFrom

In mapping by IMapFrom, the fields of the same name will be mapped. Fields can be of any data type. In this type of map, one object is usually mapped to another object and no special configuration is required. In the following example, an entity is mapped to a DTO. It is enough to implement the IMapFrom interface and when loading the data, the service will load the data from the database according to this interface and the required data. In the example below, a Student entity is created:


            
public class Student : DomainEntity
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

}


Models inherit the BaseEntityDto class at the AUA, and the monitoring and Id fields are added automatically to them. The AUA framework has two mapping methods of IMapFrom and IHaveCustomMappings to map one object to another. In the IMapFrom model, only fields with the same name are mapped, and there is no mapping for those with different names. This type of mapping is the simplest and fastest type of mapping. Derivative and computable fields are best to be placed in the DTO, such as FullName. In the example below, a Student entity is mapped to a StudentDto, as follows:


            
public class StudentDto : BaseEntityDto, IMapFrom<Student>
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    public string FullName => $"{FirstName} {LastName}";

}

ConvertTo

To help with mapping operations, you can convert an object or list of objects into one or a list of view models without any restrictions, and use IMapFrom and IHaveCustomMappings to configure mapping operations (MapperInstance is by default an instance of AutoMapper in all services). For example, we have created a view model called TestMappingVm that uses IHaveCustomMappings to configure mapping operations, thereby mapping a query of the AppUser entity to this view model using ConvertTo and ProjectTo .


            
public class TestMappingVm : IHaveCustomMappings
{

    public string Email { get; set; }
    
    public string PersonName { get; set; }
    
    public int RoleCount { get; set; }
    
    public ICollection<Role> UserRoles { get; set; }
    
    public void ConfigureMapping(Profile configuration)
    {
        configuration.CreateMap<AppUser, TestMappingVm>()
                     .ForMember(p => p.PersonName, p => p.MapFrom(q => q.FirstName + " " + q.LastName))
                     .ForMember(p => p.RoleCount, p => p.MapFrom(q => q.UserRoles.Count))
                     .ForMember(p => p.UserRoles, p => p.MapFrom(q => q.UserRoles.Select(m => m.Role)));
    }

}

                

In the service, you are able to use "ConvertTo" for mapping process
            
public IEnumerable<TestMappingVm> GetTestMappingVms()
{
    var query = GetAll().Where(p => p.IsActive);
    
    return query
           .ConvertTo<TestMappingVm>(MapperInstance)
           .ToList();
}


IMapFrom in youtube More videos

IMapFrom in youtube More videos

ProjectTo


In service, you are able to use "ProjectTo" for mapping process

            
public IEnumerable<TestMappingVm> GetTestMappingVms()
{
    var query = GetAll().Where(p => p.IsActive);
    
    return MapperInstance
               .ProjectTo<TestMappingVm>(query)
               .ToList();
}


ProjectTo in youtube More videos

ProjectTo in youtube More videos

IHaveCustomMappings

In the IHaveCustomMappings model, not only fields with the same name, but also each field of the source model can be mapped to the Linq commands. In this case, your map includes configuration, which is performed at the bottom of the model. This method is very flexible. Anything that can be written with the Linq commands for an entity can be written with this type of mapping. Below is a mapping example that maps an object from AppUser to AppUserDto. In addition, access levels and roles are mapped. In the reporting section, we will use complex mapping for reporting.


            
public class AppUserDto : BaseEntityDto<long>, IHaveCustomMappings
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string UserName { get; set; }

    public string FullName => $"{FirstName} {LastName}";

    public string Password { get; set; }

    public string Phone { get; set; }

    public string Email { get; set; }

    public bool IsActive { get; set; }

    public virtual ICollection<UserRole> UserRoles { get; set; }
    
    public void ConfigureMapping(Profile configuration)
    {
        configuration.CreateMap<AppUser, AppUserDto>()
                     .ForMember(p => p.UserRoles, p => p.MapFrom(q => q.UserRoles));
    }
}

In case of reversing the mapping process from Dto to the Entity, you can use the CreateMap, vice versa, it has shown in the code below:


            
public class AppUserDto : BaseEntityDto<long>, IHaveCustomMappings
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string UserName { get; set; }

    public string FullName => $"{FirstName} {LastName}";

    public string Password { get; set; }

    public string Phone { get; set; }

    public string Email { get; set; }

    public bool IsActive { get; set; }

    public virtual ICollection<UserRole> UserRoles { get; set; }
    
    public void ConfigureMapping(Profile configuration)
    {
        configuration.CreateMap<AppUser, AppUserDto>()
                     .ForMember(p => p.UserRoles, p => p.MapFrom(q => q.UserRoles));

       configuration.CreateMap<AppUserDto, AppUser>()
    }

}


IHaveCustomMappings in youtube More videos

IHaveCustomMappings in youtube More videos