Вопрос

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

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

Мой обычный бизнес структура бизнеса является это (основной вид на него):

  • Бизнес
    • Услуги
      • FOOCOMPONENT
        • Fooheelpers
        • Fooworkflows.
      • Бахкомпонент
        • Божевины
        • Bahworkflows.
    • Утилиты
      • Общий
      • Исключения
      • Импортеры
      • так далее...

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

XXXHELPERS дают мне доступ к сохранению, редактированию и загрузке соответствующих объектов, но где я положу логику сохранения объектов с дочерними объектами.

Например:

У нас есть следующие объекты (не очень хорошие объекты, которые я знаю)

  • Работник
  • По службе работы
  • Рождаемость
  • Сотрудника

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

Но я немного потерей, где я бы поставил эту логику, и что позвонить в сектор, будет ли он пойти на коммунальные услуги, как этот сотрудник?

Что бы ты сделал? И я знаю, что это все предпочтение.

Более подробный макет

Рабочие процессы содержат все вызовы непосредственно к DataRepository, например:

public ObjectNameGetById(Guid id)
{
    return DataRepository.ObjectNameProvider.GetById(id);
}

А затем поставщика помощников доступа к рабочим процессам:

public ObjectName GetById(Guid id)
{
    return loadWorkflow.GetById(id);
}

Это необходимо сократить дублирующий код, так как вы можете иметь один звонок в рабочем процессе, чтобы GetBysomeProperty, а затем несколько звонков в помощнике, которые могли бы сделать другие операции и возвращать данные по-разному, плохой пример будет публичным GetBiDasc и Gethbyiddesc

Разделив вызовы в модели данных, используя регистрарифриво, это означает, что можно было бы высказать модель для другого экземпляра (это было мышление), но ProvireHelper не был разбит, чтобы он не был взаимозаменен, как это Хардкод к EF к сожалению. Я не намерен изменить технологию доступа, но в будущем может быть что-то лучшее или просто то, что все крутые дети теперь используют, что я могу использовать вместо этого.

ProjectName.core.

projectName.Business
    - Interfaces
        - IDeleteWorkflows.cs
        - ILoadWorkflows.cs
        - ISaveWorkflows.cs
        - IServiceHelper.cs
        - IServiceViewHelper.cs
    - Services
        - ObjectNameComponent
            - Helpers
                - ObjectNameHelper.cs
            - Workflows
                - DeleteObjectNameWorkflow.cs
                - LoadObjectNameWorkflow.cs
                - SaveObjectNameWorkflow.cs
    - Utilities
        - Common
            - SettingsManager.cs
            - JavascriptManager.cs
            - XmlHelper.cs
            - others...

        - ExceptionHandlers
            - ExceptionManager.cs
            - ExceptionManagerFactory.cs
            - ExceptionNotifier.cs


projectName.Data
    - Bases
        - ObjectNameProviderBase.cs
    - Helpers
        - ProviderHelper.cs
    - Interfaces
        - IProviderBase.cs
    - DataRepository.cs

projectName.Data.Model
    - Database.edmx

projectName.Entities (Entities that represent the DB tables are created by EF in .Data.Model, this is for others that I may need that are not related to the database)
    - Helpers
        - EnumHelper.cs

ProjectName.presenation.

(Зависит от того, какой вызов приложения)

projectName.web
projectName.mvc
projectName.admin

Тестовые проекты

projectName.Business.Tests
projectName.Data.Test
Это было полезно?

Решение

+1 на интересный вопрос.

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

Но сначала мой предпочтительный подход здесь - довольно распространенная архитектура предприятия, которую я постараюсь подчеркнуть вкратце, но там гораздо больше глубины. Это требует некоторых радикальных изменений в мышлении - использование фреймворда NhiBernate или Entity, чтобы позволить вам непосредственно запрашивать свою модель объекта напрямую и позволить обменам ORM с такими вещами, как отображение, и из базы данных и ленивых нагрузочных отношений и т. Д. Это позволит вам реализовать Вся ваша бизнес-логика внутри доменной модели.

Сначала ярусы (или проекты в вашем решении);

YreaPlication.domain.

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

YourApplication.data.data.

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

Например, в маловероятном классах в маловероятно, что вы хотели бы посмотреть на сотрудника (предположение, что я знаю, но вы получаете линию счета-фактуры, - это лучший пример, вы вообще доберетесь до линий счетов через счет, а не загрузка их самостоятельно). Как таковые, классы репозитория, из которых у вас есть один класс за совокупный корню, будут нести ответственность за получение исходных объектов из базы данных, используя соответствующую базу данных, реализуя любые стратегии запросов (например, пейджинг или сортировка) и возвращение совокупного корня на потребитель. Репозиторий потребляет текущий активный контекст данных (isessess in nibernate) - как создается эта сессия, зависит от того, какой тип приложения вы строите.

YourApplication.workflow.

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

Другие ярусы, затем зависят от вашей архитектуры, и приложение, которое вы реализуете.

YemoApplication.yourChenpresentationTier.

Если вы используете веб-сервисы, чтобы распространить свои уровни, то вы бы создавали контракты DTO, которые представляют только данные, которые вы подвергаете домене и потребителям. Вы бы определили сборщики, которые знали бы, как перемещать данные в эти контракты из домена (вы никогда не будете отправлять объекты домена на провод!)

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

Если вам не нужно распространять свои ярусы, помнить первое правило распределенных архитектур, не распространяются, то вы будете использовать рабочий процесс / услуги и репозитории непосредственно из в рамках ASP.NET, MVC, WPF, WinForms и т. Д.

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

В приложении настольных компьютеров WPF или WinForms у вас будет контекст за форму. Это гарантирует, что редактирует доменные объекты в диалоговом окне редактирования, которые обновляют модель, но не делайте его в базе данных (например, выбрана Отмена) Не вмешиваться в другие контексты или в худшем случае случайно сохраняются.

Внедрение зависимости

Все вышеперечисленное будет определяться как интерфейсы первыми, с конкретными реализациями, реализованными посредством внедрения IOC и зависимостей (мое предпочтение является виндзор замка). Это позволяет вам изолировать, макет и модуль тестировать отдельные ярусы независимо и в большом применении, инъекция зависимости - это спасатель жизни!

Эти пространства имен

Наконец, причина, по которой я потеряю пространство имен помощников, в модели выше, вам они не нуждаются в них, но и, как и именные пространства, которые они дают ленивому разработчикам, не думать, где кусок кода логически сидит. Myapp.helpers. * И myapp.utility. * Просто означает, что если у меня есть какой-код, скажите обработчик исключения, который, возможно, логически принадлежит в MyApp.data.Repositories.Customers (возможно, это клиент Ref не является уникальным исключением), ленивый Разработчик может просто разместить его в MyApp.Utility.CustomerRefnotuniqueException, не надо думать.

Если у вас есть общий код типа Framework, который вам нужен, добавьте проект myapp.framework и соответствующие пространства имен. Если вы добавите новую модельную связующее, поместите его в myapp.framework.mvc, если это общая функциональность ведения журнала, поместите ее в myapp.framework.logging и так далее. В большинстве случаев нет необходимости вводить утилиту или помощников пространства имен.

Заворачивать

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

Ура Тони

Другие советы

Существует хорошая диаграмма и описание на этой странице о макете приложения, Alhtough выглядит дальше вниз по статье. Приложение не разделяется на физические слои (отдельный проект) - Сущность Рамки Poco Репозиторий

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