2009-04-06 2 views
10

я в настоящее время есть приложение, которое состоит из: интерфейса пользователя (веб-страницы) BLL (менеджер & домена объектов) DAL (DataAccess класса для каждого из моих доменных объектов).Что для возвращения из DAL в BLL

Я использую в пользовательском интерфейсе для поиска объекта домена.

protect sub Button1_Click() 
{ 
    IBook book = BookManager.GetBook(txtID.Text); 
} 

Вот мой BLL

public class BookManager 
{ 
    public static IBook GetBook(string bookId) 
    { 
     return BookDB.GetBook(bookId); 
    } 
} 

public class Book : IBook 
{ 
    private int? _id 
    private string _name; 
    private string _genre; 

    public string Name 
    { 
     get { return _name; } 
     private set 
     { 
      if (string.IsNullOrEmpty(value)) 
       throw new Exception("Invalid Name"); 
      _name = value; 
     } 
    } 

    public string Genre 
    { 
     get { return _serial; } 
     private set 
     { 
      if (string.IsNullOrEmpty(value)) 
       throw new Exception("Invalid Genre"); 
      _genre = value; 
     } 
    } 

    // Other IBook Implementations 

} 

И, наконец, вот мой DAL

public class BookDB 
{ 
    public static IBook GetBook(int id) 
    { 
     // Get Book from database using sproc (not allowed to use any ORM) 
     // ?? Create IBook Item? 
     // return IBook 
    } 

Как бы один создать объект IBook и вернуть его к менеджеру? Я подумываю вернуть DataTable из BookDB в BookManager и создать объект Book и вернуть его, но это кажется неправильным. Есть ли другой способ сделать это?

Редактировать: Я решил разделить каждый слой на проект и столкнулся с проблемой циклической зависимости в слое DAL при попытке добавить ссылку на BLL. Я не могу получить доступ к классу книг или интерфейсу или что-либо в BLL из DAL. Должен ли я просто использовать объекты ado.net здесь и создать мой менеджер для создания фактического объекта из объекта ado.net? Вот как ее изложил

BLL.Managers - BookManager 
BLL.Interfaces IBook 
BLL.Domain - Book 
DAL - BookDB. 

спасибо!

+0

Обычно DAL не должна содержать ссылки на BLL. BLL, howerver должны содержать ссылку на DAL. – Martin

+0

Если бы я должен был добавить проект модели, то должен ли я перемещать как фиктивные классы, так и классы домена/интерфейсы в этот проект? – AlteredConcept

ответ

0

DataTable, который вы хотите вернуть, связан с базой данных, и для BLL ему не нужно заботиться о том, какую базу данных вы используете и что такое схема. Вы можете использовать DB-Object Mapper для сопоставления dbtable с объектом в DAL.

+0

DataTable не связан с базой данных. Он специфичен для реляционной модели, но представляет собой «несвязанную» таблицу в памяти и не связан с какой-либо базой данных. Он также не предоставляет информацию о любой базе данных, которая могла ее заполнить. –

0

Если вы не хотите возвращать DataTable, вы можете передать реализацию IBook из BookManager для заполнения DAL.

5

Вы можете создать фиктивные объекты книги, содержащие только данные. Получить, установить свойства и значения членов. Эта книга имеет 1 свойство для каждого поля в базе данных, но ничего не подтверждает.

Вы заполняете объект из db, а затем отправляете его в BLL.

Если вы хотите сохранить объект, вы также отправляете его в BLL.

Ваши классы в BLL могут обернуть эти объекты, если это имеет смысл. Таким образом, легко просто отправить его обратно в DAL.

пустышки Книга:

public class DummyBook:IBook 
{ 
    private nullable<int> _id; 
    private string _name; 
    private string _genre; 

    public string Id 
    { 
     get {return _id;} 
     set {_id = value;} 
    } 

    public string Name 
    { 
     get {return _name;} 
     set {_name = value;} 
    } 

    public string Genre 
    { 
     get {return _genre;} 
     set {_genre= value;} 
    } 

} 

DAL Книга:

public class DALBook 
{ 
    public static IBook:GetBook(int id) 
    { 
     DataTable dt; 
     DummyBook db = new DummyBook(); 

     // Code to get datatable from database 
     // ... 
     // 

     db.Id = (int)dt.Rows[0]["id"]; 
     db.Name = (string)dt.Rows[0]["name"]; 
     db.Genre = (string)dt.Rows[0]["genre"]; 

     return db; 
    } 

    public static void SaveBook(IBook book) 
    { 
     // Code to save the book in the database 
     // you can use the properties from the dummy book 
     // to send parameters to your stored proc. 
    } 
} 

BLL Книга:

public class Book : IBook 
{ 
    private DummyBook _book; 

    public Book(int id) 
    { 
     _book = DALBook.GetBook(id); 
    } 

    public string Name 
    { 
     get {return _book.Name;} 
     set 
     { 
      if (string.IsNullOrEmpty(value)) 
      { 
       throw new Exception("Invalid Name"); 
      } 
      _book.Name = value; 
     } 
    } 

    // Code for other Properties ... 



    public void Save() 
    { 
     // Add validation if required 
     DALBook.Save(_book); 
    } 

} 

Edit1: Фиктивные классы должны идти в своем собственном проекте (модель, как указано в комментариях в порядке).Ссылки будут работать следующим образом:

DAL Ссылки на проект модели.
BLL ссылается на модель и DAL.
Интерфейс пользователя BLL.

+0

Какой слой вы бы ввели DummyBook? Прямо сейчас у меня есть три проекта. 1) Web Project (Содержит Ссылку на УСК) 2) BLL Библиотека классов (содержит Ссылку на DAL) 3) DAL Библиотека классов (содержит Ссылку на УСК) – AlteredConcept

+0

@AlteredConcept: Вы можете создать еще один проект модели или такую ​​ – smoothdeveloper

1

Я бы, вероятно, использовал ExecuteReader для создания объекта в коде из базы данных. Причина этого в том, что у datatable больше накладных расходов, чем у читателя, поскольку он имеет больше функциональности (и, вероятно, был создан читателем). Поскольку вы не выполняете обновления/удаления с использованием данных, вам не нужны накладные расходы.

Как говорится, я бы поставил статический вспомогательный метод в классе BookManager.

internal static IBook BookFromReader(IDataReader reader) 
{ 
    Book B = new Book(); 
    B.Prop = reader.GetString(0); 
    B.Rinse = reader.Repeat(); 
    return B; 
} 

Причина этого в том, что причина, по которой у вас есть интерфейс, заключается в том, что вы можете изменить реализацию. Вы можете в будущем использовать INOVEL: IBook, IReference: IBook и т. Д., А затем вы захотите провести абстрактную фабричную реализацию на вашем уровне данных.

public static IBook GetBook(int id) 
{ 
    // SqlCommand Command = new Command("SQL or sproc", ValidConnection); 

    using(IDataReader DR = Command.ExecuteReader(id)) 
    { 
     // checking omitted 
     switch(DR.GetInt32(1)) 
     { 
      case 0: 
       return BookManager.BookFromReader(DR); 
      case 1: 
       return BookManager.NovelFromReader(DR); 
      etc 
     } 
    } 
} 

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

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

Вот ссылка с блога я прочитал на эту тему: http://codebetter.com/blogs/patricksmacchia/archive/2008/12/08/advices-on-partitioning-code-through-net-assemblies.aspx

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

Удачи :-)

+0

спасибо бен , Что помогает. По какой-то странной причине я думал, что, поскольку BookManager Calls BookDB.GetBook, было бы немного странно называть его изнутри в BookDB.GetBook Method. Не знаю, почему я так думал. Еще раз спасибо! – AlteredConcept

+0

Вы можете поместить статический вспомогательный метод в DAL или BLL. Я подозреваю, что я буду пылать за упоминание места размещения в BLL. Я выбираю BLL, потому что DAL можно «поменять», пока вспомогательные методы все еще применяются ... –

+0

Я думал, что у меня есть ответ здесь, я удивлен, увидев -1. Будет ли -1 прокомментировать через комментарий? –

2

BookDB должен вернуть экземпляр IBook. Мне нравится шаблон репозитория, который связан с отображением из db в домен.

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

+0

Как бы вы структурировали вышеприведенное использование шаблона репозитория без orm? – AlteredConcept

1

На мой взгляд, вы никогда не должны допускать доступ к DAL BLL. Это неоправданная зависимость.

Ввод класса книги в новый проект (возможно, с именем DomainModel) позволит зафиксировать круглую ссылку. Вы могли бы сделать что-то вроде этого:

Проект BLL ссылка DAL и DomainModel

ссылка DAL Проект DomainModel

ссылка UI проекта BLL и DomainModel

Проект DomainModel ссылка ничего

0

Чтобы следовать предназначенная модель. уровень доступа к данным (DAL) отвечает за получение и отправку данных из источника данных и из источника данных.

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

Ваш бизнес-логический уровень (BLL) не должен заботиться о том, как DAL достигает получения или записи данных.

Для связи между BLL и DAL вы должны использовать нейтральные объекты.

Ваш BLL передает свойства объекта как отдельные параметры методам в DAL. параметры в DAL нейтральны, используя строки, int, bool, любые другие объекты .NET, которые не являются специфичными для версии базы данных, с которой вы общаетесь, и не являются конкретными типами, существующими только в вашем BLL.

DAL будет извлекать данные из того, где когда-либо когда-либо, и возвращать нейтральный объект данных вызывающему. Например, это может быть DataSet или DataTable или любой другой объект, не относящийся к используемому типу/версии базы данных. Следовательно, DataSet и DataTable являются объектами в пространстве имен System.Data, а не в пространстве имен System.Data.SQL и т. Д. ....

В сущности: - BLL проходит нейтральные типы к ДАЛ (например: строка, INT, BOOL, длинные, с плавающей точкой, и т.д ..) - DAL отвечает за преобразование этих типов в типы баз данных specifci при необходимости перед передачей их на источник данных DAL возвращает нейтральные типы данных в BLL (например, DataSet, DataTable и т. д.) - BLL несет ответственность за использование содержимого этих нейтральных типов данных для создания, заполнения и возврата конкретных бизнес-объектов

Ваш BLL должен ссылаться на ваш DAL. это оно.

Вы можете полностью игнорировать эту модель и взломать столько, сколько было предложено ранее с помощью IBOOK и т. Д., Но вы не используете намеченную модель и можете также бросить все это в единую сборку, в любом случае, поддерживать его независимо.

+0

Я цитирую wiki здесь: «Уровень [Data] сохраняет данные нейтральными и независимыми от серверов приложений или бизнес-логики». Предоставление DAL Business Objects, которые являются «немыми», не противоречит этому. Пока ваши бизнес-объекты не проверяют себя и представляют собой просто хранилище базовых типов данных, завернутых в класс, их лучше использовать. Вы ничего не получаете, если вы выполняете Employee_DAL.Save (myEmployee.Id, myEmployee.Name, myEmployee.JobTitle) и Employee_DAL.Save (myEmployee). Второй - намного чище. – colithium

Смежные вопросы