Вопрос

Допустим, вы реализуете свою собственную версию 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песок Answerс Притворяйтесь, что у нас есть жесткий 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; }
}

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

Это было полезно?

Решение

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top