Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Deep Copy Using AutoMapper

0.00/5 (No votes)
19 Jun 2016 1  
Deep copy an Object using AutoMapper. AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another

Introduction

I search through the web to find out Deep Copy of a complex object and found out three ways of doing it.

  1. Serialization
  2. Implementing ICloneable interface
  3. Using Reflection

As the Complex Object I was trying to clone was used by the entire team, I was not supposed to make any changes to it. 1 & 2 did not work for me. Did not wanted to go for reflection. Hence, I used Auto Mapper to Deep Copy an object.

Background

In the application, we had product information for eight languages. Some of the fields needed to be taken from English language and other fields had to be taken from respective product of international language. Hence, a class was written to map the translatable properties and create an international language product. Now when one by one we added the product to a Product List, it was replacing all the previous language products with the last product that we added. (Complex types are passed as reference). Hence, I used Automapper to achieve what was needed.

What is Automapper?

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. For more information, please visit this link.

Using the Code

Please add the nuget for AutoMapper in your application.

I had a complex class Product which is as below:

using System;
using System.Collections.Generic;
 
namespace DeepCloneWithAutoMapper.Models
{
    [Serializable]
    public class Product
    {
        public bool IsAvailable { get; set; }
 
        public string Language { get; set; }
 
        public int ProductId { get; set; }
 
        public List<int> VariantIds { get; set; }
 
        public List<int> SiteIds { get; set; }
 
        public int MerretId { get; set; }
 
        public string Name { get; set; }
 
        public string CareDetails { get; set; }
 
        public string AdditionalCopy { get; set; }
 
        public string FabricConstruction { get; set; }
 
        public string Materials { get; set; }
 
        public string AdditionalInfo { get; set; }
 
        public string Description { get; set; }
 
        public int BrandId { get; set; }
 
        public string BrandName { get; set; }
 
        public string BrandDescription { get; set; }
 
        public string CareInfo { get; set; }
 
        public List<attribute> Attributes { get; set; }
 
        public string DateModified { get; set; }
 
        public string DateCreated { get; set; }
 
        public string BackOfficeDateModified { get; set; }
 
        public string ProductCode { get; set; }
 
        public int CategoryId { get; set; }
 
        public string Category { get; set; }
 
        public int DepartmentId { get; set; }
 
        public string Department { get; set; }
 
        public int DivisionId { get; set; }
 
        public string Division { get; set; }
 
        public int ShippingRestrictionId { get; set; }
 
        public bool IsReturnable { get; set; }
 
        public string TranslatableDataDateChanged { get; set; }
 
        public List<webcategory> WebCategories { get; set; }
 
        public List<associatedproductgroup> AssociatedProductGroups { get; set; }
 
        public int StatusId { get; set; }
    }
}

Though the Product class is Serializable but the Properties Like WebCategories and AssociatedProductGroups were not.

public List WebCategories { get; set; }
public List AssociatedProductGroups { get; set; }

Please find the WebCategory and AssociatedProductGroup classes.

//WebCategory
public class WebCategory
  {
    public int WebCategoryId { get; set; }

  }

// AssociatedProductGroup
public class AssociatedProductGroup
  {
    public int AssociatedProductGroupId { get; set; }
 
    public string Type { get; set; }
  }

I had a method "GetProductForAllLanguage". I wanted all languages products in a List by mapping the translatable properties. I was calling MapTranslatableProperties method to map the translatable properties and create a new product object and then add to a List. But this was replacing all the List products by the last product added. Hence, I used the AutoMapper for deep coping and creating a new object and then adding to the list.

public IEnumerable<Product> GetProductForAllLanguage()
        {
            var testProduct = new TestProduct();
            var productList = new List<Product>();
            productList.Add(testProduct.Product);
            productList.Add(testProduct.InternationalProduct);
            var internationalProduct = testProduct.InternationalProduct;
            internationalProduct.Language = "fr-Fr";
            productList.Add(internationalProduct);
 
            internationalProduct = testProduct.InternationalProduct;
            internationalProduct.Language = "ru-RU";
            productList.Add(internationalProduct);
 
            var feedProductsList = new List<Product>();
            var defaultLanguageProduct =
                productList.FirstOrDefault(p => p.Language == "en-GB");
 
            var otherLanguageProducts = productList.Where(s => s.Language != "en-GB");
            feedProductsList.Add(defaultLanguageProduct);
 
            // this is how we initialize automapper with the same object type. 
            Mapper.Initialize(cfg => { cfg.CreateMap<Product, Product>(); });
            foreach (var product in otherLanguageProducts)
            {
                
                var feedProduct = new Product();
                // map properties to give a new object. 
                feedProduct = Mapper.Map(defaultLanguageProduct, feedProduct);
                feedProduct = MapTranslatableProperties(feedProduct, product);
                feedProductsList.Add(feedProduct);
            }
 
            return feedProductsList;
        }

Points of Interest

I have wasted a huge amount of time searching on the web how to deep copy an object, but found only the above three methods. Just AutoMapper click to my mind and I tried the piece of code here. I played a small trick. Please share your view on this if this helps.

History

  • 17th June, 2016: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here