Подтвердить что ты не робот

Платформа проекта инфраструктуры .NET Entity (архитектура)

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

Веб-сайт

Здесь содержится весь внешний интерфейс.

Проект С# - MLS.Game.Data​​strong >

Это содержит файл EDMX со всеми моими сопоставлениями данных. Здесь не намного больше.

Проект С# - MLS.Game.Business

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

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

var planet = PlanetManager.getPlanet(1);

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

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

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

ИЗМЕНИТЬ

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

Спасибо

4b9b3361

Ответ 1

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

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

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

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

Хороший вопрос, кстати.

Ответ 2

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

UI ссылки BLL и BOL. BLL refences BOL и DAL (LINQ to Entites).

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

Ответ 3

Что касается вашего второго вопроса (после EDIT), если вам нужно или хотите добавить функции в объекты EF, вы можете использовать частичные классы. Щелкните правой кнопкой мыши файл EDMX и выберите код просмотра.

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

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

Ответ 4

Что касается вашего второго вопроса в разделе "EDIT":

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

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

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

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

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

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

Марк

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

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