【问题标题】:Asp.Net Multi-Tier Architecture Class Library ReferencesAsp.Net 多层架构类库参考
【发布时间】:2014-12-17 13:41:35
【问题描述】:

我是一名 PHP 程序员,申请了一份 ASP.NET 工作。他们给了我一个任务,让我制作一个(我选择的)实现多层架构的应用程序。

我有很多难题。据我了解,多层是一个没有通用形式的概念,每个人都应该决定什么是最适合他们的。但是,他们建议我表示层不应该对数据访问层有任何引用,这是有道理的。但是……

我用Add new project(有控制器和视图)创建了一个新项目,它是一个表示层。现在,在表示层中,还有一个class library,它使用Ninject 为整个应用程序注入依赖项,称为NinjectIoC。 NinjectIoC 必须具有对表示层项目的引用,以便将依赖项作为参数直接注入控制器中。它还必须具有对所有其他层(DataAcessLayer、BusinessLayer 等)的引用,以便将它们绑定到它们的依赖项。

主要问题是表示层项目还必须具有对 NinjectIoC 的引用才能在 Global.asax 中创建 StandardKernel,这会创建循环依赖,并且是不允许的。

唯一的解决方案是添加对所有层(包括 DataAccessLayer)的表示层项目的引用,据我所知,这是一件坏事。但是,这是绑定所有层的所有接口并在 Global.asax 中执行的唯一方法。

我想错了吗?

编辑:

NinjectIoC 安装了 Ninject 并引用了所有层,以便在应用程序中绑定它们。它必须有对 UI 的引用才能在 Global.asax 中调用

UI 必须具有对 NinjectIoC 的引用,以便它可以在 Global.asax 中调用它以进行控制器绑定。

我尝试创建一个引用 NinjectIoC 的中间类库。该库在 UI 中被引用。问题在于,这也会创建循环依赖,因为 NinjectIoC 必须具有 UI 的引用才能绑定控制器。

【问题讨论】:

  • 将 IoC 抽象为一个通用库(横向层)。然后,您可以在 UI 中实现 Ninject 来执行查找,但在其他库中它不需要任何其他知识,而不是通用库。
  • 我想我试过了。我制作了一个仅引用 NinjectIoC 和 NinjectIoC 引用 UI 的“内核”类库。问题是 UI 必须具有对 UI 的引用才能在 Global.asax 中使用它。这也是一个循环依赖。
  • 看看ProDinner。这是一个将多层与 MVC 结合使用的示例(并将 IoC 容器分解为 ProDinner.Infra 库)。

标签: asp.net-mvc-4 architecture inversion-of-control multi-tier


【解决方案1】:

多层可以简单地表示有一个 DAL、一个 BL 和一个 UI 层。而“在 UI 层中不引用 DAL”的要求可能只是意味着您的 UI 层(MVC4 应用程序)只能引用 BL。这很容易实现,例如这样:

  • 一个 UI 项目 (MVC4)
  • 实体项目(类库):在此处定义使用的实体,并从所有必要的层引用它(这有助于避免循环引用)
  • 一个 BL 项目(类库):这必须引用实体和 DAL 项目
  • 一个 DAL 项目(类库):这引用了实体项目

这是最经典、最简单的多层项目。

在最终编译的时候,当然间接依赖会包括UI工程和3个库,但是不需要在UI中添加对DAL的引用。

另一个不同的问题是使用 IoC 模式。在这种情况下,为了解决循环引用问题,我建议您为每一层分别定义“接口”项目和“实现”项目。类似于以前的结构,但有以下变化:

  • 一个 UI 项目
  • 一个实体项目
  • 一个 BL 接口项目
  • 实现 BL 接口的项目
  • DAL 接口项目
  • 实现 DAL 接口的项目

您需要定义哪个是主项目。它通常是 UI 项目。这个项目将拥有所有依赖项。

在这种情况下,UI 项目直接依赖于 BL Interfaces 项目。 BL 接口将依赖于 DAL 接口。简而言之,您的 UI 项目将仅与 BL 接口有直接依赖关系。

问题是,当你尝试运行代码时,它需要解决这个依赖关系,即找到接口的实现,以及存在依赖关系。这是应用程序的“组合根”,也是您需要注册依赖项的地方。即,这是您需要定义每个接口将使用哪个具体实现的地方。而且,如果此实现依赖于其他接口,您还必须定义它们的实现。根据框架(我不知道您是否可以使用 NInject),您可以动态地执行此操作,而无需添加对实现项目的引用。但是,即使您必须包含对所有其他实现和接口项目的引用,您也不会有循环依赖,并且您的 UI 不会依赖于 DAL 或实现层。您只需要它们在 IoC 容器中注册它们,这是一个非常不同的问题。 (如果使用构造函数注入,则使用此项目结构可以获得最大可能的解耦)。

保留一个或多个独立的实体项目可以避免循环引用和项目之间的直接依赖关系。例如,如果您在 DAL 项目中定义了实体,那么在您的 UI 项目中使用它们时,您需要添加对 DAL 项目的引用。如果实体在单独的项目中声明,这个问题就会消失。

纯粹的IoC,如“洋葱架构”,远不止于此,它通过在主项目(UI项目)中定义依赖的实体和必要的接口,然后在其他项目中实现这些依赖,并动态解决它们,以避免循环引用。 IE。所有其他项目直接或间接依赖于 UI 项目,而不是相反。在这种情况下,您需要动态解决依赖关系以避免循环引用。

正如您所见,有很多选择,我已经向您展示了几个可行的解决方案示例。

【讨论】:

  • 我以前做过同样的系统,但是我申请的公司说他们有自己的方式,UI只依赖于业务层,其他依赖必须完成在其他一些类库中。不管怎样,你帮了我很多,我可能会经常回来看这篇文章。
  • 那家公司不是个好主意。有一些选项,例如 1) 在所有项目中实现一个静态方法,可以调用该方法来注册依赖项,并接收容器作为参数。缺点:它需要调用此方法 2) 创建一个单独的项目,该项目具有一个公开 IoC 容器的静态类,并从所有项目中引用它,以便它们可以注册它们的依赖项。缺点:您需要在任何地方添加静态构造函数来注册依赖项。 3)在所有项目中使用能够使用依赖配置文件的框架:我不知道
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多