【发布时间】:2012-01-10 01:42:40
【问题描述】:
假设您正在实现自己的 stackoverflow 版本(再次,是的)
您的服务提供了所有必需的功能,如下所示:
class Question { ... } // EF entity
class Answer { ... } // EF entity
interface IStackoverflowService
{
void PostQuestion(Question question);
void PostAnswer(Answer answer);
void UpdateQuestion(Question question);
...
}
这似乎很简单,总的来说我认为这是个好主意。我在这里唯一不喜欢的是客户端代码(ASP.NET MVC 控制器)可以直接访问Questions 和Answers。假装我们有一些与发布问题和答案有关的强硬 BL。将这个逻辑集中在一个“单一的地方”——在服务层上是个好主意。如果您的客户端代码可以访问Questions,那么有一天有人可能会决定向您的一个控制器添加“一点点逻辑”,这基本上是个坏主意。
我正在考虑定义一些 DTO,它们将成为服务接口的一部分,因此客户端代码将只能使用这些包含“恰到好处的详细信息”的 DTO。
假设您的问题实体是这样定义的:
interface Question
{
int Id { get; set; }
User Poster { get; set; }
DateTime Posted { get; set; }
DateTime? Edited { get; set; }
string Title { get; set; }
string Text { get; set; }
IQueryable<Answer> Answers { get; set; }
...
}
发布问题时,请求应仅包含Title、Text 和Poster。所以,我会定义一个PostQuestionDTO:
class PostQuestionDTO
{
User Poster { get; set; }
string Title { get; set; }
string Text { get; set; }
}
当有人打开页面查看问题时,会有更多详细信息,例如 Posted 和 Edited:
class QuestionDetailsDTO
{
User Poster { get; set; }
string Title { get; set; }
string Text { get; set; }
DateTime Posted { get; set; }
DateTime? Edited { get; set; }
}
等等。这是一个好的做法还是你认为它过度设计?这里有哪些常用的方法?
【问题讨论】:
-
实施 DTO 并不能阻止人们向控制器“添加一点逻辑”。 MVC 是它自己的范例,我希望人们能够意识到这一点并停止尝试添加 n 层概念。
-
问题不在于MVC,而在于“MVC + BL”中的“+”符号
-
控制器应该包含关于作为控制器一部分的动作的业务逻辑,模型应该封装其他业务逻辑。除非您需要连接到 WCF 或其他服务来访问您的数据,在这种情况下,您可以将其封装在 EF 中。不需要在单独的程序集中使用 PL/BL/DL 的 n 层 BL 抽象。 MVC 模式非常清楚什么去哪里。
标签: asp.net-mvc controller dto service-layer