MVC, EF - Одноэлементный экземпляр DataContext Per-Web-Request в Unity

У меня есть веб-приложение MVC 3, в котором я использую Entity Framework для доступа к данным. Кроме того, я просто использовал шаблон репозитория, где, например, все, что связано с Продуктом, обрабатывается в "ProductRepository", а все, что связано с пользователем, обрабатывается в "UserRepository".

Таким образом, я использую контейнер UNITY, чтобы создать одноэлементный экземпляр DataContext, который я вставляю в каждый из репозиториев. Быстрый поиск в Google, и все рекомендуют НЕ использовать одноэлементный экземпляр DataContext, так как это может привести к некоторым утечкам памяти в будущем.

Итак, вдохновленный этим сообщением, создание одноэлементного экземпляра DataContext для каждого веб-запроса является ответом (пожалуйста, поправьте меня, если я ошибаюсь!)

http://blogs.microsoft.co.il/blogs /gilf/archive/2010/05/18/how-to-manage-objectcontext-per-request-in-asp-net.aspx

Однако UNITY не поддерживает диспетчер времени жизни "Per-web-request". Но можно реализовать свой собственный диспетчер времени жизни, который сделает это за вас. Собственно, это обсуждается в этом посте:

Singleton Per Call Context (Web Request) в Unity

Вопрос в том, Я реализовал собственный менеджер времени жизни, как описано в сообщении выше, но я не уверен, что это способ сделать это. Мне также интересно, где находится экземпляр datacontext в предоставленном решении? Я что-то упускаю?

Есть ли на самом деле лучший способ решить мою «проблему»?

Спасибо!

** Добавлена ​​информация о моей реализации **

Ниже приведены фрагменты из моего Global. asax, Контроллер и Репозиторий. Это дает четкое представление о моей реализации.

Global.asax

  var container = new UnityContainer();
            container
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(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();
}

Завод контроллера

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;
    }

}

Дополнительная информация Мне также интересно, где находится экземпляр datacontext в предоставленном решении? Я что-то упускаю?

Есть ли на самом деле лучший способ решить мою «проблему»?

Спасибо!

** Добавлена ​​информация о моей реализации **

Ниже приведены фрагменты из моего Global. asax, Контроллер и Репозиторий. Это дает четкое представление о моей реализации.

Global.asax

  var container = new UnityContainer();
            container
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(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();
}

Завод контроллера

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;
    }

}

Дополнительная информация Мне также интересно, где находится экземпляр datacontext в предоставленном решении? Я что-то упускаю?

Есть ли на самом деле лучший способ решить мою «проблему»?

Спасибо!

** Добавлена ​​информация о моей реализации **

Ниже приведены фрагменты из моего Global. asax, Контроллер и Репозиторий. Это дает четкое представление о моей реализации.

Global.asax

  var container = new UnityContainer();
            container
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(new ContainerControlledLifetimeManager())
                .RegisterType(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();
}

Завод контроллера

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;
    }

}

Дополнительная информация Привет, я опубликую дополнительные ссылки, с которыми я столкнулся, относительно связанных проблем и предложений по их решению:

  1. http://cgeers.wordpress.com/2009/02/21/entity-framework-objectcontext/#objectcontext
  2. http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
  3. присоединение linq к sql datacontext к httpcontext в бизнес-уровень
  4. http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
  5. http : //msdn.microsoft.com/en-us/library/bb738470.aspx

49
задан Community 23 May 2017 в 02:34
поделиться