I'm using Automapper in my MVC 5 app to auto map my Entity Framework entities. Some of the mappings need to be looked up, so I need to inject them in the AutoMapperConfig. I use PerRequestLifetimeManager. To do the injection I've setup Unity in Appliction_BeginRequest the following lines:
Mapper.Initialize(cfg => cfg.ConstructServicesUsing(type => UnityConfig.GetConfiguredContainer().Resolve(type)));
var UnityContainer = UnityConfig.GetConfiguredContainer();
UnityContainer.Resolve<AutoMapperConfig>().MapAutoMapper();
But strangely after a few requests (hit F5 several times) the app breaks on Mapper.AssertConfigurationIsValid(); with the error message:
AutoMapper.AutoMapperConfigurationException was unhandled by user code HResult=-2146233088 Message= Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type ======================================================================= IssueDTO -> Issue (Destination member list) Improveize.Classes.DTO.IssueDTO -> Improveize.Classes.Persistent.Issue (Destination member list) ----------------------------------------------------------------------- CreatedBy
But the member mentioned (CreatedBy) is mapped correctly in my code. FYI: the specific mapping makes use of a repository to lookup the data.
The relevant part of the AutoMapperConfig mapping that seems to generate the issue:
Mapper.CreateMap<IssueDTO, Issue>()
.ForMember(dest => dest.CreatedBy,
opt => opt.MapFrom(
src => _UserRepository.Get(u => u.UserID == src.CreatedByID).FirstOrDefault()));
So I thought this would have anything to do, that Automapper is initialized too often (every request) so I've put the Mapper.Initialize..... line in Application_Start. But strangly (at least to me) I get the following error message when I want so save the data of a partial view through an Ajax call to the webapi part of the app.
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
It breaks on the following lines in my DBContext when I want to set the EntityState to Modified:
public new virtual DbEntityEntry Entry(object obj)
{
return base.Entry(obj);
}
So apperantly the mapping resolved by a repository gets another DBContext. (if I ignore the properties that need a lookup, 'everything' works fine)
So it is Obvious that I'm doing something wrong, but I do not know what. The questions that arise:
- where to put Mapper.Initialize(cfg => cfg.ConstructServicesUsing(type => UnityConfig.GetConfiguredContainer().Resolve(type))); ?? In which class to put in in?
- can the context issue have anything to do with the web app is using MVC 5 and Webapi 2.0? Do they generate different dbcontext? And how can I avoid this.
- where is the AutoMapper error coming from (it looks like the wrong message to me)? And how to solve
EDIT to answer the questions of Gert Arnold:
- DbEntityEntry method breaks my DBContext
- it breaks when I want to set the EntityState to Modified, called in the update action of the repository
- Since I use PerRequestLifeTimeManager I assume the lifetime of _UserRepository.Get to be the lifespan of the request. I'm doing nothing explicitly to dispose the context nor the repository.
Application_Startis the right place. The rest is hard to tell without more details. What is the lifespan of_UserRepository.Get? Where does thisEntrymethod run? Where is it called?_UserRepository.Get()creates a new DbContext, so the row returned from this call uses a different DbContext than what you are assigning it to. It's hard to tell, though, since you don't include any of that code...