7

解决方案设置:

  • DAL(类库)
  • BLL(类库)
  • 通用(类库(一些通用功能 - 枚举、日志记录、异常...))
  • 应用程序 1(Windows 应用程序)
  • 应用程序2(Windows 应用程序)
  • WebApp(网络应用程序)
  • ...

假设我有一个客户实体,即:

  • SQL server 中的一个表
  • DAL 中的 CustomerDataTable
  • BLL 中的客户类
  • 所有应用程序中的 BLL.Customer 类

BLL 和 DAL 应该使用什么样的对象进行通信 -DataTableList<Customer>(例如)?在第一种情况下,BLL 逻辑应该将 Customer 对象转换为 DataTable 并将其发送到 DAL。在第二种情况下,DAL 层应该知道位于 BLL 层中的 Customer 类。但是最初的 DLL 引用了 DAL 而不是相反...

我是否应该将所有类放入单独的程序集中,由所有其他程序(Common、BusinessObjects、...)引用?在这种情况下,我可以在所有项目中使用 Customer 类。

当我知道只有一个 BLL 会使用我的 DAL 时,我是否应该费心将 DAL 和 BLL 分开。在这种情况下,我可以将它们合并到一个项目中。

PS - 我正在阅读有关 DataTables 的信息,很多人说我们根本不应该使用它们。有什么更好的选择?也许是时候让我学习一些 ORM 映射工具了 :)

4

4 回答 4

9

在我看来,你应该有另一个层(单独的 dll)。就像“域”一样,您会将客户等所有实体保存在哪里。然后简单地将这个程序集包含在层次结构中的所有更高级别(DAL、BLL、UI 和其他)中。

示例架构可能如下所示:

(Database) <-> DAL <-> BL <-> UI

and on all levels you will have access to "domain" layer. DAL should return List not a DataTable. On some stage your development process you may want to use in DAL some OMR like NHibernate with would also return a List, probably.

于 2010-10-17T09:04:14.780 回答
4

如果不充分了解应用程序领域,就很难回答这个一般性问题。我会从考虑未来最有可能发生变化的地方开始,并尝试从中找出需要灵活性的地方。

我的以下想法只是一个建议。随意考虑它们并更改/忽略您认为无关紧要的内容。

将 DAL 与 BLL 分开几乎总是一个好主意。数据方案是应该封装并隐藏在应用程序的其余部分中的一件事,因此请将您的 DataTables、DataSets、ORM 或任何其他解决方案隐藏在 DAL 中。BLL(和它上面的层)应该使用简单的数据类型(意思是简单的类)。我认为将这些类放在没有引用并且可以在任何地方使用的 Model 类库中是个好主意。

感觉你的分层有点太多了……你真的需要 BLL 中的 Customer 类和 Application 层中的另一个吗?可能是,但我会确保并三思而后行。

根据我最近的一个项目(一个每天有 20 万独立访问者的天气网站)的经验,我们使用 link2sql 进行数据访问(主要是只读数据),并在我们的 ASP.Net MVC 应用程序中使用简单的数据类(当然作为模型/视图模型的一部分)。它工作得非常顺利,我们可以轻松更改数据方案而无需破坏其他层。

至于您关于 DataTables 的最后一个问题,如果您决定使用它们(我会投反对票),这些对象完全属于您的 DAL。它们不应该暴露给其他层,因为这会产生与该特定类的耦合。如果明天 MS 发明一个更好的课程怎么办?既然您的项目中都有大量对 DataTables、它的方法和属性的引用,您会切换吗?将您的 DAL 更改为与 NewAwsomeDataTable 类一起使用会更好,而您的应用程序的其余部分则非常无知。

希望有帮助:)

于 2010-10-17T08:39:29.773 回答
2

我将使用以下模式,因为它允许您稍后升级到不同的持久性策略。

UI/Consumer  <--- (view models) --> BLL <--- Models ----> DAL/Persistence

在这里,视图模型在 BLL 之外使用,模型在 BLL/DAL 层之间进行通信。

在您的情况下,模型可以是 DAL 使用的任何东西——例如 DataTables,或者以后可能是 ORM 实体。BLL 负责模型和视图模型之间的映射。

至于将类型保留在自己的程序集中 - 是的,对于视图模型并且为了保持一致性,对于模型也是如此。

保持模型和视图模型分开可以阻止持久性策略在 BLL 之外的泄漏,从而允许未来对持久性进行设计更改。

这种分离的一个优点是不同的视图模型消费者对于相同的持久性模型/实体可以有不同的视图模型。有些可能很小,属性很少,而另一些可能很大,功能丰富。它还允许您引入离线/断开连接功能,因为视图模型可以在不同时间返回,从而允许您决定数据合并策略。这也允许您成为持久性实体(例如,表格可以增长和改变形状)。因为这看起来像一个 .net 实现,所以像AutoMapper这样的东西将提供很多开箱即用的功能

当然,这对您的应用程序来说可能有点过头了——但是我仍然会维护一个 BLL 映射,它只与所有 BLL 消费者讨论视图模型。这应该给你足够的解耦。

于 2010-10-17T08:31:32.017 回答
1

将域实体推入 dal 是一种可以消除循环依赖的选项,但可能与您的意图不符。不过,这并非闻所未闻。例如 LINQ-to-SQL 生成的实体将存在于 DAL 中。

其他选项:

  • 将它们放入一个通用的下部组件中(但这可能会使您的 BL 相当空)
  • 使用 IOC 删除/反转 BL/DAL 之间的引用

这里没有一个正确的答案。

重新数据表;我个人同意 - 我不是粉丝;)但是,它们可以成功且合理地使用。但是,如果我必须使用它们,我会将它们作为实现细节保留在 DAL 中 - 而不是在此之上公开它们。

于 2010-10-17T08:38:33.453 回答