2

假设您正在实现自己的 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,TextPoster。所以,我将定义一个PostQuestionDTO

class PostQuestionDTO
{
    User Poster { get; set; }
    string Title { get; set; }
    string Text { get; set; }
}

当有人打开页面检查问题时,会有更多详细信息,例如PostedEdited

class QuestionDetailsDTO
{
    User Poster { get; set; }
    string Title { get; set; }
    string Text { get; set; }
    DateTime Posted { get; set; }
    DateTime? Edited { get; set; }
}

等等。这是一个好的做法还是你认为它过度设计?这里的常用方法是什么?

4

1 回答 1

1

我最近使用大量的 Ninject 和 AutoMapper 几乎完全实现了您所说的内容。我的逻辑结构是这样的:

    MyCompany.Data // Data layer namespace containing EF EDMX file / Codefirst / ADO.Net, whatever you want.
    class User { } // EF Entity

MyCompany.Business // Business layer namespace containing business level factory interfaces and classes that expose their own business objects (some are directly mapped to the DB, most are not). All members expose POCO objects

class NewUser { } // POCO class RegisteredUser { } // POCO interface IAccountFactory {
    void AddUser(NewUser user);
    RegisteredUser GetUser(int id); } // factory interface class AccountFactory : IAccountFactory // Service provider

MyCompany.MVC // Presentation layer containing controllers and views. Controllers expose POCO objects from the business layer to the Views.

我认为这根本不算矫枉过正——是的,编写起来需要更长的时间,但 AutoMapper 基本上为你删除了大部分的驴工作。

我的一位同事非常热衷于控制反转,这显然解决了这个问题......虽然我还没有完全接受它:)

于 2011-12-09T14:58:44.967 回答