我有一个项目,在该项目中我们使用屏幕DTO来封装服务层和表示层之间的数据。在我们的情况下,表示层是ASP.Net。
唯一知道DTO的类是服务层类和调用这些服务并显示DTO的页面/控件。
DTO几乎总是特定于页面/控件的,因此我认为它们属于表示层,但这意味着服务层必须引用表示层才能使用DTO。
我几乎认为服务层应该返回更丰富的对象(但不是域实体?),然后表示层可以获取这些对象并将它们映射到针对每个页面/控件关注的具体DTO。
这是一个接口声明和一个DTO,你可以看看我在说什么:
唯一知道DTO的类是服务层类和调用这些服务并显示DTO的页面/控件。
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())