3

I have an object

public class Tenant : EntityBase
{
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual string CreatorName { get; set; }
    public virtual TenantState State { get; set; }
    public virtual Address Address { get; set; }

    public virtual IList<TenantActivity> Activities { get; set; }
    public virtual IList<AppUser> Users { get; set; }
    public virtual IList<TenantConfig> TenantConfigs { get; set; }

    ....
}

A DTO like so:

public class TenantDto
{
    public Guid Id { get; set; }
    public DateTime CDate { get; set; }
    public string CUser { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string CreatorName { get; set; }
    public TenantState State { get; set; }
    public AddressDto Address { get; set; }
    public List<TenantActivityDto> Activities { get; set; }
    public List<AppUserDto> Users { get; set; }
    public List<TenantConfigDto> TenantConfigs { get; set; }
    ....
}

The class Address is a ValueObject which also has a DTO. I use the following mapping (standard, no special configs)

public class TenantMapperProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Tenant, TenantDto>();
        CreateMap<TenantDto, Tenant>();
    }
}

public class AddressMapperProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Address, AddressDto>();
        CreateMap<AddressDto, Address>();
    }
}

And in my App.xaml.cs I have:

        var mapperConfig = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<TenantMapperProfile>();
            cfg.AddProfile<TenantActivityMapperProfile>();
            cfg.AddProfile<AppUserMapperProfile>();
            cfg.AddProfile<AddressMapperProfile>();
            //cfg.ShouldMapProperty = p => p.SetMethod.IsPrivate || p.GetMethod.IsAssembly;
        });
        Mapper = mapperConfig.CreateMapper();

Then I call it in a service like so:

    public TenantDto CreateTenant(TenantDto tenantDto)
    {
        tenantDto.CreatorName = creatingUserName;
        var tenant = _mapper.Map<Tenant>(tenantDto); 
        tenant = _tenantManagerService.CreateTenant(tenant);//<-- Screenshot made here
        return _mapper.Map<TenantDto>(tenant);
    }

After the first call to mapper I made a screenshot of my debugger window. As you can see the tenantDto instance contains data in the Address object but the tenantobject contains its own data correctly mapped but the nested Address object has only null values! What am I doing wrong here??

EDIT - additional information

calling mapperConfig.AssertConfigurationIsValid(); returns one error:

The following property on Bedisoco.BedInventory.Sys.Models.Entities.Role cannot be mapped: Roles Add a custom mapping expression, ignore, add a custom resolver, or modify the destination type Bedisoco.BedInventory.Sys.Models.Entities.Role.

The Role object is somewhere inside one of the Lists, I think the User object inside the List<AppUser> collection contains itself a list of Role objects. It is not even implemented completely.

Am I wrong assuming that Automapper ignores such things silently??

enter image description here

3
  • Try adding mapperConfig.AssertConfigurationIsValid(); before calling CreateMapper. It should fail if you haven't given automapper enough info. Commented Jul 10, 2016 at 20:31
  • You also need to CreateMap for internal entities like CreateMap<TenantActivity, TenantActivityDto>(); and so on. Commented Jul 11, 2016 at 5:46
  • I did so, I did not paste a dozen profile classes here. I have updated everything and AssertConfigurationIsValid() does NOT throw any exceptions anymore. But my Address object still contains only NULL values after the mapper call. This ends in an exception on the database for fields that do NOT allow NULL values. Commented Jul 11, 2016 at 6:09

1 Answer 1

3

Ok solved it, was my own problem.

Most of my value objects contain a constructor with all fields and a private setter. Private setters are NO problem with Automapper if configured correctly (cfg.ShouldMapProperty = p => p.SetMethod.IsPrivate || p.GetMethod.IsAssembly;).

But VS or ReSharper suggested to make auto properties 'get-only'. This refactoring pleases VS but NOT Automapper!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.