СУХИЕ действия ASP.NET MVC: ApplicationController или Service?

Я пишу приложение ASP.NET MVC 3 и довольно часто пишу эту строку в моих методах действий:

var user = _session.Single<User>(u => u.UserName == User.Identity.Name);

(Очевидно, используется в сочетании с AuthorizeAttribute)

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

Так что это нужно высушить:

  1. Должен ли я написать ApplicationContoller от которого все остальные контроллеры наследуют и выставляют User собственность там или я должен добавить это к моему IAdminService и выставить это как метод?

  2. Является ли 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 в базовом контроллере.

Другие вопросы по тегам