I have a problem with Automapper when I try use custom resolver which uses dependency injection.
I have the following model:
public class User : Entity
{
public virtual string Name { get; set; }
public virtual Country Country { get; set; }
}
public class Country : Entity
{
public virtual string Name { get; set; }
}
and the following view model:
public class RegistrationViewModel
{
[Required]
public string Name { get; set; }
public int CountryId { get; set; }
public IEnumerable<Country> Countries { get; set; }
}
in order to map I use the following code:
Mapper.Map(registrationViewModel, user);
earlier I register the following:
Mapper.Reset();
container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<ISession>().
UsingFactoryMethod(() => NHibernateSessionFactory.RetrieveSession()).
LifeStyle.Is(LifestyleType.Transient));
container.Register(Component.For(typeof(LoadingEntityResolver<>)).ImplementedBy(typeof(LoadingEntityResolver<>)).LifeStyle.Transient);
Mapper.Initialize(x =>
{
x.AddProfile<BasicProfile>();
x.ConstructServicesUsing(container.Resolve);
});
My BasicProfile is the following:
public class BasicProfile : Profile
{
public const string VIEW_MODEL = "MyBasicProfile";
public override string ProfileName
{
get { return VIEW_MODEL; }
}
protected override void Configure()
{
CreateMaps();
}
private void CreateMaps()
{
CreateMap<RegistrationViewModel, User>()
.ForMember(dest => dest.Country, _ => _.ResolveUsing<LoadingEntityResolver<Country>>().FromMember(src => src.CountryId))
);
}
}
The custom resolver is done in the following way:
public class LoadingEntityResolver<TEntity> : ValueResolver<int, TEntity>
where TEntity: Entity
{
private readonly ISession _session;
public LoadingEntityResolver(ISession session)
{
_session = session;
}
protected override TEntity ResolveCore(int source)
{
return _session.Load<TEntity>(source);
}
}
When the mapping code is being run I get the following exception:
AutoMapper.AutoMapperMappingException : Trying to map ViewModels.RegistrationViewModel to Models.User. Using mapping configuration for ViewModels.RegistrationViewModel to Models.User Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ----> AutoMapper.AutoMapperMappingException : Trying to map ViewModels.RegistrationViewModel to LModels.Country. Using mapping configuration for ViewModels.RegistrationViewModel to Models.User Destination property: Country Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ----> System.ArgumentException : Type 'Mapping.LoadingEntityResolver`1[Models.Country]' does not have a default constructor
I have no idea what may be wrong. It is probably something with constructing the resolver. When I try the following there is no problem:
var resolver = container.Resolve<LoadingEntityResolver<Country>>();
Assert.IsInstanceOf<LoadingEntityResolver<Country>>(resolver);
I would be greatfull for any help.
Best regards
Lukasz
You have some pretty hefty DI stuff going on here :-) I would avoid having AutoMapper resolve entities from a database or whatever. Makes the code difficult to understand and following objects lifetime could become a nightmare.
Anyway, to fix your problem simply swap the order from (wrong):
Mapper.Initialize(x =>
{
x.AddProfile<BasicProfile>();
x.ConstructServicesUsing(container.Resolve);
});
to (correct):
Mapper.Initialize(x =>
{
x.ConstructServicesUsing(container.Resolve);
x.AddProfile<BasicProfile>();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With