我正试图找到一个很长一段时间让我疯狂的问题的最终答案。
通常表示BLL应该包含业务逻辑和业务对象(BO),并且引用了DAL。另一方面,DAL不能引用BLL,因此它不能接受BO作为参数,或者将BO作为返回值返回。
这个问题最常见的答案是:
a)接受简单参数,并返回(最好是Typed)DataSet和DataTables以返回数据: 命名空间DAL { 公共课联系方式 public DataTable GetContacts(){...} public UpdateContacts(DataTable contacts){...}
b)第二个最推荐的解决方案是定义临时的,可序列化的数据传输对象(DTO)(有时称为值对象(VO)),它只有字段和属性,没有方法,仅用于简单地传输数据备份到BLL层,其中用于填充新BO,然后丢弃它们。
c)使用定义BO的公共第三个程序集(例如,称为Entities.dll),并由所有3个层引用:UI,BLL和DAL。
选项a)实现最少的工作(不需要构建另一个程序集),因此为什么经常提出,但DataTables只需要简单的操作就需要额外的布线。
然而,目前还不清楚b)或c)中的哪一个更好......
我看到b)有时提供,几乎从不c),虽然c)似乎是两者中最容易的。
我错过了什么?为什么c)很少提供,即使它在逻辑上看起来最简单,为什么a)在明显不适合所有场景时提供(例如返回单个对象)?
谢谢!
答案 0 :(得分:3)
好吧,我很难看到(b)在实践中受雇。我大部分时间都使用(c)中描述的方法(其他时候是我甚至没有在BLL / DAL之间分开或者根本没有域模型)。毕竟,业务和数据组件通常是物理上共同定位的,因此这两者可以直接共享BO。事实上,像Hibernate,Entity Framework,Linq2Sql等框架实际上鼓励(c)允许一个人为复杂域模型执行ORM。
DTO更常用于将数据从BLL传递到UI,尤其是。当UI和BLL部署在不同的服务器中时。在这种情况下,UI可能需要简化域模型视图,以减少跨进程往返并最小化更改的影响(当域模型更改时)。
答案 1 :(得分:1)
ADDENDUM to original Question:
我认为(在第一次回复之后,Buu Nguyenthat认为以下参考模式是完全可以接受的,甚至可能推荐使用LINQ等:
BLL >
v Business Entities Layer (BEL)
DAL >
除非BLL和DAL在不同的层上,并且BLL通过WCF与DAL通信......? 在这种情况下,它将无法工作(DAL通过WCF返回的业务实体将被序列化,并且在BLL端将被反序列化为原始BE的代理 ...并且不会映射回来BE是他们自己。或者是明显错误的,上面的参考模式适用于BLL和DAL在同一层时,以及 在不同的层次?
ADDENDUM#2: 找到了一个有趣的链接,为什么它实际上很好地使用BO的外部组件。 He states“违反规则,图层应该只知道下面的图层,但是指定列名称的数据库不是直接在BLL之下,而是在DAL之下。所以没有键入的DataSet不会保护你不受数据库的影响,这就是为什么我认为它们是错误的。更好的解决方案是使用在单独项目中定义的强类型对象。例如,DTO中将有一个带有Name属性的Teacher类但没有等级方法。“
答案 2 :(得分:1)
如果(c)很常见,我不会感到惊讶。如果您的BLL和UI位于不同的服务器上,您还可以通过线路传递实体,如果您使用的是WCF。 看一下这个示例,了解如何对实体here [zip]进行序列化,这里是downloads page的链接。这篇文章也可能有助于serializing with WCF