asp.net mvc поместил контроллеры в отдельный проект

107

Я только изучаю asp.net mvc и пытаюсь понять, как переместить свои контроллеры в отдельный проект. Обычно, когда я раньше разрабатывал веб-приложения asp.net, я создавал один проект для своих моделей, другой - для своей логики, а затем была сеть.

Теперь, когда я изучаю asp.net mvc, я надеялся следовать аналогичному шаблону и поместить модели и контроллеры в свои отдельные проекты, а просто оставить представления / сценарии / css в Интернете. Модель была проста, но я не понимаю, как «найти» мои контроллеры в отдельном проекте. Также я хотел бы знать, целесообразно ли это. Спасибо!

Аарон Палмер
источник

Ответы:

92

Прежде всего, неплохо было бы вынести вашу модель в отдельный проект. Как вы обнаружили, это тривиально.

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

Если вы все же решите сделать это, вам нужно будет указать фреймворку, как найти ваши контроллеры. Основной способ сделать это - предоставить свой собственный ControllerFactory. Вы можете взглянуть на исходный код DefaultControllerFactory, чтобы понять, как это делается. Подтипа этого класса и переопределения метода GetControllerType (string controllerName) может быть достаточно для выполнения того, о чем вы просите.

Создав свой собственный ControllerFactory, вы добавляете следующую строку в Application_Start в global.asax, чтобы сообщить фреймворку, где его найти:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

Обновление: прочтите этот пост и сообщения, на которые он ссылается, для получения дополнительной информации. См. Также комментарий Фила Хаака к этому сообщению о:

ControllerBuilder.Current.DefaultNamespaces.Add(
    "ExternalAssembly.Controllers");

... что не является полным решением, но, возможно, достаточно хорошо для простых случаев.

Крэйг Стунц
источник
2
Спасибо, Крейг! Это именно то, что я искал. Эта информация вообще существует в сети? Я искал это в Google без особого успеха. StackOverflow снова работает!
Аарон Палмер,
11
Я согласен, контроллеры обрабатывают ввод пользователя, управляют моделью, а затем передают данные в представление. Обычно они очень специфичны для приложения. Любая логика, не относящаяся к конкретному приложению, может быть лучше в библиотеке или модели. Но контроллеры в целом должны быть с веб-проектом.
Haacked
2
У меня есть контроллер ошибок и представления, которые идентичны для двух приложений. Для меня имеет смысл объединить их в одну сборку, которую могут использовать оба приложения.
Парусное дзюдо
3
Разве не проще протестировать контроллеры и использовать IoC, когда контроллеры находятся в отдельном проекте - это была бы основная причина,
Сэмюэл Голденбаум
1
@Chev, я не думаю, что это имеет значение. Возможность тестирования ваших контроллеров больше связана с тем, как вы их кодируете, а не с тем , где они
Craig Stuntz
19

Хотя разумно создать свой собственный ControllerFactory, я счел более удобным определять все мои контроллеры в каждом проекте, но выводить их из контроллеров в моем общем проекте:

namespace MyProject1.Controllers
{
   public class MyController : MySharedProject.Controllers.MyController
   {
      // nothing much to do here...
   }
}

namespace MySharedProject.Controllers
{
   public abstract class MyController : System.Web.Mvc.Controller
   {
      // all (or most) of my controller logic here...
   }
}

Это дает дополнительное преимущество, заключающееся в том, что у вас есть место для размещения логики контроллера, которая отличается от проекта к проекту. Кроме того, другим разработчикам проще быстро найти логику вашего контроллера, поскольку контроллеры существуют в стандартном месте.

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

Этот парень
источник
1
Это сработало очень хорошо, но мне пришлось удалить некоторый избыточный код, чтобы предотвратить ошибку маршрутизации
Кен Мак,
Привет! Как я могу управлять маршрутизацией в этом типе проекта? Я хочу использовать маршрутизацию по атрибутам ...
محمد
Вы можете использовать маршрутизацию атрибутов так же, как обычно.
ThisGuy
2
Не уверен, почему у этого нет большего количества голосов ... Я думаю, гораздо более элегантно, чем принятый ответ. Спасибо!
jleach
У меня это не работает. Не могли бы вы сказать, это .Net Core или .Net Framework?
Homayoun Behzadian 09
4
  • Добавьте библиотеку классов для своего проекта mvc.
  • В классе добавьте следующий код (для кода контроллера u'r)

    namespace ContactController
    {
    public class ContactController : Controller
    {
        public ActionResult Call()
        {
            ViewBag.Title = "Inside MyFirst Controller.";
            return View();
        }
    }

    }

  • В папке просмотра проекта mvc добавьте папку для контакта и создайте файл Call.cshtml. Просмотр папки

  • Добавьте ссылку на проект библиотеки классов в свой основной проект MVC.

Ссылка

  • Наконец, чтобы указать пространство имен контактного контроллера в Route Config.

RouteConfig

RandyMohan
источник
3
Немного прискорбно, что у вас есть пространство имен с тем же именем, что и у контроллера.
Мариуш Ямро, 02
3

Моя проблема решена после того, как я обновил System.Web.Mvcссылку NuGet, поэтому MvcWebsite и Class Library используют одну и ту же System.Web.Mvcверсию

Нет необходимости добавлять пространства имен по умолчанию

Хомаюн Бехзадиан
источник
Проблема заключалась в том, что MvcWebsite не генерировал исключение, в то время как текущая сборка mvc имеет более низкую версию, чем сборка mvc, на которую ссылается библиотека классов
Homayoun Behzadian 09
1

Самая простая форма разделения, которую я использую, - это сохранить представления «как есть» в исходном проекте MVC, но удалить контроллеры. Затем в новом проекте ClassLibrary добавьте классы Controller и убедитесь, что они наследуются от Controller.

Механизм маршрутизации MVC будет автоматически направлять контроллеры в ClassLibrary, а контроллеры автоматически построят представления из исходного проекта MVC, при условии, что у вас есть ссылки и использование правильно.

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

Джейми
источник