Добрый день, друзья.
Помогите, пожалуйста, понять как решить проблему взаимодействия между DAL и BLL.
Я использую custom entities (т.е. не DataSet'ы, а свои классы, см. пример кода ниже). Если я выделяю DAL в отдельную сборку, я не могу поместить ссылку на BLL, т.к. circular reference. Поэтому для того, чтобы я мог получить доступ из DAL к объектам бизнес логики мне нужно еще создать IPerson (куда вытащить все property Person, которые используются из DAL) и сделать Factory для Person, чтобы в DAL можно было создавать экземпляр Person.
Поэтому получается, для одного класса Person, мне нужно сделать как минимум 4 класса: BLL.Person, IDAL.Person, Model.IPerson, DAL.Person. Что получается слишком громоздко. И тем более, если в BLL.Person я получаю список, мне нужно будет каждый IPerson кастить в Person, что не совсем удобно.
Вопрос 1: Как обычно решается подобная проблема?
Читал статью
Application Architecture for .NET: Designing Applications and Services.
Вопрос 2: Подскажите чем Business Entity отличается от Business Component.
Недавно просматривал книгу Applying Domain-Driven Design and Patterns, и как я понял автор предлагает разделять классы Domain (состояние) и Business Logic (поведение). Мало того, говорит что классы Business Logic можно делать статическими, содержащими одни только методы, которые принимают экземпляр класса как аргумент, например static OrderManager.Save(Order order), а не Order.Save().
Вопрос 3: Правильно ли я думаю, что Business Entity это синоним Domain?
Не могу понять такой подход.
Вопрос 4: Проясните пожалуйста как подобную вещь с наследованием (см. ниже) сделать на Domain-Driven Design?:
/// BLL
enum PersonKind
{
Student,
Professor
}
abstract class Person
{
public Guid Id;
public string UserName;
public abstract PersonKind Kind { get; } // хранится в базе, при вытаскивании записи - создается нужный класс
public void Register()
{
IDAL.Save(this); // IDAL - для простоты. Объект реализующий IDAL.Person и содержащий методы DAL
OnRegister();
}
protected abstract OnRegister();
// вызывается из базы
public static GetInstance(PersonKind kind)
{
if (kind == PersonKind.Professor) return new ProfessorPerson();
else return new StudentPerson();
}
}
class ProfessorPerson : Person
{
protected override PersonKind Kind { get { return PersonKind.Professor; } }
public string Subject; // некое дополнительное проперти только для Professor'а
// просто кастомная логика, показать, что ProfessorPerson и StudentPerson ведуть себя по-разному
// таких функций может быть много и у них логика будет сложнее.
protected override void OnRegister
{
RegisterNewEmployee();
ScheduleManager.RecalculateSubject(Subject);
}
private void RegisterNewEmployee() { ... }
}