Альтернативный MVC Framework на ASP.NET: FubuMVC

Введение

Почему же альтернативный? Всё просто, данный framework пишется силами выдающихся участников ALT.NET community, а именно:

Jeremy Miller, Chad Myers, Mark Nijhof, Ryan Kelley, и Joshua Flanagan.

FubuMVC не имеет никакого отношения к ASP.NET MVC Framework, кроме того, что так же построен поверх ASP.NET и реализует паттерн Front-Controller. Название FubuMVC строится из акронима “For us by us” и аббривеатуры MVC (кто ещё не знает, что это значит Model-View-Controller ?). Проект был инициирован по причине недовольства вышеперечисленных личностей архитектурными решениями, принятыми в ASP.NET MVC. Сказать, по правде, по прошествии года, после старта проекта, он не утратил своей элегантности и простоты в подходах.

FubuMVC вносит несколько непривычное понимание Controller’а. Теперь это не просто некоторый класс, теперь это больше логическая связность некоторых методов. Это раскрывает более широкие возможности для настройки специфичного поведения Controller’а, к примеру, обработки ошибок, реализации правил кэширования, определения типа возвращаемых значений. К тому же возможность динамического объединения вызовов Action’ов уже является удобным механизмом к расширению. Далее мы более подробно поговорим об особенностях этой реализации в FubuMVC.

В качестве View Engine (в данном случае является лишь определением и не имеет отношения к ASP.NET MVC View Engine) используется механизм рендринга WebForms (проще говоря FubuPage, которая является View в FubuMVC, наследует от System.Web.UI.Page), но имеется возможность в подключении всех существующих в ASP.NET MVC ViewEngine’ов, примером тому может быть реализация SparkViewEngine.

Конечно же уместным будет вопрос, а зачем же нужен “другой” MVC Framework, с меньшим количеством участников проекта, с меньшим вниманием со стороны разработчиков, с меньшим количеством тестеров и прочими атрибутами mainstream проектов.

В основу проекта FubuMVC его создатели заложили больше возможностей для кастомизации проекта под прикладные нужды, а так же конвенциям (соглашениям) относительно настройки и расширяемости. Причём конвенции должны покрывать основные и типичные нужды приложения, коих в разработки решений достаточно большое количество. Какие-либо дополнительные разработки будут инициировать собой появление дополнительных модулей.

ScreencastsАналогичные конвенции (соглашения) существую в известном всем MVC Framework на Ruby: Ruby On Rails. На своей практике разработки под Ruby On Rails я неоднократно убеждался, что данные конвенции действительно позволяют снизить сложность и количество написанного кода. Примером тому может служить ORM Active Record с его соглашениями касательно преобразования объектов в таблицы реляционной базы данных, а так же соглашение, относительно хранения конфигурации в формате YAML.

Официальный сайт проекта: http://fubumvc.com/

FubuMVC на GitHub: http://github.com/darthfubumvc/fubumvc

Первое погружение

Начнём с конвенций именования и структуры проекта. Вся работа с настройкой приложения FubuMVC ведётся через некоторый DSL, стиль конфигурирования очень близок к работе с FluentNhibernate.

public class HelloWorldFubuRegistry : FubuRegistry
{
    public HelloWorldFubuRegistry()
    {
        IncludeDiagnostics(true);

        Applies.ToThisAssembly();

        Actions
            .IncludeTypesNamed(x => x.EndsWith("Controller"));

        Routes
            .IgnoreControllerNamespaceEntirely()
            .ConstrainToHttpMethod(action => action.Method.Name.EndsWith("Command"), "POST")
            .ConstrainToHttpMethod(action => action.Method.Name.StartsWith("Query"), "GET");

        Views
            .TryToAttach(x=>
            {
                x.to_spark_view_by_action_namespace_and_name(GetType().Namespace);
                x.by_ViewModel_and_Namespace_and_MethodName();
                x.by_ViewModel_and_Namespace();
                x.by_ViewModel();
            });

        Output.ToJson.WhenCallMatches(action => action.Returns<AjaxResponse>());

        HomeIs<HomeInputModel>();
    }
}

Исходя из данной конфигурации IoC-container’а нетрудно догадаться о следующем:

  • Все классы, оканчивающиеся на “Controller” будут зарегистрированны в качестве Controller
  • Все запросы, оканчивающиеся на “Command” должны будут приниматься POST’ом, а начинающиеся на “Query” GET’ом
  • Все View будут заполняться соответствующими по именованию ViewModel
  • Весь вывод, возвращающий тип AjaxResponse будет серилизоваться в JSON

В качестве IoC-container’а в FubuMVC выбран StructureMap. Выбор не случаен, т.к. фактически StructureMap является старейшим IoC/DI-container’ом. Начало разработки датировано июнем 2004ого года и велось Jeremy D. Miller, так же и участником проекта FubuMVC.

Второе погружение

Давайте рассмотрим несколько примеров приложений на FubuMVC

Первое из них http://github.com/DarthFubuMVC/fubumvc-examples/tree/master/src/Actions/ControllerActionStyle/

Начнём, с того, что проверим его работоспособность:

image

В namespace’е SimpleWebsite.Core определена наша модель предметной области, а именно Movies, работе с которыми и просвещенно приложение.

В SimpleWebsite.Controllers определен единственный Controller и View, работу которых мы и видим на рисунке выше.

Давайте разберемся с MoviesController. Судя по его конструктору нетрудно догадаться, что DependencyInjection мы получаем out-of-box без каких-либо переопределений Controller Factory:


private readonly IRepository _repository;

public MoviesController(IRepository repository)
{
    _repository = repository;
}

Метод List() является “списочным” и предоставляет нам доступ к ViewModel


public ListMoviesViewModel List()
{
    return new ListMoviesViewModel {Movies = _repository.Query<Movie>()};
}

Стоит обратить внимание на конвенцию именования в данном случае. Под ViewModel (читается так же как PresentationModel) понимается адаптированная для представления модель, что подчеркивает SoC в реализации FubuMVC. View в данном случае будет строго типизировано на  этот тип:

 public class List : FubuPage&lt;ListMoviesViewModel&gt;   <br />{}

Метод Add() попадает под правило обработки AjaxResponse, следовательно вернется на страницу в виде JSON, где будет радужно встречен jQuery обработчиком.

image

Аналогичная ситуация с методом Remove().

Стоит обратить внимание на конвенцию именования принимаемых данными методами типов:

AddMovieInput, RemoveMovieInput

Наименования данных классов указывают на направление данных, т.е. их ввод с запросом. С помощью этих типов на View мы определяем Url для обработки соответствующих Action’ов Controller’а:

<%= Get<IUrlRegistry>().UrlFor(new AddMovieInput()) %>

FubuMVC реализует 3 модели обработки запросов:

  1. Controller / Action Привычный для ASP.NET MVC Framework способ. Определяется некоторый тип — Controller, который содержит в себе соответствующие методы — Action’ы. Данный пример был рассмотрен выше.
  2. Controller-less Actions (HandlerStyle) Данный способ подразумевает под собой “обезличенные” Action’ы. т.е. без привязки к какому-либо Controller’у. Правила нахождения Action’ов описываются Policy, которые можно описывать и добавлять в коде.
  3. REST-like (EndPointStyle) Этот способ близок к предыдущему, однако, в отличии от него реализует не только метод Execute, а все методы, необходимые для REST взаимодействия, каждый метод Get(), Post(), Put(), Head() в дальнейшем будет соответствовать типу HTTP запроса:
var httpVerbs = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
    {"GET", "POST", "PUT", "HEAD"};

Погружаемся далее

Как вы уже догадались, FubuMVC славится своими возможностями для расширения. Предлагаю ознакомиться с ещё одним примером: http://github.com/DarthFubuMVC/fubumvc-examples/tree/7c4b2165aedb6754a01538aee956e29d4060654c/src/Outputs/VaryByAcceptHeader

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

Этот пример практически ни чем не отличается от рассматриваемого, раннее, за тем лишь исключением, что в классе

VariableOutputConvention : IConfigurationAction

мы регистрируем интересующие нас возвращаемые типы, а так же указываем дополнительный Behavior для рендринга страницы:

RenderVariableOutput : BasicBehavior

После чего достаточно только заполнить интересные вам Movies http://localhost:59187/movies/list и попросить вернуть их в JSON http://localhost:59187/movies/list?renderformat=json или в XML http://localhost:59187/movies/list?renderformat=xml

Данный пример наглядно иллюстрирует точки расширения FubuMVC для любых нужд.

Диагностика

По адресу http://localhost:59187/_fubu вас будет ждать небольшой сюрприз, а именно – диагностическая утилита для FubuMVC.image

C её помощью вы сможете просматривать все зарегистрированные в вашем приложении

  • Chains – цепочки поведения, так называются логические связи между маршрутами и Action’ами. О цепочках можно посмотреть все обертки и возвращаемые значения.
  • Routes – показывает все зарегистрированные маршруты, и связанные с ними Action’ы, тип выводимых данных и цепочки поведения.
  • Actions – зарегестрированные в приложении Action’ы, их маршруты и возвращаемые значения
  • Inputs – возможные типы и способы ввода в вашем приложении со стороны запросов

Заключение

При первом и поверхностном знакомстве проект FubuMVC не показался мне чем-то выдающимся. Однако в последнее время мой интерес к нему постоянно растёт. Я считаю, что FubuMVC является более удобным и гибким инструментом, по сравнению с ASP.NET MVC. Однако это ещё не значит, что я уже готов доверить данному проекту свои коммерческие проекты. Тот факт, что сообщество всё же поддерживает многообразие качественных решений для создания приложений на ASP.NET, может только радовать.

Материалы

FubuMVC Contrib http://code.google.com/p/fubumvc-contrib/

Front Controller http://msdn.microsoft.com/en-us/library/ms978723.aspx

FubuMVC — Front Controller style framework  http://blog.fohjin.com/blog/2009/2/21/FubuMVC_Front_Controller_style_framework

FubuMVC Google Group http://groups.google.com/group/fubumvc-devel?pli=1

Ещё один MVC Framework на ASP.NET OpenRasta http://trac.caffeine-it.com/openrasta

Соглашение относительно настройки http://msdn.microsoft.com/ru-ru/magazine/dd419655.aspx

Реклама

9 комментариев on “Альтернативный MVC Framework на ASP.NET: FubuMVC”

  1. This is a really great post on FubuMVC. Thank you! I’m glad to see some interest in FubuMVC from our Russian friends.

    Is there enough interest yet that we should look at adding Russian translations to the Diagnostics pages and error messages?

    Translated via Google Translate:

    Пересчитываются Google Translate:

    Это действительно большой пост на FubuMVC. Спасибо! Я рад видеть некоторый интерес FubuMVC с нашими русскими друзьями.

    Достаточно ли интересы еще, что мы должны смотреть на добавить русский перевод к диагностике страниц и сообщения об ошибках?

  2. Я смотрел на эту штуку, и вобщемто не нашел для себя ничего чем бы она отличалась от ASP.NET MVC. Все конвеншены или уже существуют(может быть не аут-оф-зе-бокс), или пишуться за два клика. А вот зато оверкомпликейтов по типу цепочек поведения, в ASP.NET MVC, что а) в целом хорошо, б) может быть легко заимплеменчено.

  3. Dmitri:

    Имхо тут самое главное это skills risk, то есть насколько ты и твоя комманда могут изучить и «вкурить» новый фреймворк. Если в консалтинге — могут. Если в обычном аутсорсе или «на прикорме» у какой-нть конторы — скорее всего нет. Тот же самый вопрос у меня был со Spark-ом — с одной стороны хорошо конечно что реализованы умные вещи, но с другой пришлось написать целый документ чтобы для себя задокументировать новый синтаксис.

    P.S.: you really ought to start blogging in English, methinks.

  4. Dmitry:

    Сам использую asp.net mvc + structuremap, где очень нравится концепция Registry и default conventions — появляется желание расширить этот подход на все приложение.

    В FubuMVC вижу, что эти идеи изначально заложены в фреймворк — так что буду смотреть. Хотя конечно беспокоят проблемы, которые озвучили комментаторы выше.

  5. Альтернативный MVC Framework на ASP.NET: FubuMVC « butaji…

    Thank you for submitting this cool story — Trackback from progg.ru…

  6. mogadanez:

    про «старейшесть» StructureMap — не совсем уверен,
    по крайней мере с Windsor они ровестники примерно.
    дату начала разработки я не нашел, но 26-Dec-2004 уже опубликована статья
    http://www.codeproject.com/KB/architecture/introducingcastle.aspx
    в котором он выглядит вполне себе рабочим.

  7. Интересные ребята эти ALT.NET. ASP.NET MVC — наверное первый продукт MS, который грамотно спроектирован и ориентирован на TDD, DDD и лучшие практики. А они, видите-ли «не довольны архитектурными решениями». Лучше бы написали альтернативный WebForms или WinForms)) А вообще, конечно, интересно.

  8. Спасибо, за статью! Теперь будем с моими коллегами что-то думать! framework нуден нам хороший!


Добавить комментарий

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

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s