怎样减少域/实体/ DTO对象的重复? [英] How do I reduce duplication of domain/entity/DTO objects?

查看:348
本文介绍了怎样减少域/实体/ DTO对象的重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在重新设计我当前的项目更容易维护,并尽我所能去遵循良好的设计实践的过程。目前,我有一个Silverlight成分的溶液,ASP.Net主机说SL应用程序,还包含一个WCF RIA服务,并共享类库所以无论SL和WCF服务可以共享的对象。业务逻辑是分散各地的地方,所有的CRUD操作的手我的WCF服务的内部编码。所以,我创建一个新的结构的一切,将端口这个烂摊子到新的格式。在这样做的过程中,我发现,我复制类时,我不知道我是否应



我的新的结构布局为这样的:



客户:结果
Reporting.Silverlight 的= Silverlight应用程序。这将引用我的DTO类。结果
Reporting.Web 的=保持我SL应用程序,是主入口点的人得到它。
结果
结果
商家:结果
Reporting.Services 的=我的WCF服务,住在这里。我SL应用程序将拨打电话这个做的东西,而这些服务将返回DTO类。结果
Reporting.Services.Contracts 的=保持我的接口为WCF服务,并包含我的DTO类用DataContract装饰。结果
Reporting.Domain 的=保持我的域对象和业务逻辑
结果
结果
数据:结果
Reporting.Data.Contract 的=保持我的资料库和放界面;工作结果
单元的 Reporting.Data 的混凝土=库/ UOW的FPGA实现。实体框架5方面在此处定义。结果
Reporting.Data.Models 的=保持我所有的实体对象,因此EF5可以做它与SQL的事情。



我有3个地方,我几乎完全一样的课,对我它的气味。里面的 Reporting.Services.Contracts的的我有被交给SL客户端DTO。这里有一个作为一个例子:

  [DataContract(NAME =ComputerDTO)] 
公共类ComputerDTO
{
[数据成员(NAME =主机名)]
公共字符串主机名{获得;组; }

[数据成员(NAME =ServiceTag)]
公共字符串ServiceTag {搞定;组; }

// ...其它更多
}



我觉得上面的DTO是好的,因为它只是一堆属性,这些属性得到传递到客户端SL。绝大多数我DTO属性映射到我的实体对象的电学性能的研究1:1,除了ID字段。下面是与上面DTO相当于我的实体对象:

  [表(Inventory_Base)] 
公共类ComputerEntity
{
//主键
[关键]
公众诠释由assetid {搞定;组; }

//外键
公众诠释? {的Cl​​ientID得到;组; }

//这些道具是没有自定义映射
公共字符串主机名细{搞定;组; }
公共字符串ServiceTag {搞定;组; }
// ...加上另外一群更合我的导航属性
}

我使用与EF5代码优先的方法。我仍然在我重新写的一开始阶段,到目前为止,我的印象中,业务逻辑不应该是我的EF实体内。 DTO的不应该有商业逻辑无论是。这意味着它进入我的域模型,对吧?好了,给我的第3几乎相同类的 Reporting.Domain



 公共类电脑
{
公共字符串主机名{获得;组; }
公共字符串ServiceTag {搞定;组; }
// ...其它更多,几乎镜子DTO

公共字符串方法一(字符串参数1)
{
//很多的方法和逻辑去这里
}
}

3具有几乎相同的班没可能是去了解这个正确的方式,可以吗?我应该把我所有的业务逻辑的EF实体内,那么结果伸入,获取跨线通过的DTO?如果这是一个好主意,补习班的EF实体类内的所有我的域/业务逻辑,结构上应本人动议装配到我的业务层和超出了我的数据层,即使这些对象是被保存到我的数据库的人?理想情况下,我试图让我的包含数据的项目中,我的经营项目以外的实体框架的任何引用。我有大约200左右的类,我移植过来,将包括我的域名,我希望这件事情能够扩展到了更多的功能,一旦我得到这个重新编写完成。如何组织这件事情,并保持干燥,将不胜感激任何见解。



在情况下,它有助于定义什么,我试图做的更好,让我知道如果我应包括我下面我的仓库/的UnitOfWork方法。


解决方案

有3几乎相同班不可能是正确的方式
去了解这一点,可以吗?




IMO他们是不是 3几乎相同班,他们没有达到同样的目的。他们是相当同一个域概念的多个方面,每一个为特定层的需求量身定做。



这是支付模块化和关注明确分​​离的价格。更多的端口(如六角架构的港口及放大器;适配器)你有,更多的方面,你需要和。更多的映射,你就必须做



这是一个很好的文章:的 http://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/


I am in the process of redesigning my current project to be more maintainable, and doing my best to follow good design practices. Currently I have a solution with a Silverlight component, ASP.Net host for said SL app that also contains a WCF RIA service, and a shared class library so both SL and the WCF service can share objects. Business logic is scattered all over the place, and all CRUD operations are hand coded inside my WCF services. So, I am creating a new structure for everything and will port this mess into the new format. In the process of doing this, I find that I am duplicating classes when I don't know if I should be.

My new structure is laid out as such:

Client:
Reporting.Silverlight = Silverlight Application. This will reference my DTO classes.
Reporting.Web = Holds my SL app and is the main entry point for people to get to it.

Business:
Reporting.Services = My WCF services live here. My SL app will make calls to this to do stuff, and these services will return DTO classes.
Reporting.Services.Contracts = Holds my interfaces for the WCF services, and contains my DTO classes with the DataContract decorators.
Reporting.Domain = Holds my domain objects and business logic

Data:
Reporting.Data.Contract = Holds my interfaces for repository & unit of work
Reporting.Data = Concrete implemention of repository/UoW. Entity Framework 5 context is defined here.
Reporting.Data.Models = Holds all my Entity objects so EF5 can do its thing with SQL.

I have 3 places where I have almost the exact same class, and to me it smells. Inside of Reporting.Services.Contracts I have a DTO that gets handed to the SL client. Here is one as an example:

[DataContract(Name = "ComputerDTO")]
public class ComputerDTO
{
    [DataMember(Name = "Hostname")]
    public string Hostname { get; set; }

    [DataMember(Name = "ServiceTag")]
    public string ServiceTag { get; set; }

  // ... lots more
}

I think the above DTO is fine, as it just a bunch of properties that get passed to the SL client. The vast majority of my DTO properties map to my Entity objects' properities 1:1 except for ID fields. Here is my Entity object that corresponds with the above DTO:

[Table("Inventory_Base")]
public class ComputerEntity
{
    // primary key
    [Key]
    public int AssetID { get; set; }

    // foreign keys
    public int? ClientID { get; set; }

    // these props are fine without custom mapping
    public string Hostname { get; set; }
    public string ServiceTag { get; set; }
    // ... plus a bunch more in addition to my navigation properties
}

I am using the code first approach with EF5. I'm still in the very beginning stages of my re-write, and so far I have the impression that business logic should NOT be inside my EF Entity. DTO's shouldn't have business logic either. That means it goes into my domain model, right? Well, that gives my 3rd almost identical class in Reporting.Domain

public class Computer
{
   public string Hostname { get; set; }
   public string ServiceTag { get; set; }
   // ... lots more, pretty much mirrors the DTO

   public string Method1(string param1)
   {
       // lots of methods and logic go in here
   }
}

Having 3 almost identical classes can't possibly be the right way to go about this, can it? Should I be putting all my business logic inside the EF entity, then projecting the result into a DTO that gets passed across the wire? If it is a good idea to cram all my domain/business logic inside the EF entity classes, structurally should I move that assembly to my business layer and outside my data layer, even though those objects are the ones that get saved to my database? Ideally I'm trying to keep any references to Entity Framework contained within my data projects and outside of my business projects. I have about 200 or so classes that I'm porting over and will comprise my domain, and I expect this thing to scale to a lot more functionality once I get this re-write done. Any insight on how to structure this thing and keep it DRY would be much appreciated.

In case it helps define what I'm trying to do any better, let me know if I should include my repository/unitofwork methodology that I am following.

解决方案

Having 3 almost identical classes can't possibly be the right way to go about this, can it?

IMO they aren't "3 almost identical classes", they don't serve the same purpose. They are rather multiple facets of the same domain notion, each one tailored for the needs of a specific layer.

It's the price to pay for modularity and clear separation of concerns. The more ports (as in Hexagonal Architecture's Ports & Adapters) you have, the more facets you'll need and the more mapping you'll have to do.

A good article on this : http://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/

这篇关于怎样减少域/实体/ DTO对象的重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆