ASP.NET MVC - 服务层< - >控制器

时间:2011-11-30 20:19:06

标签: asp.net-mvc controller dto service-layer

假设您正在实现自己的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控制器)可以直接访问QuestionAnswer。假装我们有一些与发布问题和答案相关的艰难BL。将这种逻辑集中在一个“单一位置” - 在服务层上是个好主意。如果您的客户端代码可以访问Question,那么有一天可能会有人决定向您的一个控制器添加“一点点逻辑”,这基本上是个坏主意。

我正在考虑定义一些将成为服务接口一部分的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; }
    ...
}

发布问题时,请求应仅包含TitleTextPoster。所以,我将定义一个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; }
}

等等。这是一种很好的做法还是你认为它是过度工程?这里有哪些常用方法?

1 个答案:

答案 0 :(得分: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基本上可以为你删除大部分的驴工作。

我的一位同事非常热衷于控制反转,这显然解决了这个问题......虽然我还没有完全卖掉它,但是它已经完成了:)