ASP.NET 5: что изменилось для разработчика
Всем привет. В прошлой статье я рассказывал о том, что изменилось в инфраструктуре ASP.NET и CLR. Теперь самое время поговорить об изменениях, связанных с разработкой приложений. Пока я писал, ASP.NET успел обновится, поэтому, можно считать, что это уже вторая версия.
Эту статью я решил построить на примере создания MVC 6 приложения с пустого проекта. Если вы захотите повторить то, что я буду описывать, вы можете это сделать в любой редакции Visual Studio 2015. На всякий случай — бесплатная редакция Visual Studio Community.
Важно:
1. После установки Visual Studio нужно обновить Microsoft ASP.NET and Web Tools 2015 до beta 8 (на сейчас последняя версия).
2. Запустить «Developer Command Prompt for VS2015» и выполнить 2 команды: dnvm setup и dnvm upgrade.
Создание проекта
Итак, создаем новый проект как обычно: File -> New Project -> Web.
И вот оно, первое изменение — раньше в разделе «Web» мы видели разные типы проектов ASP.NET (WebForms, MVC, WebApi), а теперь только «ASP.NET Web Application». И это не просто так: это тонкий намек на то, что не имеет значения, какой подход вы хотите использовать (WebForms, MVC, WebApi) — это теперь часть единого движка.
Но появились 2 новых типа проектов:
Class Library (Package) — это возможность создания библиотеки для вашего сайта и запаковать ее в nuget пакет. Почему именно nuget? Это часть новой стратегии управления зависимостями. Теперь все подключаемые библиотеки тянутся через package manager. При этом не важно, они лежат локально или онлайн. На самом деле и сам ASP.NET при упаковке для отправки на сервер сворачивается в nuget пакет.
Console Application (Package) — это вообще что-то из ряда вон выходящее. Консольное приложение для веб проекта. Зачем? На самом деле, этот тип проекта появился для создания собственного веб сервера на случай, если вы не хотите использовать Kestrel, WebListener или IIS. Например, вы просто хотите перенаправлять все запросы по порту 80 в ASP.NET и не проводить какие-то фильтрации, преобразования и прочее (ну или хотите написать свой уникальный веб сервер).
С этим, думаю, понятно. Дальше выбираем ASP.NET Web Application -> OK:
Как видим, все наши типы проектов спрятались в этом открывшемся окне. В данном случае нас интересует ASP.NET 5 Preview Templates. И опять вопрос: где же наши MVC, WebApi, WebForms шаблоны? Это еще один тонкий намек на то, что теперь все едино.
При этом внизу мы видим чекбоксы для выбора шаблона, но для ASP.NET 5 проектов они не активны. Это уже конкретный, толстый намек, граничащий с издевательством (можно было эти контролы просто скрыть), что теперь деваться некуда и придётся разбираться с новой структурой проектов и подходом к созданию ASP.NET приложений. Жмем «ОК», и через какое-то время у нас открывается новый пустой проект.
Будем превращать его в MVC проект шаг за шагом, попутно останавливаясь на особенностях нового шаблона.
Подключение библиотек
Первое что необходимо сделать на пути превращения пустого проекта в MVC — добавить необходимые для MVC библиотеки (References). Это можно сделать двумя способами:
1. Классический (в Solution Explorer, правой кнопкой по «References» -> Add Reference)
2. Продвинутый (ручной), используя файлик project.json.
Давайте рассмотрим структуру project.json по блокам в данном проекте:
webroot — директория на сервере, куда будет опубликовано наше приложение.
version — это версия приложения. Никакой связи с версией CRL или еще чего-то не имеет.
Тут то как раз мы и подключаем необходимые для нашего MVC библиотеки. Нужно дописать одну строку: «Microsoft.AspNet.Mvc»: «6.0.0-beta8». Рекомендую вводить руками, intellisense (он тут работает) вам подскажет версию библиотеки. У вас может стоять не «6.0.0-beta8», а какая-то другая версия.
И тут начинается магия: как только ввели новую строку и сохранили изменения, вы можете заметить, как в Solution Explorer раздел References начинает обновляться:
Как вы, наверное, догадались, Visual Studio автоматом докачивает только что добавленную библиотеку из nuget и сохраняет ее в кеш (и, соответственно, добавляет в ваш проект). Если вы сотрете только что созданную строку в project.json, Visual Studio уберет ее из References в вашем проекте, но при повторном добавлении этой строки, библиотека подключится уже из кэша, без закачки из онлайн репозитория.
Также, раз уж мы смотрим на References, обратите внимание, что здесь нет привычной простыни из подключенных библиотек. Все они спрятаны в разделы DNX 4.5.1 и DNX Core 5.0 в виде дерева (что такое DNX, читайте в предыдущей статье). Дерево — это зависимости одних библиотек от других. По-моему, очень удобное отображение.
Вопрос: откуда взялся DNX 4.5.1 и DNX Core 5.0 в нашем проекте? Опять таки, из project.json:
Если мы удалим, например, строчку с dnx451, то весь раздел DNX 4.5.1 пропадет из References в Solution Explorer. Иными словами, раздел «frameworks» указывает, под какие фреймворки будет собран наш проект. Причем в каждом из них можно создать свой набор зависимостей аналогично тому, как это делалось выше, там, где мы добавляли библиотеку MVC.
Далее блок «commands»:
Это команда запускает dnx для старта вашего приложения.
Ну и последние 2 блока:
publishExclude — компоненты, которые не нужно включать в пакет публикации.
exclude — компоненты, которые нужно игнорировать при компиляции.
Более детальная информация о структуре project.json есть тут.
Закрываем наш project.json и идем дальше.
Запуск сервиса и обработка запросов
Для того, чтобы наш проект стал MVC, нам необходимо сделать еще 2 вещи:
1. Запустить сервис MVC (тут понятие сервис несет немножко иной смысл, нежели сервис (служба) в Windows).
2. Добавить компонент MVC в процедуру роутинга трафика для веб сервера.
Все это делается в файлике Startup.cs. Как вы понимаете, это входящая точка нашего проекта.
Видим два метода. Первый — ConfigureServices. Тут начинается эпопея с новым механизмом DependencyInjection. Детально изучить этот механизм можно тут. Я же расскажу вкратце, применительно к нашей задаче.
В методе ConfigureServices мы добавляем и настраиваем все сервисы, которые будем использовать в нашем приложении. Сервисом может быть любая логика, которую нужно расшарить для всех компонентов приложения, например, Db Context, Logger.
Выглядит это примерно так: приложение говорит «Эй там, наверху, DbContext мне сюда подайте, хочу в него записать чего-нибудь». Этот крик доходит до ServiceProvider, который в ответ отдает объект DbContext. Идея в том, что попросить вернуть экземпляр требуемого нам сервиса мы можем откуда угодно в нашем проекте.
Если вы хотите попробовать DI механизм в деле, можете это сделать по инструкции тут.
Наша задача на сейчас — добавить строчку services.AddMvc(); в метод ConfigureServices. AddMvc — это Extension метод, который появляется вместе с пакетом Microsoft.AspNet.Mvc, который мы добавляли ранее.
Второй метод, Configure, служит для настройки последовательности обработки HTTP запросов.
Ввиду того, что MVC сам по себе является частью этой последовательности (ловит запрос, парсит url параметры, направляет на нужный контроллер), его нужно добавить и сюда, при этом настроить маршрут по умолчанию. В итоге Startup.cs должен выглядеть так:
Обратите внимание на строчку app.UseIISPlatformHandler();. Использование IIS HttpPlatformHandler позволяет завернуть трафик IIS на используемый нами Kestrel или WebListener. Прежде, чем использовать его на сервере, нужно сделать предварительную установку этого компонента в IIS (ссылки для x86, x64).
Что значит появление этого компонента в нашем проекте? Ранее, в версиях ASP.NET до Beta 8, работу с IIS обеспечивал Helios, который по сути являлся еще одним хостом со своей логикой. С выходом Beta 8 от него отказались в пользу дополнительного нативного модуля IIS HttpPlatformHandler. Используя этот модуль, IIS запускает внешний процесс (в нашем случае dnx.exe) и перенаправляет трафик на него.
Главное запомнить: ConfigureServices — сервисы, которые мы шарим по всему нашему приложению (MVC является таким сервисом), Configure — включение какого-либо Middleware в последовательность обработки HTTP запросов. Тут даже в названиях методов скрыт сакральный смысл: добавляем сервис — services.AddMvc(), используем Middleware — app.UseMvc().
Контроллеры и представления
Теперь осталось создать контроллеры и представления. Создаем 2 папки в нашем проекте: «Controllers» и «Views».
В папку Controllers добавляем (правой кнопкой мышки по папке -> Add -> New Item -> MVC Controller Class) контроллер «HomeController». В папке «Views» создаем папку «Home» и добавляем туда (правой кнопкой мышки по папке -> Add -> New Item -> MVC View Page) представление «Index».
В итоге структура проекта должна быть такой:
Дабы не было скучно, давайте что-то отобразим на нашей веб страничке. В контроллере для метода действия (другого перевода для Action в данном контексте не нашел) Index напишем:
А в представлении:
Теперь можем запустить приложение, и — та-да — в браузере «Hello World!». MVC без обмана. :)
Структура проекта
Еще буквально пару слов о структуре.
Папка wwwroot в проекте в Visual Studio — это вся статика нашего приложения. CSS, картинки и прочее, всё кидаем туда. Приятная новость: мы можем добавлять туда файлы с помощью Windows Explorer (т.е. не в Visual Studio), и они тут же подтянутся в ваш Solution Explorer. В Visual Studio 2015 встроен File System Watcher, который отслеживает все изменения в файлах вашего проекта и подтягивает их в ваш проект. В таком же виде содержимое этой папки развернется на сервере в папке wwwroot.
Dependencies в проекте — это не тоже самое, что Dependencies в project.json. Сюда попадают скрипты из Bower и NPN. Это 2 дополнительных package manager, которые используются для подтягивания клиентских зависимостей (например, JavaScript библиотек jquery) или скриптов для потоковой сборки проектов (GulpJS). Попробуйте создать новый проект, только шаблон выберите ASP.NET Web Application. Посмотрев в Dependencies, всё поймете.
Это далеко не все изменения, которые пришли с ASP.NET 5, но, я надеюсь, прочитав данную статью, вы легче поймёте, что из себя представляет новый ASP.NET 5, и легче начнёте использовать новый функционал уже сегодня.
В следующем материале, по просьбам комментаторов предыдущей статьи, я расскажу о способах публикации ASP.NET 5 приложений. Ну а в дальнейшем продолжу раскрывать изменения для разработчиков (типа «как заменить настройки, которые ранее делались в Web.config», «MVC 5 vs MVC 6, что изменилось?»).
P.S. Если вы хотите почитать о чем-то конкретном — пишите в комментариях, я постараюсь учесть ваши пожелания в последующих статьях.
P.P.S. Ну и конечно еще больше деталей от крутых спикеров со всего мира вы можете узнать на конференции DevDay*Kyiv, которая пройдет уже на следующей неделе.