dimanche 8 octobre 2017

Dynamic class mapping with AutoMapper

I am creating an utility class using AutoMapper 4.2.1. My goal is to use this class in my project to map DataModel & DTO classes.

DataModel Class:

public class UserModel
{
    public UserModel()
    {
        UserAdresses = new List<UserAddressModel>();
    }

    public string UserId { get; set; }
    public string UserName { get; set; }

    public IList<UserAddressModel> UserAdresses { get; set; }
}

DTO Class:

public class UserDTO
{
    public UserDTO()
    {
        UserAdresses = new List<UserAddressDTO>();
    }

    public string UserId { get; set; }
    public string UserName { get; set; }

    public IList<UserAddressDTO> UserAdresses { get; set; }
}

List Class:

public class UserAddressModel/UserAddressDTO -- Based on the usage
{
    public string AddressType { get; set; }
    public string Address { get; set; }
}

AutoMapperUtility Class:

public static D ModelDTOMapper<S, D>(S sourceClass, D destinationClass)
    {
        try
        {
            object sourceInstance = GetListClass(sourceClass);
            object destinationInstance = GetListClass(destinationClass);

            if (sourceInstance != null && destinationInstance != null)
            {
                InitializeAutomapper(sourceInstance, destinationInstance);
            }

            InitializeAutomapper(sourceClass, destinationClass);

            destinationClass = Mapper.Map<D>(sourceClass);

            return destinationClass;
        }
        catch (Exception exception)
        {
            throw exception;
        }
    }

    private static object GetListClass<S>(S sourceListClass)
    {
        Type type = (typeof(S));
        object instance = null;

        PropertyInfo[] arrType = type.GetProperties();

        foreach (var item in arrType)
        {
            if (item.PropertyType.FullName.Contains("System.Collections.Generic.IList") || item.PropertyType.FullName.Contains("System.Collections.Generic.List"))
            {
                string listClass = item.PropertyType.GetProperties()[0].PropertyType.FullName;
                Type className = Type.GetType(listClass);

                instance = Activator.CreateInstance(className);
            }
        }

        return instance;
    }

    private static void InitializeAutomapper<S, D>(S sourceClass, D destinationClass)
    {
        Mapper.CreateMap<S, D>();
    }
}

On invoking the Map method in destinationClass = Mapper.Map(sourceClass); I am getting the below exception:

Exception: Mapping types: Object -> Object System.Object -> System.Object

Destination path: UserDTO.UserId.UserId

Source value: USER001

Inner Exception: Unable to cast object of type 'System.Object' to type 'System.String'.

This exception is occurring because the GetListClass method is returning an object instance of type object rather than instance of the type of the actual List Class (UserAddressModel/UserAddressDTO).

How can I convert this object instance type to the type of the List Class..?





Aucun commentaire:

Enregistrer un commentaire