Question

How to map User class to UserModel class using Emit Mapper?

    public class User
    {
        public Guid Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public IList<Role> Roles { get; set; }

        public Company Company { get; set; }        
    }

    public class UserModel
    {
        public Guid Id { get; set; }

        public Guid CompanyId { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }      

        public IList<RoleModel> Roles { get; set; }
}

There several problems:

  • I need to flatten the object such that I will have CompanyId instead of the Company object.
  • Company object has property Id, in the UserModel I have CompanyId which corresponds to the company id, but property names do not match.
  • I need to map List<Role> to List<RoleModel>
Was it helpful?

Solution 2

  • For flattering I was using configuration from the samples in Emit Mapper source files: http://emitmapper.codeplex.com/SourceControl/changeset/view/69894#1192663

  • To make the names to match in Company class should be the field with the name Id

  • For mapping List<Role> to List<RoleModel> I was using custom converter:

    public class EntityListToModelListConverter<TEntity, TModel>
    {
        public List<TModel> Convert(IList<TEntity> from, object state)
        {
            if (from == null)
                return null;
    
            var models = new List<TModel>();
            var mapper = ObjectMapperManager.DefaultInstance.GetMapper<TEntity, TModel>();
    
            for (int i = 0; i < from.Count(); i++)
            {
                models.Add(mapper.Map(from.ElementAt(i)));
            }
    
            return models;
        }
    }
    

    So all together:

     var userMapper = ObjectMapperManager.DefaultInstance.GetMapper<User, UserModel>( 
                 new FlatteringConfig().ConvertGeneric(typeof(IList<>), typeof(IList<>), 
                 new DefaultCustomConverterProvider(typeof(EntityListToModelListConverter<,>))));
    
  • There is a problem, using Flatterning Configuration with Custom converters, check my question: Emit Mapper Flattering with Custom Converters

OTHER TIPS

To get flattened model you could check this example. But it seems that by default it has a convention of having sub class property name as a prefix in the target.

Source

public class SourceObject
{
public SourceSubObject SomeClass { get; set; }
}

public SourceSubObject
{
    public int Age { get; set; }
}

Target

public class Target
{
public int SomeClassAge  { get; set; }
}

Second, one options is to let the default settings copy those properties that it can copy and manually do the rest

var target = ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>().Map(source);
target.CompanyId = target.Company.CompanyId;

Or if you need to reuse the mapping the create custom mapper

Custom mapper

private Target Converter(Source source)
{
   var target = new Target();
   target.CompanyId = source.Company.CompanyId;
   return target;
}

Usage

var mapper = new DefaultMapConfig().ConvertUsing<Source, Target>(Converter);
var target = ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>(mapper).Map(source);

Update

What comes to the Role & RoleModel mapping. It seems that in this case you need to have Deep copy enabled and depending on the class(es) definitions you can either copy it directly or do some custom mapping.

ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>(new DefaultMapConfig().DeepMap<ClassToDeepMap>().DeepMap<ClassToDeepMap>()).Map(source, target);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top