I've been following Darin's answer to a question I had on slimming down my controllers and I'm running into problems with this IEntityChangeTracker
exception:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Here's my model binder:
public class PostModelBinder : IModelBinder
{
private readonly IPostRepository _repository;
public PostModelBinder(IPostRepository repository)
{
_repository = repository;
}
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
var postIDValue = controllerContext.Controller.ValueProvider.GetValue("postID");
int postID;
if (postIDValue == null || !int.TryParse(postIDValue.AttemptedValue, out postID))
return null;
return _repository.FindPost(postID, filterByPublished: true);
}
}
After this, my custom action filter simply carries out a bit of validation on the post and redirects if the post isn't valid. Up until this point, everything is fine. The error happens in my controller when I try to update the post read count:
public class PostsController : Controller
{
private IPostRepository postRepository;
// snip...
[AutoMap(typeof(Post), typeof(PostViewModel)), HttpGet]
[PostActionFilter]
public ActionResult ShowPost(Post model)
{
postRepository.PostVisited(model);
return View(model);
}
}
I understand IEntityChangeTracker
's complaining because I effectively end up with 2 repositories referencing the same object and that just seems like bad mojo waiting to happen. I know I could push the PostVisited()
call into PostModelBinder
but updating a model doesn't seem like behaviour that belongs there.
Is there another way around this?
Thank you.
From the error, I assume your two
IPostRepository
implementation objects use different Entity Framework object contexts; you can fix this by using the same object context throughout a request.Some DI containers support per-request object lifetimes, otherwise you can lazy-load and store your object context in
HttpContext.Items
and dispose of it at the end of the request, as mentioned in this question.