Data-和BusinessLayer之间的实体

时间:2011-11-11 13:15:00

标签: .net design-patterns multi-tier

我正处于新项目的起始阶段。因为,我总是想提高自己并尽量避免过去的错误(每个人都有一些包袱),我看着Layered Architecture Sample for .NET。查看数据和业务逻辑,我发现数据层实际上引用了ExpenseSample.Business.Entities程序集,因此数据层意识到存在业务层。看起来和感觉有点尴尬。

当然,它节省了将DataObject映射到BusinessEntities的时间,但这不是一种“危险”方法吗?

期待一些讨论,也许还有一些更好的解决方案。

更新: 感谢您的投入。我现在用

MyApp.Data.Contracts.*
MyApp.Data.Access.*         /* has the classes to access the DB and maps it to 
                               the Data.Contracts */
MyApp.Business.Entities.*
MyApp.Business.Components.* /* accesses the classes from Data.Access, 
                               maps the Contracts to the Business.Entities and 
                               provides the components to access them */

因此,我可以确保对数据表示的内部更改不会影响外层。

4 个答案:

答案 0 :(得分:2)

我不同意,所有图层都需要访问某些对象,我这样做:

-----------
| DAL | E  |
------- N  |
| BAL | T  |
------- I  |
|  G  | T  |
|  U  | I  |
|  I  | E  |
|     | S  |
-----------

DAL通常连接到WCF服务,并屏蔽知道它的其余应用程序(因此当WCF过期时可以在几年内更改)。

BAL主要针对应用程序(虽然可以在另一个应用程序中重用),但实体是专门为应用程序制作的,我不太可能在其他地方使用它们。

当然,这是一个相当小的应用程序,它可以与其他dll(模块,第三方等)进行扩展,并且变得更加复杂,但这就是主意。

我想我想说的是实体和BA​​L是两个不同的东西,不要混淆它们;)

答案 1 :(得分:1)

一般规则是下层应该不了解上层。该示例不正确,因为业务实体是BAL的一部分而不是DAL。因此,业务层应该进行映射,而不是数据层。

映射并不需要时间,只需使用类似ValueInjecter

的内容

免责声明:我没有看过链接的样本。一般只给我分两分钱。

答案 2 :(得分:0)

我要说的一件事是,如果您要允许DAL访问业务对象,那么您也可以创建一个项目,并将BAL和DAL分成该项目中的单独目录和名称空间。至少你不是在开玩笑说自己的分层。

在我参与的大多数项目中,将BAL和DAL分离成单独的程序集几乎没有什么好处。如果您的数据库解决方案可能会发生变化,并且您希望自己面向未来,那么请使用类似nHibernate的ORM。

答案 3 :(得分:0)

  

...所以数据层知道有业务层

不太正确,它只是意识到有一个名为Business.Entities的命名空间,但这些实体肯定是架构中的叶子。它们不依赖于任何其他东西,而是.Net框架。实体实际上并没有任何逻辑(除了ToString())因此它们只是作为整个架构的数据契约。他们也没有参考任何其他项目。只有不能使它们成为POCO的东西才是它们能够识别序列化。

正如狒狒所说,这种方法是可行的,我确信有一些例子可以很好地运作。如果你看一下项目和代码,它看起来都那么美好和舒适,我只想爱上它。

只要您仔细规划整个架构的每一个附加内容,审核每个更改并与开发人员进行密切沟通,它就会很好而有序。但是,只要您的体系结构,数据库和业务流程以更快的方式发展,您就必须尽可能地为具有公共对象的所有这些层的数据建模。在我看来,有一些例子支持特定于图层的数据合同。其中有一天,UI程序员希望在你的UI对象层中有PropertyChanged通知程序。 Hrmpf!如果不影响你的BAL和DAL,你就不能这样做。另一天,您遇到的情况是您希望在实体中存储仅GUI属性(例如显示颜色,屏幕上的位置,选择状态等)。数据库与它有什么关系?如果你仔细观察,你会注意到实体已经有了特定于层的处理方法。您是否在导航属性中看到了虚拟关键字?它们在那里,以便EF可以对它们进行子类化,并为您提供启用延迟加载的代理类...这反过来可能不会通过服务传输。

另一种方法是使用对象映射(手动,通过模板或通过AutoMapper等库)。这个解决方案肯定不那么干净,不太舒适,因为代码重复,以及映射代码的行和行。但所有这些都允许您根据每个图层的特定需求对图层中的数据进行解耦并对其进行建模。