Требуется некоторое руководство по архитектуре ASP.NET MVC 3

Я опытный разработчик .NET, который в основном работает с веб-формами. Я знаком с MVC, но пока не использовал его коммерчески. В настоящее время я занимаюсь самообразованием в этой области, и я несколько смущен различиями в мнениях по предмету архитектуры, позвольте мне придать этому вопросу понимание, что нет правильного или неправильного ответа, но я просто ищу то, что элегантное решение.

Я начну с того, что говорю, что я не использую инфраструктуру сущности или какой-либо ORM - я бы хотел напрямую реализовать свои собственные бизнес-объекты и код доступа к данным (используя ADO, SPROCS и т.д.), чтобы обеспечить их оптимальность, это личное предпочтение. Именно здесь я изо всех сил пытаюсь найти согласованную информацию, поскольку большинство информации относится к использованию LINQ to SQL или Entity Framework.

MY приложение структурировано со следующими проектами:

  • Веб (веб-приложение MVC 3)
  • Модели (библиотека классов)

Есть только два проекта, потому что у меня проблемы с развязкой; это корень моего вопроса. Моя библиотека классов моделей содержит...

  • классические бизнес-объекты с полями и свойствами
  • Класс репозитория для каждого бизнес-объекта, который содержит код доступа к данным (ADO.NET прямо SqlDataReaders и т.д.)
  • Интерфейс для каждого класса репозитория

Проблема, которую я имею, - это зависимость между всеми этими уровнями. Это не совсем так!

1. Бизнес-объекты должны содержать методы, реализующие бизнес-логику, поэтому помимо полей и свойств существуют методы для реализации любой требуемой логики?

2. Классы репозитория выполняют код доступа к данным, но знают о бизнес-объектах, это опять не так, код доступа к данным должен находиться в собственной библиотеке классов и ничего не знать об объектах?

3. Контроллеры (на веб-уровне) используют интерфейсы репозитория, но почему? Они не должны содержать бизнес-логику, "модель" или "бизнес-объект" должны? Контроллеры, конечно же, не должны содержать бизнес-логику, поэтому это неправильно. Я не хочу, чтобы бизнес-логика в репозиториях попадала в базу данных.

Я изо всех сил стараюсь найти элегантную архитектуру для приложения, просто базовый план того, как реализовать свои собственные объекты, свой собственный код доступа к данным и обеспечить, чтобы приложение было слабо связано. Может ли кто-нибудь предложить мне какие-либо указания?

Ответ 1

Я бы предложил несколько изменений в структуре вашего решения.

Например, проекты могут быть структурированы следующим образом: -

Основная библиотека

Это будет простой POCO, который будет представлять ваши данные домена и интерфейсы для любых служб. Здесь нет бизнес-логики. Просто простые свойства.

например.

public class User  {     public int UserId {get; задавать; }     public string Имя {get; задавать; }  }

- Core
      \Entities <-- Poco's
      \Services <-- Interfaces for services

Услуги

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

Repository

Здесь вы делаете свой основной материал базы данных. Вы сказали, что не используете L2S или EF и т.д. Нет проблем. Я серьезно всерьез посмотрю на использование Micro-ORM, например Dapper или Massive.

Испытания

Вы проводите тесты на единицу и интеграцию, верно? Я рекомендую xUnit или nUnit для среды тестирования.

Веб-приложение

Это приложение MVC3. Я бы рекомендовал использовать StructureMap для вашей инъекции зависимостей. (Вы используете IoC/DI, правильно?)

Вы можете подумать сначала → что СООО много проектов, не так ли? хорошо, легко разбить это только на два проекта.

  • Веб-приложение
  • Проект тестирования

а основная библиотека, службы, репозиторий существуют в проекте веб-приложения в виде папок.

Попытайтесь не переустроить решение Visual Studio. Большинство людей думает, что им нужно много проектов и дерьмо загрузок абстракции.. потому что то, что они думают, все остальные делают, и это правильно. Ну, этот ход мыслей очень рано в начале 2000 года.. и в 2012 году - с тех пор многое изменилось.

Попробуйте использовать DI/IoJ, NuGet для загрузки этих библиотек в ваше решение, Micro-OR/M для доступа к данным и проекта тестирования.

Несколько проектов, чтобы проверить, re: как вещи выложены:

Ответ 2

  • возможно, если модель требует этого. большинство моделей - простые dtos с публичными свойствами. но вы можете так же легко инкапсулировать часть этого.

  • не совсем. репозиторий представляет собой набор бизнес-объектов. он может создавать экземпляры этих объектов из базы данных.

    Контроллеры
  • - это точка входа для контроля того, что происходит на сервере. reads будет загружать данные из репозиториев в модели просмотра и вставлять модели представления в представление. записи будут загружать данные из репозиториев, обновлять домен и сохранять изменения. затем перенаправляется на действие контроллера чтения.

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

независимо от того, используете ли вы базу данных или ORM не имеет значения, у вас есть те же функции в ваших репозиториях.

Ответ 3

Я думаю, что начало маленького - это хорошо, а затем, когда возникает необходимость, вы начинаете расширять свое представление и начинаете разделять слои по мере необходимости. Зачем отделять свою работу от проектов 20ish, если у вас есть 2 модели, 1 представление и одна таблица для запроса и обновления в базе данных.

Начните с малого и позвольте "нужно" управлять дизайном. Если вам нужно прочитать/написать много таблиц в базе данных, возможно, пришло время начать использовать шаблон репозитория. Вы обнаружите, что вам сейчас нужны по меньшей мере 10 или более разных моделей, на которые теперь может потребоваться внедрение библиотеки для размещения DTO/моделей и извлечения их из веб-приложения.

Если вам, например, требуется написать модульные тесты или сделать TDD, вы обнаружите, что сразу можете придумать, как можно быстро имитировать репозиторий, бизнес и сервисный уровень.

Однако, ради аргумента, я видел проекты, похожие на приведенные ниже (но большинству не нужен этот уровень разделения):

  • Веб-проект; использование библиотеки сервисов и библиотеки dto.
  • Сервисная библиотека; использование библиотеки бизнес-уровня и библиотеки dto.
  • Библиотека бизнес-уровня; использование библиотеки репозитория, библиотеки объектов и библиотеки dto.
  • Библиотека репозитория; использование библиотеки объектов
  • Библиотека сущностей
  • Библиотека dto

Большинство из них были еще больше разбиты на отдельные библиотеки, содержащие интерфейсы в одном и реализации в другом и т.д. В некоторых проектах, над которыми я работал, было более 50 библиотек, чтобы отделить большинство, если не все, но оно всегда основывалось на требовании или необходимости.

Идея приведенного выше примера состоит в том, чтобы веб-приложение просто касалось передачи DTO на вызов службы и получения DTO обратно из служебного вызова.

Вы можете использовать DTO большую часть времени как Модели, но иногда, если вам нужна плоская модель, основанная на нескольких DTO, вы можете создать свою собственную модель представления в качестве обертки, чтобы сгладить несколько DTO.

Услуга идет и вызывает метод в диспетчере, передавая DTO, который находится в библиотеке бизнес-уровня. Этот менеджер будет использовать DTO и сопоставить его с одним или несколькими объектами и вызывает методы в репозитории, передающие эти объекты. Репозиторий возвращает объекты, которые менеджер использует для построения DTO для отправки.

Существует много способов сделать это, и я уверен, что ни один из них не будет единственным правильным способом.

Вы можете добиться дальнейшего разделения и независимости, используя инфраструктуру инъекций зависимостей, например, Ninject.

Вышеприведенный пример - всего лишь один пример. Это может отлично работать для одной группы людей, в то время как другая считает это неприемлемым. Это зависит от многих факторов, причем размер проекта является одним из основных.

Кроме всего прочего, всегда начинайте с архитектуры с управляемым размером, вы будете постоянно перегруппировываться, так как возникает необходимость в изменении, будь то для издевательств в модульных тестах, количество моделей стало неуправляемым в пределах веб-приложение или теперь отдельная команда должна написать уровень обслуживания, и вы не хотите, чтобы это мешало вашей разработке, теперь уровень сервиса может потребляться другим слоем пользовательского интерфейса, а не только вашим веб-интерфейсом и т.д....

Ответ 4

Несколько точек:

  • Нет проблем с наличием "бизнес-логики" в ваших репозиториях. На самом деле большая часть вашей "бизнес-логики" будет там. Ваши репозитории содержат запросы, и если эти запросы вообще интересны, эти запросы будут тесно связаны с вашей "бизнес-логикой".

  • Нет проблем с наличием "бизнес-логики" в ваших контроллерах. Ваши контроллеры контролируют ваш интерфейс и как работает ваш пользовательский интерфейс - "бизнес-логика".

  • По определению, в многоуровневой архитектуре каждый уровень знает об открытом интерфейсе слоя над ним. В вашем доступе к данным можно увидеть общий интерфейс вашего домена. Уровень пользовательского интерфейса может видеть общий интерфейс вашего уровня обслуживания.

  • Если ваш проект настолько мал, что вы можете позволить себе вручную вводить свой собственный уровень доступа к данным, а не использовать ORM или аналогичный, то наличие полностью развязанной архитектуры Starship Enterprise, вероятно, только сделает вашу жизнь сложнее, (И этим я подразумеваю, что я думаю, что вы сумасшедший, записываете свой собственный уровень доступа к данным - по крайней мере, попробуйте облегченную структуру, такую ​​как Dapper).

  • Основывайте свои варианты на ваших потребностях. Спросите себя: "Почему X нужно отделить от Y". Ответ может быть "Так что я могу издеваться над X, когда я тестирую единицы Y". Ответ может быть "Поэтому я могу использовать X в другом проекте, который не должен знать о Y". Если вы не можете найти ответ, тогда YAGNI.