2009-12-08 8 views
4

Скажем, у меня есть трехуровневая архитектура (пользовательский интерфейс, бизнес и данные). Обычно я создаю 4-й проект под названием «Модель» или «Общий», чтобы сохранить объекты доступа к данным, и каждый из других проектов будет использовать этот проект.n-уровневая архитектура: лучшее место для хранения бизнес-объектов?

Теперь я работаю над проектом, в котором некоторые из моих объектов доступа к данным имеют такие методы, как Save() и т. Д., Которым нужен доступ к проекту Data. Итак, у меня была бы круговая ссылка, если бы я попытался использовать проект Model/Common в проекте Data.

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

+0

я должен уточнить, что я имел в виду бизнес-объекты на самом деле являются объекты доступа к данным - это классы со свойствами, относятся к полям в моих таблицах БД. – Prabhu

+0

Будьте осторожны, чтобы скомпоновать термины «уровень» и «слой». Похоже, что вы говорите, это слои, а не уровни. – RickNZ

ответ

2

Это то, что я имею в мой проект.

1.) Application.Infrastructure

  • Базовые классы для всех BusinessObjects, Busines объект коллекции, классы доступа к данным, и мои собственные атрибуты и утилиты как методы расширения, общие рамки проверки. Это определяет общую организацию поведения моего последнего приложения .net.

2.) Application.DataModel

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

3.) Application.DataAccess

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

4.) Application.DomainObjects

  • Бизнес-объекты и коллекции бизнес-объектов.
  • Enums.

5.) Application.BusinessLayer

  • Обеспечивает классы менеджер доступных из уровня представления.
  • HttpHandlers.
  • Мой собственный базовый класс.
  • Больше дела идут здесь ..

6.) Application.WebClient или Application.WindowsClient

  • Моя презентация слой
  • принимает ссылки от Application.BusinessLayer и Application.BusinessObjects.

Application.BusinessObjects используются по применению и они путешествуют во всех слоях, когда neeeded [за исключением Application.DataModel и Application.Infrastructure]

Все мои запросы определяются только Application.DataModel.

Приложение.DataAccess возвращает или принимает бизнес-объекты как часть любой операции доступа к данным. Бизнес-объекты создаются с помощью атрибутов отражения. Каждый бизнес-объект помечен сопоставлением атрибутов в целевой таблице в базе данных, а свойства в бизнес-объекте помечены сопоставлением атрибутов целевому coloumn в соответствующей таблице базы данных.

Моя система проверки позволяет мне проверять каждое поле с помощью назначенного параметра ValidationAttribute.

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

Образец бизнес-объекта будет выглядеть так в моем приложении.

User.cs

[TableMapping("Users")] 
public class User : EntityBase 
{ 
    #region Constructor(s) 
    public AppUser() 
    { 
     BookCollection = new BookCollection(); 
    } 
    #endregion 

    #region Properties 

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute 

    private System.Int32 _UserId; 

    private System.String _FirstName; 
    private System.String _LastName; 
    private System.String _UserName; 
    private System.Boolean _IsActive; 

    [DataFieldMapping("UserID")] 
    [DataObjectFieldAttribute(true, true, false)] 
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")] 
    public override int Id 
    { 
     get 
     { 
      return _UserId; 
     } 
     set 
     { 
      _UserId = value; 
     } 
    } 

    [DataFieldMapping("UserName")] 
    [Searchable] 
    [NotNullOrEmpty(Message = "Username Is Required.")] 
    public string UserName 
    { 
     get 
     { 
      return _UserName; 
     } 
     set 
     { 
      _UserName = value; 
     } 
    } 

    [DataFieldMapping("FirstName")] 
    [Searchable] 
    public string FirstName 
    { 
     get 
     { 
      return _FirstName; 
     } 
     set 
     { 
      _FirstName = value; 
     } 
    } 

    [DataFieldMapping("LastName")] 
    [Searchable] 
    public string LastName 
    { 
     get 
     { 
      return _LastName; 
     } 
     set 
     { 
      _LastName = value; 
     } 
    } 

    [DataFieldMapping("IsActive")] 
    public bool IsActive 
    { 
     get 
     { 
      return _IsActive; 
     } 
     set 
     { 
      _IsActive = value; 
     } 
    } 

    #region One-To-Many Mappings 
    public BookCollection Books { get; set; } 

    #endregion 

    #region Derived Properties 
    public string FullName { get { return this.FirstName + " " + this.LastName; } } 

    #endregion 

    #endregion 

    public override bool Validate() 
    { 
     bool baseValid = base.Validate(); 
     bool localValid = Books.Validate(); 
     return baseValid && localValid; 
    } 
} 

BookCollection.cs

/// <summary> 
/// The BookCollection class is designed to work with lists of instances of Book. 
/// </summary> 
public class BookCollection : EntityCollectionBase<Book> 
{ 
    /// <summary> 
    /// Initializes a new instance of the BookCollection class. 
    /// </summary> 
    public BookCollection() 
    { 
    } 

    /// <summary> 
    /// Initializes a new instance of the BookCollection class. 
    /// </summary> 
    public BookCollection (IList<Book> initialList) 
     : base(initialList) 
    { 
    } 
} 
1

Уровень данных должен хранить информацию в терминах строк и столбцов (возможно, используя типизированные DataSets, если хотите), если вы используете реляционный бэкэнд. Нет «бизнес-объектов».

Бизнес-уровень должен использовать ваши «бизнес-объекты». Он может иметь ссылку на проект BusinessObjects.

В итоге:

  • UI имеет ссылки на бизнес и BusinessObjects
  • Бизнес имеет ссылки на BusinessObjects и Data

Надежда это помогает.

0

Я бы предложил создать и связать то, что вы хотите в проекте модели, и реализовать это определение в слое данных. Таким образом, все три (четыре?) Проекта могут использовать это определение, не зная, как оно реализовано.

0

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

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

8

Я не думаю, что у вас есть ваш n-ярус совершенно правильно. Похоже, вы строите более двухъярусные системы.

В реальном 3-уровневом проекте только ваш уровень данных позволяет разговаривать с базой данных. У вас это есть с вашими «Модельными» или «Обычными» проектами. Этими проектами являются ваш уровень данных. Но там, где вы отклоняетесь, только бизнес-уровень должен быть разрешен для общения с ними. Ваш код презентации не должен позволять вообще разговаривать с проектами уровня данных.

n-Tier приходит, когда у вас есть более 3 "ярусов", но те же самые принципы: каждый уровень знает, как использовать (и требует только ссылку) ниже, а затем предоставляет api для уровня выше него. В моих собственных проектах я беру типичный уровень представления, бизнеса и данных и предоставляю 4-й уровень перевода между бизнесом и данными. Таким образом, уровень данных может возвращать общие типы, такие как набор данных, datatable и datarow, а бизнес-уровень только должен работать с точки зрения строго типизированных бизнес-объектов. Уровень перевода только преобразует между общими объектами данных и сильно типизированными объектами.Таким образом, изменение одного из традиционных уровней менее вероятно потребует изменения в другом.

+0

Хорошие моменты, но вам нужно «не» в последнем предложении второго абзаца. – jason

+0

исправлено, спасибо за указание. –

+0

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

0

Это действительно зависит от шаблона, если вы используете MVC (шаблон контрольного контроллера), модель Является специфическим для домена представлением данных, на которых работает приложение (как правило, с помощью ORM), мы используем DATA проект для этих классов.

Модели не являются объектами доступа к данным, поэтому доступ к данным становится в виде репозиториев в другом проекте. Услуги для бизнес-правил и, наконец, веб-проект. При таком подходе Data.dll упоминается во всех проектах. Модель похожа на вездесущий.

DATA(Domain Model) -> REPOSITORY(Data Access) -> SERVICE(Business Rules) -> WEB 
1

У меня есть проект BusinessObjects, на стороне сервера хранения отображения (ORM) и соответствующую услугу DATAACCESS разоблачением операции CRUD на них (и другие тоже, как GETALL) и т.д.