Reputation: 1546
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 tenant
object 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??
Upvotes: 3
Views: 2569
Reputation: 1546
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!
Upvotes: 3