C# 如何使用DTO';在UI、BLL和DAL之间
我正在尝试编写一个在BLL和DAL之间有非常严格边界的小应用程序,现在我想知道在层之间传递数据(域传输对象)的最佳方式是什么 我在BLL和DAL都可以访问的域级(类库)中实现了一些类。这些类基本上只包含属性/数据成员,并且当前反映DAL数据。例:C# 如何使用DTO';在UI、BLL和DAL之间,c#,user-interface,dns,data-access-layer,bll,C#,User Interface,Dns,Data Access Layer,Bll,我正在尝试编写一个在BLL和DAL之间有非常严格边界的小应用程序,现在我想知道在层之间传递数据(域传输对象)的最佳方式是什么 我在BLL和DAL都可以访问的域级(类库)中实现了一些类。这些类基本上只包含属性/数据成员,并且当前反映DAL数据。例: class CustomerData { // some data fields } 然后我在BLL中实现了一些类,如下所示: class Customer : CustomerData { // Some methods } 在DAL中,
class CustomerData
{
// some data fields
}
然后我在BLL中实现了一些类,如下所示:
class Customer : CustomerData
{
// Some methods
}
在DAL中,我通过Linq到Sql从数据库获取客户记录。然后,我通过以下方式将linq对象映射到我的域对象:
CustomerData.field = LinqObject.field
// Etc
因此,我的想法是,当请求时,我现在从DAL向BLL发送一个CustomerData实例(并且我应该将一个Customer实例传递给我的UI)
在我的BLL中,我将因此收到一个CustomerData实例,但现在我想从中创建一个客户
问题:
客户c=新客户; c、 字段=CustomerData.field李>
类客户 { 客户数据; }
谢谢一般来说,我认为DTO是非层特定的,由DAL创建/消费,由BLL处理,被UI消耗/创建。 通常每个层都是VS解决方案文件夹中的一个单独项目,因此DTO是每个层引用的另一个项目
这样,如果UI中需要存在字段,但其他层中不需要存在字段,则可以从中继承DTO。您没有完全使用DTO。在
Customer
类中,将CustomerData
直接返回到您的UI
而且不需要从CustomerData
编辑:
我在这里使用fully这个词是因为CustomerData是DTO,所以不要返回Customer,而是返回CustomerData,因为它是您的DTO,如下图所示
有一个建议,你应该用它来隔离你的BLL和DAL
1] 我的观点是,我不是甲骨文,但希望它能提供一些帮助:) 在我看来,这里的“模特”太多了。这可能会导致混淆,并导致大量代码只是在不同的表示形式之间复制数据。大量的代码意味着更多的bug。然后,我认为数据类和业务类之间的继承在定义业务类时会限制您。如果您想创建一个由多个数据类组成的业务类,该怎么办?我认为,您应该使用接口或组合 通常,我只使用一个反映业务领域的概念模型。正如Dead Rabit指出的那样,这个模型被数据层和业务层使用,在某些情况下甚至被表示层(在较小的应用程序中)使用。对于持久性,我使用一个O/RM,比如EF4 对于较大的项目,尤其是在分布式场景中,我使用自定义DTO作为UI层。这些类反映了UI的需求,并且可能与概念模型中的实体有很大不同 就我个人而言,我认为Entity Framework 4在根据这种结构构建应用程序时对您有很大帮助,如果您正处于项目的早期阶段,并且使用.NET 4,您可能想查看一下它
如果您坚持在DTO上有多个层,您可以使用来帮助您在一行代码中从一个层转换到另一个层(通过在DTO中使用相同的约定)
CustomerData CustomerData=Mapper.Map(linqObjectInstance);
您还应该查看PresentationModel模式:
如果你想这样做,你也可以在谷歌上搜索MVVM(Model View ViewModel)。肯定会查看EF4。我最初的结论是,这个应用程序的层太多了。但过去我的层总是“泄漏”太多,所以我在这里试图对自己严格要求。我如何“充分利用”“DTO’s?有人给了我一篇文章,其中有一个很好的例子,说明了DTO和BLL和DAL之间的相互作用不是贫血领域模型反模式。meYorah对1的回答是+8,这令人困惑。猴子那样编码对你来说可能是一种痛苦。最后,这实际上是错误的做法,因为它增加了bug的程度,使事情在a$$中变得如此痛苦。试试看,很多人喜欢它比AutoMapper好,更轻。请务必重复使用映射。
CustomerData customerData = Mapper.Map<LinqObject, CustomerData>(linqObjectInstance);