Как добавить бизнес-уровень в приложение C# MVC
У меня есть проект на Github, который я пытаюсь разработать, который показывает, как использовать лучшие практики на практике. Однако у меня проблемы с понятиями. Когда я это сделаю, я вернусь к основам и попробую простой пример. Чтобы увидеть проект перейдите по этой ссылке:
https://github.com/franasm/Store.git
Рабочая ветвь имеет полностью работающий DI/IOC. Разорванная ветвь - это то, что произошло, когда я попытался добавить простой бизнес-уровень. Итак, я вернулся к основам.
Я создал простое стандартное простое приложение MVC4. Затем я добавил EF5 с одной таблицей (таблица продуктов из проекта выше).
Я решил добавить бизнес-уровень без каких-либо DI/IOC или каких-либо модных вещей. Но концепция просто смущает меня.
Все, что я хочу сделать в этом примере, это создать класс, который расширяет класс продукта, добавить свойство TaxAmt и добавить метод для вычисления TaxAmt при создании экземпляра класса.
Я пробовал разные способы, но получаю всевозможные ошибки. От исключений переполнения стека, до экземпляров не установленных исключений. Большую часть времени вещь просто не отображает значение, потому что поле Product.Price не инициализировано.
Я также обнаружил, что мой BL находится не в том месте:
У меня есть моя модель,
тогда мой БЛ,
тогда мой контроллер.
Хорошо для этого небольшого примера. Но поскольку наиболее близким к рабочему примеру, который я могу получить, является создание частичного класса уже существующего класса, сгенерированного EF, когда я разделю это для использования DI/IOC, BL будет находиться на неправильной стороне интерфейсов, потому что он будет частью класса Model (частичный класс).
Я хотел бы, чтобы мои слои были четко разделены, как:
EF Модельный класс,
Интерфейс,
репо,
BL,
контроллер,
ViewModels,
Просмотры.
Потому что репо отвечает за грубые операции. BL должен опираться на это. После того, как информация о продукте (одна из которых - цена) была прочитана, BL может затем взять эту информацию, выполнить расчет налога, а затем контроллер может использовать ее.
Я не уверен, правильно ли я думаю об этом.
По большей части я категорически не согласен с тем, что BL должен быть частью модели. Но даже если бы это было так для моего надуманного примера, как описано выше. Я до сих пор не могу заставить его работать. Тем не менее, я бы искал решение для этого, которое было бы направлено на наследование класса модели, расширение его, а затем использование его вместе с репо. Но это снова приводит меня в круги. Нефть выполняется слоем репо, который не имеет доступа к BL, так как BL инициализируется для расчета налога. Разве я не удваиваю объекты, POCO для каждого экземпляра модели, а также экземпляр BL того же объекта.
Я действительно смущен...
По сути, я не включил код, потому что все, что я буквально сделал, это сделал простую таблицу, простой проект mvc, добавил модель EF5, связал все это для выполнения грубых операций и обеспечения его работы. Затем попытался добавить BL, как описано. Один класс в папке BL, который либо был определен как частичный класс модели (не идеальный), либо унаследовал класс модели напрямую (также не уверен, что это круто). В идеале я хотел бы иметь возможность использовать DI, чтобы ввести мой репо в мой BL, а затем мой BL в мой контроллер.
Если кто-то знает, как это сделать, не могли бы вы дать мне ответ, либо предоставив пошаговые инструкции (и, желательно, некоторый пример кода), либо объяснение, как выполнить этот процесс и почему я так запутался.
Заранее благодарю за любую помощь.
1 ответ
Таким образом, лучший способ создания приложения MVC с бизнес-уровнем и EF-уровнем - это трехуровневая компоновка.
У нас есть проект данных, который, скорее всего, является вашим EF-проектом (также может быть SSDT или чем-то подобным), затем "сервисным" слоем (на самом деле это может быть веб-служба, но также может быть просто обычная библиотека вывода классов). Я также иногда называю это своим "агентским" слоем. Классы здесь содержат модели и преобразуют модели из кода EF в эти модели. Вот пример этого с использованием LINQ:
public static BlogModel GetBlog(string ID)
{
Blog b;
using (Entities cm = new Entities())
{
b = cm.Blogs.Where(blog => blog.ID == ID).FirstOrDefault();
}
if (b != null)
return GetBlog(b);
return null;
}
Таким образом, этот метод будет получать объект Blog из базы данных, используя EF и LINQ to SQL. Теперь, чтобы превратить это в модель:
public static BlogModel GetBlog(Blog blog)
{
return new BlogModel()
{
Title = blog.Title,
Enabled = blog.Enabled
};
}
Это, конечно, также использует объект BlogModel с включенной строкой Title и bool. Просто в качестве примеров.
Итак, теперь у вас есть два метода на вашем бизнес-уровне, которые возвращают модель. Теперь вы можете вызвать это в вашем контроллере так:
[Route("/Blogs/{id}", RouteName = "Blogs")]
public ActionResult ViewBlogs(string id)
{
BlogModel m = BusinessNamespace.BlogClass.GetBlog(id);
return View("Blogs", m);
}
Теперь, предполагая, что у вас есть представление Blogs.cshtml с правильной настройкой модели, вы должны быть в порядке.
Надеюсь, что это помогает некоторым.