5

最近我开始深入研究存储库模式和 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();
}

我怎样才能安全地实现这一目标,我是否走在正确的轨道上?

4

2 回答 2

3

首先:不要发明轮子。

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

您的UoW应该从Web 请求的开始开始,并在请求结束时处理

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

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

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

于 2012-06-27T14:51:38.860 回答
1

你应该把你的软件分成层和组件......

UI --> 控制器 --> 服务 --> DAL

例如

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

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

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 的限制和最佳实践。

我还建议不要使用纯学术型 repository-per-base-type 模式,因为通常要有效地使用来自同一域的不同类型的数据,需要跨“存储库”查询和 LINQ 中的 requirejoin子句,或者多个查询的结果是组合在一起并在将其作为一个干净的结果返回之前对其进行重塑。

而是将您的服务视为域特定存储库,您可以在其中获得各种类型的输出。或者换句话说,在 MVC 下和 EF 上使用 SOA。

于 2012-06-29T11:49:25.100 回答