数据层和业务层之间的实体
我正处于一个新项目的开始阶段。因为,我总是想提高自己,并尽量避免过去的错误(每个人都有一些包袱),所以我查看了 .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 */
这样,我可以确保对数据表示的内部更改不会影响外层。
I am in the starting phase of a new project. Since, I always want to improve myself and try to avoid the mistakes from the past (everyone has some baggage), i looked at the Layered Architecture Sample for .NET. Looking at the data and business logic i spotted that it the data layer actually has a reference to the ExpenseSample.Business.Entities assembly, so the data layer is aware that there is business layer. That looks and feels kinda awkward.
Sure, it saves time mapping DataObject to BusinessEntities, but isn't a "dangerous" approach?
Looking forward to some discussion and maybe some better solutions.
UPDATE:
Thanks for the input. I now use
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 */
So this way i can make sure that internal changes to the representation of my data do not effect outer layers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我不同意,有些对象需要被所有层访问,我这样做:
DAL通常连接到WCF服务,并屏蔽了解它的其余应用程序(因此可以在几年内更改)当 WCF 已过时时)。
BAL 主要特定于应用程序(尽管可以在另一个应用程序中重用),但这些实体是专门为应用程序制作的,我不太可能在其他地方使用它们。
当然,这是一个相当小的应用程序,它可以使用其他 dll(模块、第三方等)进行扩展并变得更加复杂,但这就是想法。
我想我想说的是实体和 BAL 是两个不同的东西,不要混淆它们;)
I disagree, some objects need to be accessed by all the layers, i do it like this:
The DAL is usually connected to a WCF service, and shields the rest of the application of knowing it (so it can be changed in a few years when WCF is outdated).
The BAL is mainly specific to the application (although could be reused in another app), but the entities are made specifically for the application, it's highly unlikely that i would ever use them somewhere else.
Of course, that's for a reasonably small app, it can be extended with other dlls (modules, third party, etc) and get much more complex, but that's the idea.
I guess what i'm trying to say is Entities and BAL are two different things, don't mix them up ;)
一般规则是下层不应该了解上层。该示例不正确,因为业务实体是 BAL 而不是 DAL 的一部分。因此,业务层应该进行映射,而不是数据层。
映射并不真正需要时间,只需使用类似 ValueInjecter
免责声明:我没有查看链接的示例。只是给出我关于一般分层的两分钱。
A general rule is that the lower layer should have no knowledge about the upper layers. The example is incorrect since the Business Entities is part of the BAL and not the DAL. Hence the business layer should do the mapping and not the data layer.
Mapping doesn't really take time, just use something like ValueInjecter
Disclaimer: I've not looked at the linked sample. Just giving my two cents about layering in general.
不太正确,它只是知道有一个名为
Business.Entities
的命名空间,但这些实体肯定是架构中的叶子。它们只依赖于 .Net 框架。这些实体实际上没有任何逻辑(除了 ToString() 之外),因此它们只是充当整个架构上的数据契约。而且它们不引用任何其他项目。唯一不让它们成为 POCO 的是它们具有序列化意识。正如 Baboon 提到的,这种方法是可行的,而且我确信有一些例子表明这种方法非常有效。如果你看看这个项目和代码,一切看起来都那么美好和舒适,我只想爱上它。
只要您仔细规划整个架构的每一个添加,审查每一个更改并与开发人员密切沟通,这将是美好而有序的。但是,一旦您的体系结构、数据库和业务流程以更快的速度发展,您就必须使用公共对象对所有这些层的数据进行建模。在我看来,有一些例子支持特定于层的数据契约。其中之一是,有一天,UI 程序员希望在他的 UI 层的对象中拥有 PropertyChanged 通知程序。哼哼!您无法在不影响 BAL 和 DAL 的情况下做到这一点。有一天,您遇到这样的情况:您希望将仅限 GUI 的属性存储在实体中(例如显示颜色、屏幕上的位置、选择状态等)。数据库与它有什么关系?如果您仔细观察,您会发现这些实体已经具有特定于层的处理。您看到导航属性上的虚拟关键字了吗?它们的存在是为了让 EF 可以对它们进行子类化,并为您提供启用延迟加载的代理类……而这些代理类可能并不意味着通过服务进行传输。
另一种方法是使用对象映射(手动、通过模板或通过 AutoMapper 等库)。这个解决方案肯定不太干净、不太舒适,因为存在代码重复以及一行又一行的映射代码。但所有这些都允许您解耦层中的数据,并根据每个层的特定需求对其进行建模。
Not quite correct, it's just aware that there's a namespace called
Business.Entities
, but these entities are certainly leafs in the architecture. They depend on nothing else, but the .Net framework. The entities don't actually have any logic in them (apart from a ToString()) so they're just acting as data contracts over the whole architecture. Also they're free from references to any other projects. Only thing that doesn't make them POCOs is that they're serialization-aware.As Baboon mentioned, this approach is possible and I'm sure there are examples where this works very well. And if you look at the project and the code it all looks so nice and cozy I just want to fall in love with it.
And it will be nice and orderly as long as you carefully plan every addition to your whole architecture, review every change and have tight communication with the developers. But as soon as your architecture, your database and your business processes evolve in a more rapid fashion, you'll have to stretch far to model the data for all those layers with common objects. There are some examples that in my opinion speak in favor for layer-specific data contracts. Among them is that some day the UI programmer wants to have PropertyChanged notifiers in your objects for his UI layer. Hrmpf! You can't do that without also affecting your BAL and DAL. Another day you come across the case that you want to have GUI-only properties stored in the entities (like display color, position on the screen, selection states, etc.). What's the database got to do with it? And if you looked carefully you have noticed that the entities already have layer-specific treatments. Did you see the virtual keywords on the navigation properties? They're there so that EF can subclass them and give you lazy-loading enabled proxy classes... which in turn are likely not meant to be transmitted over the service.
The alternative is to use object mapping (either manual, through templates or by libraries such as AutoMapper). This solution is certainly less clean, less cozy, as there's code duplication, and lines and lines of mapping code. But all that allows you to decouple the data in your layers and model it according to the specific needs for each layer.
我要说的一件事是,如果您要允许 DAL 访问业务对象,那么您也可以创建一个项目,并将 BAL 和 DAL 分离到该项目内的单独目录和命名空间中。至少你没有在分层方面自欺欺人。
在我参与过的大多数项目中,将 BAL 和 DAL 分成单独的程序集几乎没有什么好处。如果您的数据库解决方案可能会发生变化,并且您希望自己能够面向未来,那么请改用像 nHibernate 这样的 ORM。
One thing I would say is that if you are going to allow the DAL to access business objects then you may as well create one project and separate BAL and DAL into separate directories and namespaces within that project. At least you're not kidding yourself about the layering then.
On most projects I've worked on there has been little benefit in separating BAL and DAL into separate assemblies. If your database solution is likely to change, and you want to future-proof yourself, then use an ORM like nHibernate instead.