I have an MVC 3 web application where I use the Entity Framework to access data. In addition, I made a simple use of the repository template, where, for example, all product-related materials are processed in the "ProductRepository", and all user-related materials are processed in the "UserRepository".
Thus, I use the UNITY container to create one instance of the DataContext, which I insert into each of the repositories. A quick google search and everyone recommends NOT using a single instance of the DataContext, as this may give you some memory leaks in the future.
So, inspired by this post, one instance of the DataContext for each web request is the answer (please correct me if I am wrong!)
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/05/18/how-to-manage-objectcontext-per-request-in-asp-net.aspx
However, UNITY does not support the Per-web-request lifecycle manager. But you can implement your own lifetime manager that handles this for you. Actually, this message says:
Singleton Per Call context (web request) in Unity
The question is, I have now implemented a user-defined lifetime manager, as described above, but I'm not sure if this is the way to do this. I also wonder where the datacontext instance is in the provided solution? Am I missing something?
Is there a better way to solve my problem?
Thank!
** Added information about my implementation **
Below are snippets from my Global.asax, Controller, and Repository. This gives a clear picture of my implementation.
Global.asax
var container = new UnityContainer(); container .RegisterType<ProductsRepository>(new ContainerControlledLifetimeManager()) .RegisterType<CategoryRepository>(new ContainerControlledLifetimeManager()) .RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString)
Controller
private ProductsRepository _productsRepository; private CategoryRepository _categoryRepository; public ProductsController(ProductsRepository productsRepository, CategoryRepository categoryRepository) { _productsRepository = productsRepository; _categoryRepository = categoryRepository; } public ActionResult Index() { ProductCategory category = _categoryRepository.GetProductCategory(categoryId); . . . } protected override void Dispose(bool disposing) { base.Dispose(disposing); _productsRepository.Dispose(); _categoryRepository.Dispose(); }
Product Repository
public class ProductsRepository : IDisposable { private MyEntities _db; public ProductsRepository(MyEntities db) { _db = db; } public Product GetProduct(Guid productId) { return _db.Product.Where(x => x.ID == productId).FirstOrDefault(); } public void Dispose() { this._db.Dispose(); }
Factory Controller
public class UnityControllerFactory : DefaultControllerFactory { IUnityContainer _container; public UnityControllerFactory(IUnityContainer container) { _container = container; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (controllerType == null) { throw new HttpException(404, String.Format("The controller for path '{0}' could not be found" + "or it does not implement IController.", requestContext.HttpContext.Request.Path)); } return _container.Resolve(controllerType) as IController; } }
Additional Information Hi, I will post additional links that I come across regarding relevant issues and solutions: