【问题标题】:How to make the data access technology (Entity Framework) ignorance from the presentation layer (ASP.NET MVC)?如何让表示层(ASP.NET MVC)对数据访问技术(Entity Framework)的无知?
【发布时间】:2015-03-30 13:32:33
【问题描述】:

前提:

我正在练习领域驱动设计,我将我的解决方案分为 4 层:

  • 表示层
    • 用于 RESTful API Web 服务的 ASP.NET Web API 2 项目
    • 用于文档和管理屏幕的 ASP.NET Web MVC5 项目
  • 应用层
    • 一个类库项目,负责从表示层获取命令并使用任何域服务
  • 域层
    • 包含业务模型和逻辑的类库项目
    • 包含领域服务的类库项目
  • 基础设施层
    • 一个包含所有具体实现的类库项目,例如使用 Entity Framework 的 dataq 持久性、使用 Log4net 的日志记录、使用 Simple Injector 的 IoC 等

领域层只有一组为聚合定义的存储库接口,它取决于基础设施层中存在的实现数据访问机制来隐藏实现细节。

在本练习中,我决定使用实体框架数据库第一种方法。当然,基础设施项目中有一个app.config,其中包含一个连接字符串。


问题:

好的,我花了很多时间尝试分离所有关注点并专注于域模型。在表示层(即 API 和 MVC 项目)中,没有直接引用基础设施项目。并且已经设置了 IoC 容器,因此所需接口的所有具体实现都将被注入到控制器构造函数中。

例如,当我选择 API 项目作为启动项目并运行它时,我得到了

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code.

Additional information: No connection string named 'xxxxxx' could be found in the application config file.


问题:

现在我明白了,如果我将实体框架安装到 API 项目中,将连接字符串从基础设施项目的 app.config 复制并粘贴到 API 项目的 web.config 中,一切都会奏效。但这打破了我们分离关注点的最初目的,不是吗?如果我们这样做,那么使用领域驱动设计并让表示层的数据访问技术无知又有什么意义呢?

我们不直接引用数据访问技术的直接实现(即使用dbContextLinq 的具体实现)的原因是我们可以轻松地将地下访问技术转换为其他技术。

那么正确的做法是什么?!!

我不想在我的表示层中安装实体框架,也不想到处复制连接字符串。我希望所有的数据访问和存储库的具体实现都存在于一个库中。

【问题讨论】:

  • 将所有的 ORM 数据访问放在存储库中是不值得的。教条地分离关注点会产生比它解决的问题更多的问题。

标签: c# architecture asp.net-mvc-5 domain-driven-design entity-framework-6


【解决方案1】:

实体框架配置必须在使用它的项目中。这并不意味着它会破坏您的分层结构或您的关注点分离。

【讨论】:

  • ".. 必须在使用它的项目中。"因此,如果我将所有数据访问存储库都放在一个类库中,并且还有其他几个引用它的项目,这是否意味着我需要将配置放入所有项目中?这意味着所有项目现在都知道它正在使用特定技术(即实体框架)。那会破坏SoC,不是吗?因为我们希望所有访问数据访问库的客户都不知道具体使用的是什么技术。对吗?
  • 您必须在使用它的项目中添加连接字符串。其他层/项目不必包含该连接字符串。
  • @DavidLiang 配置文件中的参数不会破坏关注点分离——它是一个运行时、松散的依赖关系,而不是编译时的参数。配置是在应用程序的入口点之外声明的,而不是在项目级别声明的,至少它在 .NET 中是这样工作的。
  • @DavidLiang 顺便说一句,MVC 应用程序可能会托管您的Composition Root,因此无论如何它都会引用基础架构。
  • 如果您不希望在 web.config 文件中跟踪 EF,请使用 Code First。关于在您的网站中引用 EF,恐怕您不能这样做。只要您的 Web 项目使用继承 EF 类的类(通常是 DBContext),您就需要它。
【解决方案2】:

从您的 app.config 中删除所有实体框架元素。创建您自己的连接字符串元素,并在应用启动时将其提供给实体框架。

【讨论】:

  • 您的意思是动态提供连接字符串,而不是放在 app.config / web.config 中?例如,您确定它可以在 MVC 项目上工作,而无需在那里安装实体框架吗?你能提供一个简单的例子吗?
  • 您仍然在配置中提供连接字符串,只需删除所有实体框架的特定设置。我没有示例,但明天会发布
猜你喜欢
  • 1970-01-01
  • 2016-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多