繁体   English   中英

更好的方法是:为DbContext创建自己的包装器或在Controller中使用DbContext

[英]What way is better: make own wrapper for DbContext or use DbContext in Controller

在我的项目中,我使用实体框架7asp.net mvc 6 \\ asp.net 5 我想为自己的模型创建CRUD

我怎样才能做得更好:

  1. 使用控制器中的dbcontext。 在下面的链接作者解释说这种方式更好,但它是否适合控制器?
  2. 制作自己的包装纸。 一些最佳实践写下了什么是最好的自己的存储库。

我不会在其他方面改变ef,所以不要介意,即使有一个强大的连接来访问来自特定实现的数据,我知道在ef7中dbcontext立即实现了工作单元和存储库模式。

您的问题的答案主要是基于意见的。 在许多其他问题得到解答之前,没有人可以明确地说“一种方式比另一种方式更好”。 您项目的规模/范围/预算是多少? 有多少开发人员会参与其中? 它只有(基于视图的)MVC控制器,还是它有(基于数据的)API控制器? 如果是后者,MVC和API动作方法之间会有多少重叠,如果有的话? 是否有任何非网络客户端,如WPF? 您打算如何测试应用程序?

实体框架是一种数据访问层(DAL)工具。 控制器是HTTP客户端请求和响应处理工具。 除非您的应用程序是纯CRUD(这是值得怀疑的),否则当您通过HTTP接收Web请求和使用EF将该请求的数据保存到数据库之间时,您可能需要进行某种业务逻辑处理(字段X是必需的,如果为字段Y提供数据,则还必须为字段Z提供数据等。 因此,如果您直接在控制器中使用EF代码,这意味着您的业务处理逻辑几乎肯定会与控制器一起出现在控制器中。

我们这些在使用.NET开发非平凡应用程序方面具有相当丰富经验的人倾向于发展出一种观点,即由于在实现这样的设计时出现某些困难,控制器中不应存在业务和数据访问逻辑。 例如,当您将web / http请求和响应逻辑以及业务逻辑和数据访问逻辑放入控制器时,您最终必须从控制器操作本身测试所有这些应用程序方面(这明显违反了Single责任原则,如果您关心SOLID设计)。 另外,假设您使用返回视图的控制器开发传统MVC应用程序,然后决定将应用程序扩展到其他客户端,如iOS / android / WPF /或其他不了解MVC视图的客户端。 如果您决定实施一组基于WebAPI数据的辅助控制器操作,那么您将至少在两个位置复制业务和数据访问逻辑。

尽管如此,这并没有决定将控制器中的所有业务和数据访问逻辑保持在比其他设计本质上更“糟糕”的状态。 在设计Web应用程序的体系结构时,您做出的任何决定都将具有优势和劣势。 无论您选择哪条路线,总会有权衡。 将所有应用程序代码保存在控制器中的优点包括降低成本,降低复杂性,从而缩短产品上市时间。 对于非常简单的应用程序来说,过度设计复杂的体系结构是没有意义的。 不幸的是,我个人从未有过开发一个简单的应用程序的乐趣,所以我在“一般意见”的船上,在控制器中保存业务和数据访问代码“可能不是”一个很好的长期设计决策。

如果您真的对替代品感兴趣,我建议您阅读这 两篇文章 它们是关于如何实现控制器可以使用的命令和查询(CQRS)模式的良好入门。 EF确实实现了存储库和开箱即用的工作单元模式,但这并不一定意味着您需要“包装”它以便将数据访问代码移到控制器之外。 祝您的项目做出这些决定。

public async Task<ActionResult> Index() {
    var user = await query.Execute(new UserById(1));
    return View(user);
}

通常我更喜欢使用Repository模式和UnitOfWork模式( http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository - 并且 - asp-net-mvc-application中的工作模式 - 我在UnitOfWork实例对象中实例化DbContext,然后在存储库中注入DbContext。 之后,我在控制器中实例化UnitOfWork,控制器对DbContext一无所知:

public ActionResult Index()
{
    var user = unitOfWork.UsersRepository.GetById(1); // unitOfWork is dependency injected using Unity or Ninject or some other framework
    return View(user);
}

这取决于应用程序的生命周期。

如果它将被使用,扩展和更改多年 ,那么我会说创建一个包装器是一个不错的选择。

如果它是一个小应用程序,并且正如您所说的那样,您不打算将EntityFramework更改为另一个ORM ,那么就不必自己创建包装器并直接在控制器中使用它。

对此没有明确的答案。 这一切都取决于你想要做什么。 如果你想要代码可维护性,我建议使用包装器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM