代码之家  ›  专栏  ›  技术社区  ›  Scott Muc

DTO的直播应该在哪个项目层进行筛选?

  •  11
  • Scott Muc  · 技术社区  · 17 年前

    我有一个项目,我们使用屏幕DTO来封装数据 服务层 以及 表示层 在我们的例子中,表示层是ASP。网。

    唯一知道DTO的类是服务层类和调用这些服务并显示DTO的Pages/Controls。

    DTO几乎总是特定于页面/控件的,所以我觉得它们属于表示层,但这意味着服务层必须引用表示层才能使用DTO。

    我几乎认为服务层应该返回更丰富的对象(但不是域实体?),然后表示层可以获取这些对象并将其映射到每个页面/控件关注点的非常具体的DTO。

    这里有一个接口声明和一个DTO,所以你可以看到我在说什么:

    public interface IBlogTasks
    {
        BlogPostDisplayDTO GetBlogEntryByTitleAndDate(int year, int month, string urlFriendlyTitle);
    }
    
    public class BlogPostDisplayDTO 
    {
        public string Title { get; set; }
        public DateTime PostDate { get; set; }
        public string HtmlContent { get; set; }
        public string ImageUrl { get; set; }        
        public string Author { get; set; }
        public int CommentCount { get; set; }
        public string Permalink { get; set; }
    }   
    

    编辑

    这是另一个代码示例,用于描述不涉及域模型的用例。也许这会澄清一些事情。我相信我已经夸大了DTO的含义。我不是在说DTO的功能是通过电线传输物体。我正在创建DTO,以正式化与服务层之间的通信契约。

    public interface IAuthenticationTasks
    {
        bool AuthenticateUser(AuthenticationFormDTO authDTO);
    }
    
    public class AuthenticationFormDTO
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public bool persistLogin { get; set; }
    }
    

    假设我的身份验证突然需要一个IP地址参数。我现在可以将该属性添加到DTO中,而无需更改我的合约接口。

    我不想将实体传递到我的表示层。我不希望我的代码后面有能力 BlogPost.AddComment(new Comment())

    2 回复  |  直到 17 年前
        1
  •  18
  •   sbohlen    17 年前

    即使“DTO”的规范用例更像是“可以通过线路传递的可序列化对象”,在这种情况下,你实际上更多地指的是“表示传输对象”或“视图模型”。

    通常,对于我们的项目来说,这些代码所在的位置就是将DDD域模型映射到PTO类的“翻译”代码所在的地方。如果这是在Prensenation层(也许不是一个很好的答案),那么pres.层就是我声明PTO的地方。但通常情况下,是“服务”为您进行翻译,这意味着“服务”和“表示”层都需要引用PTO,这(通常)会导致它们在单独的、中立的项目/程序集/命名空间/表示层和服务层都可以引用的任何内容中声明。

        2
  •  4
  •   ssmith    17 年前

    您是否使用实际的服务(web或WCF)?如果是这样,请在服务层中定义DTO,并且在添加服务(或使用旧ASMX的web)引用时创建的代理将包含所有DTO类型。这是最简单的方法,并且只保持ASP之间的松耦合。NET项目和您的服务项目——两个方向都不需要直接的项目引用。当您更新DTO时,您需要做的就是更新您的服务引用,它将通过生成的代理类自动向您的web项目公开更新。

    无论如何,如果你遵循DDD方法,最好让你的基础设施项目(如特定于web平台的UI)引用你的域对象,反之亦然。然而,如果你遵循我上面的建议,你的网络项目根本不会直接依赖于这个项目,这是一件好事,当然比让你的富域对象依赖于你的web项目要好(如果这是一个考虑因素的话——我意识到你并没有说你在做这件事)。

    如果你的DTO是特定于视图的,那么我会将它们包含在你的UI项目中。控制器的工作应该是确保视图只从模型中获得它需要的东西——在你的例子中,是一个只包含视图所需字段的值对象。

    推荐文章