EF,UoW和Repository - 何时在WebForms中部署UnitOfWork?

时间:2012-06-27 09:59:41

标签: asp.net entity-framework repository-pattern dispose unit-of-work

最近,我开始深入研究Repository Patterns和UnitOfWork的概念,并探索EntityFramework。

基于MVC示例制作了我自己的实现,他们从Controller中处理UnitOfWork,如下所示:

protected override void Dispose(bool disposing)
{
    unitOfWork.Dispose(); 
    base.Dispose(disposing);
}

我根本没有进入MVC,也不是Webforms中的新手,但我认为他们正在重写Controller dispose方法,以便将UnitOfWork处理为“其他所有内容”。

基本上我想在我的ASP.NET WebForms网站中实现相同的概念,并将页面代码后面使用的UnitOfWork与处理页面本身一起处理。

我考虑过从生命周期中添加相同的 Page_Unload 事件,但我不确定这是否是正确的方法,因为我之前没有搞过这些事情。我的想法如下:

protected void Page_Unload(object sender, EventArgs e)
{
    unitOfWork.Dispose();
    base.Dispose();
}

我如何安全地实现这一目标,我是否走在正确的轨道上?

2 个答案:

答案 0 :(得分:4)

首先:不要发明轮子。

使用依赖注入框架,例如: StructureMap,Ninject,Unity等......

您的 UoW 应该在请求开始时启动 请求

换句话说:EF的DataContext应该在请求启动时初始化。然后你可以将它存储在某个地方(Session,...),它可以被重用于该请求。 每个请求的一个DataContext实例。

但是如果你自己尝试这样做,那么你使用依赖注入框架就会出错,会让它变得如此简单。

框架可以处理DataContext的生命周期(UoW)。

答案 1 :(得分:2)

您应该将软件划分为图层和组件......

用户界面 - >控制器 - >服务 - > DAL

E.g。

UI.Submit - > Controller.SaveUserInfo - > UsersManagementService.SaveUserInfo - >

public void SaveUserInfo(User user)
{
    using (var uow = new Uow())
    {
        var dbUser = uow.Users.GetByKey(user.Id);
        if (dbUser == null)
        {
            // TODO:
        }

        dbUser.Name = user.Name;
        dbUser.Address = user.Address;
        // Or use a framework for injecting properties

        uow.SaveAndAcceptChanges();
    }
}

您甚至可以在certiain服务方法中接收查询逻辑,例如

public User GetUsersMatching(Func<IQueryable<User>, IQueryable<User>> query)
{
    using (var uow = new Uow())
    {
        var users = query(uow.Users).ToList();
        return users;

        // For this to work using POCOs you may need to disable proxy creation
    }
}

但是,这使得测试变得更加复杂,并且要求服务的消费者理解LINQ to Entities的限制和最佳实践。

我还建议不要使用纯学术存储库 - 每个基础类型模式,因为有效经常使用来自相同域需要交叉的不同类型的数据存储库“在LINQ中查询并要求join子句,或者将多个查询的结果组合在一起并重新整形,然后将其作为一个干净的结果返回。

相反,将您的服务视为domain-speicifc-repositories,您可以在其中获得各种类型的输出。或者换句话说,在您的MVC下使用SOA并在您的EF之上。