У меня есть веб-приложение MVC 3, где я использую Entity Framework для доступа к данным. Кроме того, я сделал простое использование шаблона репозитория, где, например, все связанные с продуктом материалы обрабатываются в "ProductRepository", и все связанные с пользователем материалы обрабатываются в "UserRepository".
Таким образом, я использую контейнер UNITY, чтобы создать один экземпляр DataContext, который я вставляю в каждый из репозиториев. Быстрый поиск в Google, и все рекомендуют НЕ использовать один экземпляр DataContext, так как это может дать вам некоторые утечки памяти в будущем.
Итак, вдохновленный этим сообщением, один экземпляр DataContext для каждого веб-запроса является ответом (пожалуйста, поправьте меня, если я ошибаюсь!)
Однако UNITY не поддерживает менеджер жизненного цикла "Per-web-request". Но вы можете реализовать собственный менеджер времени жизни, который обрабатывает это для вас. Собственно, об этом говорится в этом сообщении:
Контекст Singleton Per Call (веб-запрос) в Unity
Вопрос в том, что я теперь внедрил пользовательский менеджер времени жизни, как описано выше, но я не уверен, что это способ сделать это. Мне также интересно, где экземпляр datacontext находится в предоставленном решении? Я что-то упускаю?
Есть ли лучший способ решить мою проблему?
Спасибо!
** Добавлена информация о моей реализации **
Ниже приведены фрагменты из моего Global.asax, Controller и Repository. Это дает ясную картину моей реализации.
Global.asax
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>(new ContainerControlledLifetimeManager())
.RegisterType<CategoryRepository>(new ContainerControlledLifetimeManager())
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString)
Контроллер
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();
}
Репозиторий продуктов
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
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;
}
}
Дополнительная информация Привет, я опубликую дополнительные ссылки, которые мне встречаются, относительно соответствующих вопросов и решений:
- http://cgeers.wordpress.com/2009/02/21/entity-framework-objectcontext/#objectcontext
- http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
- привязка linq к sql datacontext к httpcontext в бизнес-уровне
- http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
- http://msdn.microsoft.com/en-us/library/bb738470.aspx