СУХИЕ действия ASP.NET MVC: ApplicationController или Service?
Я пишу приложение ASP.NET MVC 3 и довольно часто пишу эту строку в моих методах действий:
var user = _session.Single<User>(u => u.UserName == User.Identity.Name);
(Очевидно, используется в сочетании с AuthorizeAttribute
)
Есть и другие вещи, которые повторяются довольно часто, но этот является наиболее заметным, и в итоге у меня есть 3 действия рядом друг с другом, каждое из которых требует поиска авторизованного пользователя.
Так что это нужно высушить:
Должен ли я написать
ApplicationContoller
от которого все остальные контроллеры наследуют и выставляютUser
собственность там или я должен добавить это к моемуIAdminService
и выставить это как метод?Является ли ApplicationController чем-то, чего следует избегать или использовать в ASP.NET MVC?
2 ответа
Если вы обнаружите, что повторяете эту логику, то может помочь пользовательское связывание модели для типа User:
public class UserModelBinder : DefaultModelBinder
{
private readonly ISession _session;
public UserModelBinder(ISession session)
{
_session = session;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var username = controllerContext.HttpContext.User.Identity.Name;
return _session.Single<User>(u => u.UserName == username);
}
}
и как только вы зарегистрируете связыватель, ваше действие контроллера может выглядеть так:
[Authorize]
public ActionResult Foo(User user)
{
// ...
}
Как человек, который не любит супер-типы контроллеров, я бы подумал об использовании Dependency Injection и использовании конструктора для "внедрения" пользователя.
о / с это имеет некоторые недостатки. Это означает, что вам придется использовать поле для каждого использования в вашем контроллере, а также создавать привязку в инструменте IOC. Это также предполагает, что вы используете контейнер IOC.
Что касается других вариантов:
Предоставляя его в IAdminService, вы получаете дополнительное преимущество, будучи доступным в других местах, а не только в контроллере. Так что это плюс. Просто убедитесь, что вы не перегружаете свой интерфейс слишком сильно.
Использование его в базовом контроллере поначалу также заманчиво, но я обнаружил, что базовые типы контроллеров раздуты и неправильно управляются, поскольку добавляется все больше и больше функциональности, потому что нет множественного наследования, и людям нужно кое-что из этого и кое-что из этого.. Вещи могут стать ужасными. Не говоря уже о том, что если вы используете AsyncController, у вас будет два базовых типа для управления.
По сути, между вашими двумя вариантами я бы использовал интерфейс.
Независимо от того, что вы делаете, вы все равно можете добавить метод к интерфейсу, а также абстрагировать его за свойством User в базовом контроллере.