Как добавить бизнес-уровень в приложение 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 с правильной настройкой модели, вы должны быть в порядке.

Надеюсь, что это помогает некоторым.