Структура проекта.NET Entity Framework (архитектура)

Я пытаюсь определить, как лучше всего спроектировать проект.NET Entity Framework, чтобы получить хороший многоуровневый подход. До сих пор я пробовал это в основанной на просмотре игре, где игроки владеют и управляют планетами. Вот как у меня это получилось:

Веб-сайт

Это содержит весь передний конец.

C# Project - MLS.Game.Data

Он содержит файл EDMX со всеми моими сопоставлениями данных. Не так много здесь.

C# Project - MLS.Game.Business

Это содержит различные классы, которые я называю "Менеджеры", такие как PlanetManager.cs. Менеджер планет имеет различные статические методы, которые используются для взаимодействия с планетой, такие как getPlanet(int planetID), который возвращает объект сгенерированного кода из MLS.Game.Data.

С сайта я сделаю что-то вроде этого:

var planet = PlanetManager.getPlanet(1);

Он возвращает объект Planet из MLS.Game.Data (сгенерированный из EDMX). Это работает, но это до некоторой степени беспокоит меня, потому что это означает, что мой интерфейс должен ссылаться на MLS.Game.Data. Я всегда чувствовал, что графический интерфейс должен только ссылаться на бизнес-проект.

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

Итак... мой вопрос - как все остальные выкладывают свои проекты ASP EF?

РЕДАКТИРОВАТЬ

Однако, после еще нескольких дополнительных вещей, которые меня беспокоят. Например, допустим, у меня есть объект Planet, который снова генерирует код из мастера. Что если придет время, когда моей Планете понадобится специальное свойство, скажем "Население", которое является своего рода вычислением, основанным на других свойствах объекта Планета. Хотел бы я создать новый класс, унаследованный от Planet, а затем вернуть его? (Хм, интересно, если эти классы запечатаны EF?)

Спасибо

7 ответов

Решение

Вы можете попробовать следующее, чтобы улучшить вещи:

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

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

Если вы инкапсулируете логику в самом классе, вы можете быть более уверенными в состоянии вашего объекта, независимо от характера внешнего вызывающего.

Кстати, хороший вопрос.

ИМХО, твоя текущая раскладка в порядке. Для вашего пользовательского интерфейса вполне нормально ссылаться на слой "Данные", как вы его называете. Я думаю, что, возможно, ваша проблема возникает из-за терминологии. "Данные", которые вы описали, чаще называют слоем "бизнес-объектов" (BOL). Тогда общий макет будет состоять из уровня бизнес-логики (BLL), который является вашим уровнем "менеджеров" и уровнем доступа к данным (DAL). В вашем сценарии LINQ to Entites (при условии, что вы будете использовать это) является вашим DAL. Обычный эталонный образец будет:

UI ссылки BLL и BOL. BLL ссылается на BOL и DAL (LINQ to Entites).

Посмотрите на эту серию статей для более подробной информации.

Что касается вашего второго вопроса (после РЕДАКТИРОВАНИЯ), если вам нужно или вы хотите добавить функции к своим объектам EF, вы можете использовать частичные классы. Щелкните правой кнопкой мыши файл EDMX и выберите код просмотра.

Или, если этого недостаточно, вы можете отказаться от дизайнера и написать свои собственные классы с поддержкой EF.

Здесь есть (краткое) обсуждение обоих вариантов - http://msdn.microsoft.com/en-us/library/bb738612.aspx

Что касается вашего второго вопроса в разделе "РЕДАКТИРОВАТЬ":

Если я не ошибаюсь, классы, сгенерированные EF, не запечатаны, и они являются ЧАСТИЧНЫМИ классами, так что вы можете легко расширить их, не касаясь самих сгенерированных файлов.

Сгенерированный класс будет:

public partial class Planet : global::System.Data.Objects.DataClasses.EntityObject
{
 ...
}

так что вы можете легко создать свой собственный "PlanetAddons.cs" (или как вы хотите его называть) для расширения этого класса:

public partial class Planet 
{
 property int Population {get; set;} 
 ...
}

Довольно аккуратно, а? Не нужно создавать и создавать искусственные иерархии объектов....

Марк

Я бы добавил к вашему бизнес-уровню DTO, которые являются представлениями "тупых объектов" (т.е. только свойствами) сущностей на вашем уровне данных. Тогда ваши классы "Manager" могут вернуть их, например:

class PlanetManager
{
    public static PlanetDTO GetPlanet(int id) { // ... }
}

и ваш пользовательский интерфейс может работать только со слоем BLL через POCO; Менеджер (который я бы назвал классом "Mapper") обрабатывает все преобразования между объектами и уровнем данных. Кроме того, если вам нужно расширить класс, вы можете иметь "виртуальное" свойство объекта DTO и заставить Manager перевести его обратно в его компоненты.

Ваш макет выглядит хорошо. Я бы добавил слой Utility/Common

Веб-интерфейс
Бизнес уровень
DataObjects
Служебный слой

Я не эксперт, но это звучит довольно хорошо для меня. Это похоже на то, что у меня есть в моих решениях, за исключением того, что я просто объединяю проект EF с бизнес-проектом. Мои решения не такие большие, и мои объекты не требуют большого интеллекта, так что для меня это нормально. У меня тоже есть куча разных методов для каждого из моих статических вспомогательных классов.

Если вы не хотите, чтобы уровень представления знал о уровне доступа к данным, вам нужно создать несколько промежуточных классов, что, вероятно, потребует много работы. Так в чем же проблема с вашей текущей настройкой?

Другие вопросы по тегам