DEV Community

Diógenes Polanco
Diógenes Polanco

Posted on

16 8

the new features of AutoMapper in .net

Table Of Contents

    * [What is Automapper?](#Automapper)
    * [New features](#Features)
    * [Installation](#Installation)
    * [How to Use Automapper?](#AutomapperApplication) 
Enter fullscreen mode Exit fullscreen mode

What is Automapper?

AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper’s established convention, almost zero configuration is needed to map two types.

New features

    * Remove static API
Enter fullscreen mode Exit fullscreen mode
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Dest>();
});
var source = new Source();
var dest = Mapper.Map<Source, Dest>(source);



the way to do it now is:

var config = new MapperConfiguration(cfg => {
cfg.CreateMap<Source, Dest>();
});
IMapper mapper = config.CreateMapper();
var source = new Source();
var dest = mapper.Map<Source, Dest>(source);



* Remove dynamic maps

public class Dto
{
public string UserName { get; set; }
}
public class user
{
public string UserName { get; set; }
public string Email { get; set; }
}
var dto = new Dto { UserName = "test" };
var sample = _mapper.Map<Sample>(Dto);
// <---If unmapped, here will throw AutoMapperConfigurationException.



the way to do it now is:

var cfg = new MapperConfigurationExpression();
cfg.CreateMap<Entities.User, Dtos.User>();
cfg.AddProfile<UserMapperProfile>();
var mapperConfig = new MapperConfiguration(cfg);
IMapper mapper = new Mapper(mapperConfig);



* Update Conditional Mapping

class Foo{
public int baz;
}
class Bar {
public uint baz;
}
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Foo,Bar>()
.ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0)));
});
//OR
/*Use Preconditions
Similarly, there is a PreCondition method.
The difference is that it runs sooner in the mapping process, before the source value is resolved (think MapFrom).
So the precondition is called, then we decide which will be the source of the mapping (resolving),
then the condition is called and finally the destination value is assigned.
*/
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Foo,Bar>()
.ForMember(dest => dest.baz, opt => {
opt.PreCondition(src => (src.baz >= 0));
opt.MapFrom(src => {
// Expensive resolution proccess that can be avoided with a PreCondition
});
});
});



* Help the runtime find the AM assembly

//In order to search for maps to configure, use the AddMaps method:
var configuration = new MapperConfiguration(cfg => cfg.AddMaps("MyAssembly"));
var mapper = new Mapper(configuration);
//AddMaps looks for fluent map configuration (Profile classes) and attribute-based mappings.
//To declare an attribute map, decorate your destination type with the AutoMapAttribute:
[AutoMap(typeof(Order))]
public class OrderDto {
// destination members
//This is equivalent to a CreateMap<Order, OrderDto>() configuration.
    * Match destination enumerable types with it's enumerable for LINQ
Enter fullscreen mode Exit fullscreen mode
/*
When using an ORM such as NHibernate or Entity Framework with AutoMapper’s standard mapper.Map functions,
you may notice that the ORM will query all the fields of all the objects
within a graph when AutoMapper is attempting to map the results to a destination type.
If your ORM exposes IQueryables, you can use AutoMapper’s QueryableExtensions helper methods to address this key pain.
*/
public class OrderLine
{
public int Id { get; set; }
public int OrderId { get; set; }
public Item Item { get; set; }
public decimal Quantity { get; set; }
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
public class OrderLineDTO
{
public int Id { get; set; }
public int OrderId { get; set; }
public string Item { get; set; }
public decimal Quantity { get; set; }
}
var configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<OrderLine, OrderLineDTO>()
.ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name)));
public List<OrderLineDTO> GetLinesForOrder(int orderId)
{
using (var context = new orderEntities())
{
return context.OrderLines.Where(ol => ol.OrderId == orderId)
.ProjectTo<OrderLineDTO>().ToList();
}
}
/*
Supported mapping options
Not all mapping options can be supported, as the expression generated must be interpreted by a LINQ provider.
Only what is supported by LINQ providers is supported by AutoMapper:
MapFrom (Expression-based)
ConvertUsing (Expression-based)
Ignore
NullSubstitute
Not supported:
Condition
SetMappingOrder
UseDestinationValue
MapFrom (Func-based)
Before/AfterMap
Custom resolvers
Custom type converters
ForPath
Any calculated property on your domain object
*/

Installation

The first step is to install the corresponding NuGet package:

dotnet add package AutoMapper --version 9.0.0   
Enter fullscreen mode Exit fullscreen mode

Now, what is the way to Use Automapper?

using System;
using AutoMapper;
using AutoMapperDemo.Mappers;
namespace AutoMapperDemo
{
class Program
{
static void Main(string[] args)
{
var configuration = new MapperConfiguration(cfg => cfg.AddMaps("AutoMapperDemo"));
var mapper = new Mapper(configuration);
var entityUser = new Entities.User()
{
Name = "userEntity",
Age = 18,
//Birthdate = new DateTime(1991, 1, 1)
};
//// AutoMapper
var dtoUser2 = mapper.Map<Dtos.User>(entityUser);
var entityUser2 = mapper.Map<Entities.User>(dtoUser2);
//// AutoMapper
var dtoUser3 = entityUser.ToDto();
var entityUser3 = dtoUser3.ToEntity();
Console.WriteLine("Hello World!");
}
}
}

You can clone my code!

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (2)

Collapse
 
mincasoft profile image
mincasoft

How to register as singleton in real app .NET Framework, such as WPF

Collapse
 
diogenespolanco profile image
Diógenes Polanco

Well this article does not talk about patterns but if you need to use Singleton in .net I recommend using this autofaccn.readthedocs.io/en/latest... package that will help you implement dependency injection.

You can install it from nuget:
dotnet add package Autofac

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay