ASP.NET MVC - контроллеры сервисного уровня <-> - PullRequest
2 голосов
/ 01 декабря 2011

Допустим, вы реализуете собственную версию 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) имеет прямой доступ к Question s и Answer s. Притворимся, что у нас есть некоторые трудности с публикацией вопросов и ответов. Это хорошая идея, чтобы эта логика была сосредоточена в «одном месте» - на уровне обслуживания. Если ваш клиентский код имеет доступ к Question s, возможно, когда-нибудь кто-нибудь решит добавить «немного логики» к одному из ваших контроллеров, что в принципе является плохой идеей.

Я думаю об определении количества 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; }
}

И так далее. Это хорошая практика или ты считаешь, что это перегрузка? Каковы общие подходы здесь?

1 Ответ

1 голос
/ 09 декабря 2011

Я недавно реализовал в точности то, о чем вы говорите, используя множество 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 в основном удаляет большую часть работы за вас.

Мой коллега очень заинтересован в Inversion of Control, которая, по-видимому, решает эту проблему ... хотя я еще не полностью продал ее:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...