What is Automapper in C# and How to Use It with real world example

Simplify Object-to-Object Mapping with AutoMapper in C#

Mapping objects between different data models or transferring data from one object to another can be a tedious and error-prone task in C#. Fortunately, there’s a powerful library called AutoMapper that simplifies this process by automating the mapping between objects. In this blog post, we’ll explore the features and usage of AutoMapper with a complete example.

  1. What is AutoMapper?
  2. Installing AutoMapper
  3. Basic Mapping Example
  4. Mapping Configurations
  5. Handling Complex Mappings
  6. Custom Mapping
  7. Conclusion

What is AutoMapper?

AutoMapper is an open-source object-to-object mapping library for .NET. It eliminates the need for writing repetitive and error-prone mapping code by providing a simple and flexible way to configure and execute object mappings. It can be used to map between classes, properties, or even complex data structures.

Installing AutoMapper:

To get started, you’ll need to install the AutoMapper package from NuGet. Open your project in Visual Studio, right-click on the project name in the Solution Explorer, and select “Manage NuGet Packages.” Search for “AutoMapper” and click “Install” to add the package to your project.

Are you tired of manually mapping properties between objects in your console application? AutoMapper is here to simplify the process for you. In this section, we’ll explore how to configure and use AutoMapper in a console app, allowing you to effortlessly map objects between different types.

To get started, follow these steps:

  1. Install AutoMapper: Begin by installing the AutoMapper NuGet package in your console application project.

  2. Define your classes: Create the source and destination classes that you want to map. For example, let’s say we have a Customer class with FirstName and LastName properties, and a CustomerDto class with a FullName property.

  3. Configure AutoMapper: Initialize AutoMapper by creating a mapping configuration. In a separate method, such as InitializeAutomapper, use the MapperConfiguration class to define the mapping configuration. Specify the mapping between the source and destination classes using CreateMap. You can also customize the mapping for specific properties using ForMember.

  4. Obtain an IMapper instance: Within the InitializeAutomapper method, call CreateMapper on the MapperConfiguration object to obtain an IMapper instance. This instance will be used to perform the object mapping.

  5. Use the IMapper instance: Back in your Main method, use the IMapper instance to map objects. Create an instance of your source class, populate its properties, and then call mapper.Map<DestinationClass>(sourceObject) to map it to the destination class. AutoMapper will automatically map the corresponding properties based on the configuration you defined.

By following these steps, you can easily configure and utilize AutoMapper to simplify object mapping tasks in your console application. It’s a powerful tool that saves you time and effort, allowing you to focus on other aspects of your application’s logic.

Next, we’ll explore some common scenarios and advanced features of AutoMapper that can further enhance your object mapping experience.

Remember to include the necessary using statements for AutoMapper and the classes you’re working with, and ensure that you have the AutoMapper package installed.

Basic Mapping Example:

Let’s start with a simple example to understand how AutoMapper works. Suppose we have two classes: Customer and CustomerDto. Our goal is to map properties from the Customer class to the corresponding properties in the CustomerDto class.

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class CustomerDto
{
    public string FullName { get; set; }
    public int Age { get; set; }
}

To perform the mapping, we’ll need to create a mapping configuration. In your application startup or initialization code, add the following configuration:

using AutoMapper
void Main()
{

}
private static IMapper InitializeAutomapper()
{
	var config = new MapperConfiguration(cfg =>
		{
			cfg.CreateMap<Customer, CustomerDto>()
		.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));
		});

	var mapper = config.CreateMapper();
	return mapper;
}

In the above configuration, we specify how to map properties between the Customer and CustomerDto classes. We use the CreateMap method to define the mapping, and ForMember to customize the mapping for specific properties. In this case, we concatenate the FirstName and LastName properties of Customer into the FullName property of CustomerDto.

Now, let’s use the mapper to perform the mapping:

void Main()
{
	var customer = new Customer
	{
		FirstName = "John",
		LastName = "Doe",
		Age = 30
	};

	var mapper=InitializeAutomapper();
	var customerDto = mapper.Map<CustomerDto>(customer);
	Console.WriteLine(customerDto);

}

After executing the above code, the customerDto object will contain the mapped values from the customer object.

Mapping Configurations:

AutoMapper provides various configuration options to handle different mapping scenarios. Some of the commonly used configurations include:

Ignoring properties:

You can ignore specific properties during mapping using the Ignore method.

cfg.CreateMap<Customer, CustomerDto>()
    .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"))
    .ForMember(dest => dest.Age, opt => opt.Ignore());

Mapping collections:

To map collections using AutoMapper, you need to map the individual types (Customer and CustomerDto) and then use the ProjectTo method to perform the mapping for the collection.

 cfg.CreateMap<Customer, CustomerDto>()
                .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));();
    public static void Main()
    {
        var mapper = InitializeAutomapper();

        // Create a list of customer objects
        var customers = new List<Customer>
        {
            new Customer { FirstName = "John", LastName = "Doe", Age = 30 },
            new Customer { FirstName = "Jane", LastName = "Smith", Age = 25 }
        };

        // Map the list of customers to a list of customer DTOs
        var customerDtos = customers.AsQueryable().ProjectTo<CustomerDto>(mapper.ConfigurationProvider).ToList();

        // Display the mapped data for each customer DTO
        foreach (var customerDto in customerDtos)
        {
            Console.WriteLine($"Full Name: {customerDto.FullName}");
            Console.WriteLine($"Age: {customerDto.Age}");
            Console.WriteLine();
        }
    }

Flattening objects:

AutoMapper can flatten complex object hierarchies into a single level.

cfg.CreateMap<Order, OrderDto>()
    .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer.Name));
void Main()
{
	// Example usage
	var order = new Order
	{
		Customer = new Customer { Name = "John Doe" }
	};
	var mapper=InitializeAutomapper();
	var orderDto = mapper.Map<OrderDto>(order);

	Console.WriteLine($"Customer Name: {orderDto.CustomerName}"); //Customer Name: John Doe

}

Handling Complex Mappings:

AutoMapper can handle complex mappings involving nested objects and different property names. Let’s consider an example where we have a Product class and a ProductViewModel class, and we want to map between them.

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public Category Category { get; set; }
}

public class ProductViewModel
{
    public string ProductName { get; set; }
    public decimal ProductPrice { get; set; }
    public string CategoryName { get; set; }
}

We can define the mapping configuration as follows:

cfg.CreateMap<Product, ProductViewModel>()
    .ForMember(dest => dest.ProductName, opt => opt.MapFrom(src => src.Name))
    .ForMember(dest => dest.ProductPrice, opt => opt.MapFrom(src => src.Price))
    .ForMember(dest => dest.CategoryName, opt => opt.MapFrom(src => src.Category.Name));
void Main()
{

	var prodcut = new Product()
	{

		Category = new Category
		{
			CategoryName = "Cato01"
		},
		Name = "P001",
		Price = 12
	};
	var mapper=InitializeAutomapper();

	var productViewModel = mapper.Map<ProductViewModel>(prodcut);
	Console.WriteLine(productViewModel);


}

Now, when we map a Product object to a ProductViewModel object, AutoMapper will automatically handle the mapping of nested objects and properties with different names.

Custom Mapping:

In some cases, you may need to perform custom mapping logic that cannot be achieved through simple property assignments. AutoMapper allows you to define custom mapping functions using the ConvertUsing method.

cfg.CreateMap<DateTime, string>().ConvertUsing(dt => dt.ToString("yyyy-MM-dd"));
void Main()
{

	var mapper = InitializeAutomapper();
	var dateOnly = mapper.Map<string>(DateTime.Now);

	Console.WriteLine(dateOnly);
}

In the above example, we convert a DateTime object to a string in a specific format by providing a custom mapping function.

Conclusion:

AutoMapper is a powerful tool that simplifies the process of object-to-object mapping in C#. It helps reduce manual mapping code and improves productivity. In this blog post, we explored the basics of AutoMapper, including installation, basic mapping, mapping configurations, handling complex mappings, and custom mapping.

By leveraging AutoMapper in your projects, you can save time and effort in mapping data between different models, making your code more concise and maintainable.

Next Post Previous Post
No Comment
Add Comment
comment url