I'm struggling with Entityframework in a MVC 4 app, making use of Unity for Dependency injection and Automapper for automapping object to DTO. I run from one issue to the other, EF is sometimes returning old data, so I think my design is not good enough.
What do I have:
To configure Unity I have in my Application_Start:
var UnityContainer = UnityConfig.GetConfiguredContainer();
Mapper.Initialize(cfg => cfg.ConstructServicesUsing(type => UnityContainer.Resolve(type)));
UnityContainer.Resolve<AutoMapperConfig>().MapAutoMapper();
...
In UnityConfig.RegisterTypes:
container.RegisterType<IMyContext, MyContext>(new ContainerControlledLifetimeManager())
...
My respositories use constructor depencency injection:
public class MSSQLTenantRepository : IDalTenantRepository
{
private readonly IMyContext _Db;
public MSSQLTenantRepository(IMyContext db)
{
Db = db;
}
...
And my controller use constructor dependency injection too:
public class TenantController : Controller
{
private readonly ITenantRepository _TenantRepository;
public TenantController(ITenantRepository tenantRepository,
{
_TenantRepository = tenantRepository;
}
...
Automapper config:
public class AutoMapperConfig
{
private readonly ITenantRepository _TenantRepository;
public AutoMapperConfig(ITenantRepository tenantRepository)
{
_TenantRepository = tenantRepository;
}
...
Issues: I sometimes get old data, from the first request.
When I manually update the data in de SQL server, EF's returning object don't reflect the changes
When I tried different options I also got error about multiple context (due to Automapper)
My questions:
There is a lot said about this subject, but nothing covers all.
container.RegisterType<IMyContext, MyContext>(
new ContainerControlledLifetimeManager())
This is rather bad, it makes a singleton out of your context. This way not only multiple requests share the same context and you risk concurrency issues but also the memory consumption of such shared context grows without control.
Rather, you would like to have a "per-request" life time, where a new context is established for each separate request:
http://www.wiktorzychla.com/2013/03/unity-and-http-per-request-lifetime.html
public class PerRequestLifetimeManager : LifetimeManager
{
private readonly object key = new object();
public override object GetValue()
{
if (HttpContext.Current != null &&
HttpContext.Current.Items.Contains(key))
return HttpContext.Current.Items[key];
else
return null;
}
public override void RemoveValue()
{
if (HttpContext.Current != null)
HttpContext.Current.Items.Remove(key);
}
public override void SetValue(object newValue)
{
if (HttpContext.Current != null)
HttpContext.Current.Items[key] = newValue;
}
}
and
container.RegisterType<IMyContext, MyContext>(new PerRequestLifetimeManager())
I am not sure what your AutoMapperConfig
class does and why a repository is injected into it. This is a possible another lifetime issue but I need a clarification on that.
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