Извините за то, что этот момент здесь повсюду ... но я чувствую себя как собака, гоняющаяся за моим хвостом, и я все в замешательстве в этот момент.
Я пытаюсь найти самый чистый способ разработки трехуровневого решения (IL, BL, DL), где DL использует ORM для абстрагирования доступа к БД.
Везде, где я видел, люди используют LinqToSQL или LLBLGen Pro для генерации объектов, которые представляют таблицы БД, и ссылаются на эти классы во всех 3 слоях.
Похоже, что 40 лет шаблонов кодирования были проигнорированы - или произошел сдвиг парадигмы, и я пропустил объяснительную часть о том, почему это совершенно нормально.
Тем не менее, похоже, что есть еще основания для желания быть независимым от механизма хранения данных - посмотрите, что только что произошло с LinqToSQL: против него написано много кода - только для MS
бросить его ... Так что я хотел бы выделить часть ORM как можно лучше, просто не знаю как.
Итак, возвращаясь к абсолютным основам, вот основные части, которые я хотел бы собрать очень чистым способом:
Сборки, с которых я начинаю:
UL.dll
BL.dll
DL.dll
Основные классы:
Класс Message, имеющий свойство, представляющее коллекцию (называемую MessageAddresses) объектов MessageAddress:
class Message
{
public MessageAddress From {get;}
public MessageAddresses To {get;}
}
Функции на слой:
BL предоставляет метод для пользовательского интерфейса, называемый GetMessage (идентификатор Guid), который возвращает экземпляр сообщения.
BL в свою очередь оборачивает DL.
DL имеет ProviderFactory, которая оборачивает экземпляр Provider.
DL.ProviderFactory выставляет (возможно ... часть моих вопросов) два статических метода, называемых
GetMessage (идентификатор Guid) и
SaveMessage (Сообщение сообщения)
Конечной целью было бы иметь возможность поменять поставщика, который был написан для Linq2SQL, на одного для LLBLGen Pro или другого поставщика, который не работает с ORM (например, VistaDB).
Дизайн Цели:
Я хотел бы разделение слоев.
Я хотел бы, чтобы каждый слой имел зависимость только от слоя ниже, а не над ним.
Я хотел бы, чтобы сгенерированные ORM классы были только на уровне DL.
Я хотел бы, чтобы UL поделился классом сообщений с BL.
Следовательно, означает ли это, что:
а) Сообщение определено в BL
b) Представление Db / Orm / Manual таблицы БД («DbMessageRecord», или «MessageEntity», или как ее еще называет ORM) определено в DL.
в) BL имеет зависимость от DL
d) Перед вызовом методов DL, которые не имеют ссылки или не знают о BL, BL должен преобразовать их в объекты BL (например, DbMessageRecord)?
UL:
Main()
{
id = 1;
Message m = BL.GetMessage(id);
Console.Write (string.Format("{0} to {1} recipients...", m.From, m.To.Count));
}
BL:
static class MessageService
{
public static Message GetMessage(id)
{
DbMessageRecord message = DLManager.GetMessage(id);
DbMessageAddressRecord[] messageAddresses = DLManager.GetMessageAddresses(id);
return MapMessage(message,
}
protected static Message MapMessage(DbMessageRecord dbMessage. DbMessageAddressRecord[] dbAddresses)
{
Message m = new Message(dbMessage.From);
foreach(DbMessageAddressRecord dbAddressRecord in dbAddresses){
m.To.Add(new MessageAddress (dbAddressRecord.Name, dbAddressRecord.Address);
}
}
DL:
static class MessageManager
{
public static DbMessageRecord GetMessage(id);
public static DbMessageAddressRecord GetMessageAddresses(id);
}
Вопросы:
а) Очевидно, что это много работы, рано или поздно.
б) Больше ошибок
в) медленнее
d) Так как BL теперь зависит от DL и ссылается на классы в DL (например, DbMessageRecord), кажется, что, поскольку они определены ORM, вы не можете разорвать одного поставщика и заменить его другим, делает все упражнение бессмысленным ... может также использовать классы ORM на всем протяжении BL.
e) Или ... требуется другая сборка между BL и DL, и требуется другое отображение, чтобы оставить BL независимым от базовых классов DL.
Жаль, что я не мог бы задать вопросы яснее ... но я действительно просто потерян в этот момент. Любая помощь будет принята с благодарностью.