Что вернуть из DAL в BLL - PullRequest
10 голосов
/ 06 апреля 2009

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

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

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 и вернуть его, но это не так. Есть ли другой способ сделать это?

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

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

Спасибо!

Ответы [ 7 ]

5 голосов
/ 06 апреля 2009

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

Вы заполняете объект из БД, а затем отправляете его в 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.

2 голосов
/ 06 апреля 2009

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

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

1 голос
/ 08 июля 2009

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

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

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

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

Ссылка на пользовательский интерфейс проекта BLL и DomainModel

Project DomainModel, ссылка ничего

1 голос
/ 06 апреля 2009

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

При этом я бы сделал статический вспомогательный метод в классе 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 заключается в том, что вы можете кэшировать результаты поиска. Вы можете иметь словарь, в котором хранятся книги, которые вы искали, чтобы уменьшить количество дополнительных вызовов БД для объектов, которые вы уже вернули. Когда происходит обновление, вы удаляете кэшированную сущность ... Это еще один пост.

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

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

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

Удачи: -)

0 голосов
/ 04 июня 2010

Чтобы следовать намеченной модели. Уровень доступа к данным (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 передает нейтральные типы в DAL (например, string, int, bool, long, float и т. Д.) - DAL отвечает за преобразование этих типов в типы спецификаций базы данных, если это необходимо, перед передачей их в источник данных. DAL возвращает нейтральные типы данных в BLL (например, DataSet, DataTable и т. Д.) - BLL несет ответственность за использование содержимого этих нейтральных типов данных для создания, заполнения и возврата конкретных бизнес-объектов

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

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

0 голосов
/ 06 апреля 2009

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

0 голосов
/ 06 апреля 2009

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

...