- PVSM.RU - https://www.pvsm.ru -

Погружение в ASP.NET 5 Runtime

Вступление от переводчика

Данная статья является переводом ASP.NET 5 — A Deep Dive into the ASP.NET 5 Runtime [1] — введения в архитектуру DNX и построенного на нем ASP.NET 5. Так как оригинальная статья была написана в марте 2015 года, во время, когда ASP.NET 5 был еще в стадии активной разработки (примерно beta 3), многое в ней устарело. Поэтому при переводе вся информация была актуализирована до текущей версии ASP.NET 5 (RC1), также были добавлены ссылки на связанные ресурсы (в основном на docs.asp.net) и исходный код на GitHub (смотрите только в случаях, если вам интересна реализация). Приятного погружения!

.NET Runtime Environment (DNX)

ASP.NET 5 базируется на гибком, кроссплатформенном runtime, который может работать с разными .NET CLR (.NET Core CLR, Mono CLR, .NET Framework CLR). Вы можете запустить ASP.NET 5 используя полный .NET Framework или можете запустить используя новый .NET Core [2] docs, который позволяет вам просто копировать все необходимые библиотеки вместе с приложением в существующее окружение, без изменения чего-либо еще на вашей машине. Используя .NET Core вы также можете запустить ASP.NET 5 кроссплатформенно на Linux [3] docs и Mac OS [4] docs.

Инфраструктура позволяющая запускать и исполнять приложения ASP.NET 5 называется .NET Runtime Environment [5] docs или кратко DNX. DNX предоставляет все что необходимо для работы .NET приложений: host process, CLR hosting логику, обнаружение управляемой Entry Point и т.д.

Логически архитектура DNX имеет пять слоев. Я опишу каждый из этих слоев вместе с их обязанностями.
Изображение взято из статьи DNX-structure [6] wiki

Архитектура ASP.NET 5 и DNX

Слой первый: Нативный процесс

Нативный процесс (имеется в виду процесс операционной системы) — это очень тонкий слой с обязанностью найти и вызвать нативный CLR host, передав в него аргументы, переданные в сам процесс. В Windows — это dnx.exe (находится в %YOUR_PROFILE%/.dnx/runtimes/%CHOOSEN_RUNTIME%). В Mac и Linux — это запускаемый bash script (тоже с именем dnx).

Запуск на IIS [7] docs происходит с помощью устанавливаемого на IIS нативного HTTP-модуля: HTTPPlatformHandler [8] (который в итоге тоже запустит dnx.exe). Использование HTTPPlatformHandler позволяет запускать веб-приложение на IIS без любых зависимостей от .NET Framework (естественно, при запуске веб-приложений нацеленных на .NET Core, а не на полный .NET Framework).

Примечание: DNX приложения (и консольные и веб-приложения ASP.NET 5) исполняются в адресном пространстве этого нативного процесса. С этого момента и далее под "нативным процессом" я буду подразумевать dnx.exe и его аналоги в других операционных системах.

dnx

Слой второй и третий: Нативные CLR host и CLR

Имеют три главных обязанности:

  1. Запустить CLR. Способы достижения этого отличаются в зависимости от используемой версии CLR, но результат будет один.
  2. Начать выполнение кода четвертого слоя (Управляемая Entry Point) в CLR.
  3. Когда нативный CLR host возвращает управление, он будет "убирать за собой" и выключать CLR.

Слой четвертый: Управляемая Entry Point

Примечание: В целом логика этого слоя находится в сборке Microsoft.DNX.Host [9] github. Entry Point этого слоя можно считать RuntimeBootstrapper [10] github.

Это первый слой, в котором работа DNX приложения переходит к выполнению управляемого кода (отсюда и его название). Он ответственен:

  1. За создание LoaderContainer [11] github, контейнер для ILoader'ов. ILoader'ы ответственны за загрузку сборок. Когда CLR будет просить LoaderContainer предоставить какую-либо сборку, он будет делать это используя его ILoader'ы.
  2. Создание корневого ILoader'а [12] github, который будет загружать требуемые сборки из папки bin выбранного dnx runtime: %YOUR_PROFILE%/.dnx/runtimes/%CHOOSEN_RUNTIME%/bin/ и предоставленных во время запуска нативного процесса дополнительных путей, с помощью параметра --lib: dnx --lib <LIB_PATHS>).
  3. Настройку [13] github IApplicationEnvironment и ядра инфраструктуры системы Dependency Injection.
  4. Вызов entry point [14] github конкретного приложения или Microsoft.DNX.ApplicationHost [15] github, в зависимости от параметров переданных в нативный процесс во время запуска приложения.

Слой пятый: Application Host

Microsoft.DNX.ApplicationHost [16] github — это хост приложения поставляемый вместе с DNX. В его обязанности входит:

  1. Добавление [17] github дополнительных загрузчиков сборок (ILoader'ы) в LoaderContainer, которые могут загружать сборки из различных источников, таких как установленные NuGet пакеты и исходники компилируемые в runtime, используя Roslyn, и т.д.
  2. Просмотреть зависимости указанные в project.json и загрузить их. Логика обхода зависимостей описана более детально в статье Dependency-Resolution [18] wiki.
  3. Вызов entry point [19] github вашей сборки, в случае консольного приложения или entry point Microsoft.AspNet.Hosting [20] github в случае веб-приложения. Сборка может быть чем угодно имеющим entry point, которую ApplicationHost знает как вызвать [21] github. Приходящий вместе с DNX ApplicationHost знает как найти [22] github public static void Main метод.

Кроссплатформенныe SDK Tools

DNX поставляется вместе c SDK, содержащим все необходимое для построения кросс-платформенных .NET приложений.

DNVM — DNX Version Manager [23] wiki. Позволяет просмотреть установленные на компьютере DNX, установить новые и выбрать тот, который вы будете использовать.
После установки [24] docs вы сможете использовать DNVM из командной строки, просто наберите dnvm.

dnvm

DNVM устанавливает DNX'ы из NuGet feed настроенного на использование DNX_FEED переменной среды. DNX'ы не являются NuGet пакетами в традиционном смысле — пакеты на которые вы можете ссылаться в качестве зависимостей. NuGet — это удобный способ доставки и управления версиями DNX. По умолчанию DNX устанавливается копированием и распаковкой архива с DNX в "%USERPROFILE%/.dnx".

DNU — DNX Utility [25] wiki. Инструмент для установки, восстановления и создания NuGet пакетов. По умолчанию пакеты устанавливаются в "%USERPROFILE%/.dnx/packages", но вы можете изменить это, установив другой путь в в вашем global.json файле (Находится в папке Solution Items вашего проекта).
Для использования DNU наберите dnu в командной строке.

dnu

Кроссплатформенное консольное приложение на .NET

Сейчас я покажу вам как, используя DNX, создать простое кроссплатформенное консольное приложение на .NET.
Нам необходимо создать DLL с entry point и мы можем сделать это, используя "Console Application (Package)" шаблон в Visual Studio 2015.

Код нашего приложения:

namespace ConsoleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World");
            Console.ReadLine();
        }
    }
}

Код выглядит абсолютно идентично обычному консольному приложению.
Вы можете запустить это приложение из Visual Studio или из командной строки, набрав в командной строке dnx run, находясь в папке с файлом project.json (корень проекта), запускаемого приложения.

dnx run

dnx run — это просто сокращение, нативный процесс, фактически, развернет его в команду:

dnx.exe --appbase . Microsoft.DNX.ApplicationHost run

dnx run full

Что будет соответствовать шаблону:

dnx.exe --appbase <путь до папки проекта> <сборка, имеющая entry point> <параметры, для этой сборки >

Разберем развернутую команду:

  • dnx.exe — нативный процесс.
  • --appbase . — Задает путь до папки запускаемого проекта. Его значение "." — обозначает текущую директорию.
  • Microsoft.DNX.ApplicationHost — Любая сборка имеющая entry point. По умолчанию используется Microsoft.DNX.ApplicationHost, именно его entry point вызовет четвертый слой (Слой четвертый: Управляемая Entry Point, четвертая ответственность [26]). Четвертый слой не имеет специальных знаний о Microsoft.DNX.ApplicationHost. Он просто ищет entry point в предоставленной ему сборке и вызывает ее, передавая ей параметры (в нашем примере в качестве параметра будет передано "run").
  • run — Параметр передаваемый сборке имеющей entry point. Microsoft.DNX.ApplicationHost интерпретирует run, как команду, которая говорит найти entry point проекта по предоставленному через параметр --appbase пути и вызвать ее. Вместо команды run можно передать имя какой-либо сборки имеющей entry point и ApplicationHost вызовет ее. Ниже в разделе Хостинг [27] веб-приложений, мы рассмотрим этот пример.

Если вы не хотите использовать ApplicationHost. Вы можете вызвать нативный слой, передав ему ваше приложение напрямую. Для того, чтобы сделать это:

  1. Сгенерируйте DLL, запустив build вашего приложения (убедитесь, что вы поставили галочку около пункта "Produce outputs on build" в разделе "Build" свойств вашего проекта). Вы можете найти результаты в директории artifacts в корне папки вашего решения (вы также можете использовать не Visual Studio, а команду dnu build, набрав ее находясь в папке с файлом project.json вашего проекта).
  2. Наберите команду: dnx <путь_до_библиотеки_и_ее_имя_включая_расширение>.

Вызов dll напрямую

Вызов DLL напрямую — это довольно низкоуровневый подход написания приложений. Вы не используете Microsoft.DNX.ApplicationHost, поэтому вы отказываетесь и от использования файла project.json и улучшенного NuGet-based механизма управления зависимостями. Вместо этого любые библиотеки, от которых вы зависите, будут загружаться из указанных при запуске нативного процесса с помощью параметра --lib директорий. До окончания этой статьи я буду использовать Microsoft.DNX.ApplicationHost.

Microsoft.DNX.ApplicationHost — последний слой DNX, все что находится выше можно считать ASP.NET 5.

ASP.NET 5

Хостинг веб-приложений

В веб-приложениях ASP.NET 5 поверх Microsoft.DNX.ApplicationHost работает слой хостинга [28] docs. Он представлен сборкой Microsoft.AspNet.Hosting [29] github. Этот слой ответственен за поиск веб-сервера, запуск веб-приложения на нем и "уборку за собой" во время выключения веб-приложения. Он также предоставляет приложению [30] github некоторые дополнительные, связанные со слоем хостинга [27] сервисы.

Для запуска веб-приложения Microsoft.DNX.ApplicationHost должен вызывать entry point метод [20] github Microsoft.AspNet.Hosting.

Используемый хостингом [27] веб-сервер можно выбрать, указав опцию --server или используя другие способы настройки хостинга [27], такие как файл hosting.json или environment variables. Слой хостинга [27] загружает выбранный веб-сервер и стартует его. Обычно используемый веб-сервер должен быть перечислен в списке зависимостей в файле project.json, чтобы его можно было загрузить.

Как правило, запуск веб-приложения из командной строки производится командой dnx web.

dnx web

Шаблон веб-приложения ASP.NET 5 включает набор команд [31] docs, определенных в project.json файле и команда web одна из них:

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "ef": "EntityFramework.Commands"
  },

Команды, на самом деле, только устанавливают дополнительные аргументы для dnx.exe и когда вы набираете dnx web для запуска веб-приложения, в реальности это преобразуется в:

dnx.exe --appbase . Microsoft.DNX.ApplicationHost Microsoft.AspNet.Server.Kestrel

Погружение в ASP.NET 5 Runtime - 9

В свою очередь, вызов entry point Microsoft.AspNet.Server.Kestrel [32] github преобразуется в вызов:

Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel

Так что итоговая команда будет:

dnx.exe --appbase . Microsoft.DNX.ApplicationHost Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel

Погружение в ASP.NET 5 Runtime - 10

В результате выполнения которой, Microsoft.DNX.ApplicationHost вызовет entry point метод Microsoft.AspNet.Hosting (помните в разделе про кроссплатформенное консольное приложение я говорил, что если вместо run передать имя сборки, то ApplicationHost вызовет ее entry point ?).

Пока статья про хостинг [27] в документации docs.asp.net не готова, прочитать про ключи, используемые для настройки хостинга [27], можно здесь [33].

Стартовая логика веб-приложения

Слой хостинга [27] также ответственен за запуск [34] github стартовой логики [35] docs веб-приложения. Раньше она находилась в файле Global.asax, теперь по умолчанию находится в классе Startup и состоит из Configure метода, используемого для построения конвейера обработки запросов и ConfigureServices метода, используемого для настройки сервисов веб-приложения.

namespace WebApplication1
{
  public class Startup
  {
    public void ConfigureService(IServiceCollection services)
    {
      // Добавьте сервисы для вашего приложения здесь
    }
    public void Configure(IApplicationBuilder app)
    {
      // Настройте конвейер обработки запросов здесь
    }
  }
}

Для построения конвейера обработки запросов в Configure методе используется интерфейс IApplicationBuilder [36] github. IApplicationBuilder позволяет зарегистрировать request delegate ("Use" метод) и зарегистрировать middleware ("UseMiddleware" метод) в конвейере обработки запросов.

Request delegate — это ключевая концепция ASP.NET 5. Request delegate — это обработчик входящего запроса, он принимает HttpContext и асинхронно делает нечто полезное с ним:

public delegate Task RequestDelegate(HttpContext context);

Обработка запроса в ASP.NET 5 — это вызов по цепочке зарегистрированных request delegate. Но принятие решения о вызове следующего request delegate в цепочке, остается за их автором, поэтому каждый request delegate может прекратить обработку запроса и вернуть ответ пользователю.

В качестве упрощения регистрации в конвейере обработки запросов request delegate не вызывающего следующий request delegate, вы можете использовать Run extension метод IApplicationBuilder.

public void Configure(IApplicationBuilder app)
{
    app.Run(async context => await context.Response.WriteAsync("Hello, world!"));
}

Того же самого можно достичь используя Use extension метод и не вызывая следующий request delegate:

public void Configure(IApplicationBuilder app)
{
    app.Use(next => async context => await context.Response.WriteAsync("Hello, world!"));
}

И пример с вызовом следующего в цепочке request delegate:

public void Configure(IApplicationBuilder app)
{
    app.Use(next => async context =>
        {
            await context.Response.WriteAsync("Hello, world!");
            await next.Invoke(context);
        });
}

Для того, чтобы request delegate было удобно переиспользовать, можно оформить его в виде ASP.NET 5 middleware [37] docs.

Middleware

Middleware ASP.NET 5 — это обычный класс, следующий определенному соглашению:

  1. Следующий в цепочке request delegate (а также необходимые сервисы и дополнительные параметры) передается в конструктор middleware.
  2. Логика обработки HttpContext должна быть реализована в асинхронном Invoke методе.

Пример middleware:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using System.Threading.Tasks;
public class XHttpHeaderOverrideMiddleware
{
  private readonly RequestDelegate _next;
  public XHttpHeaderOverrideMiddleware(RequestDelegate next)
  {
    _next = next;
  }
  public Task Invoke(HttpContext httpContext)
  {
    var headerValue =
      httpContext.Request.Headers["X-HTTP-Method-Override"];
    var queryValue =
      httpContext.Request.Query["X-HTTP-Method-Override"];
    if (!string.IsNullOrEmpty(headerValue))
    {
      httpContext.Request.Method = headerValue;
    }
    else if (!string.IsNullOrEmpty(queryValue))
    {
      httpContext.Request.Method = queryValue;
    }
    return _next.Invoke(httpContext);
  }
}

Вызов следующего (если вы хотите вызвать следующий) в цепочке request delegate должен осуществляться внутри Invoke метода. Если вы разместите какую-нибудь логику ниже вызова следующего request delegate, то она будет выполнена после того, как все следующие за вашим обработчики входящего запроса отработают.

В конвейер обработки запросов вы можете включить middleware следующее этому соглашению с помощью UseMiddleware<T> extension метода IApplicationBuilder:

public void Configure(IApplicationBuilder app)
{
  app.UseMiddleware<XHttpHeaderOverrideMiddleware>();
}

Любые параметры, переданные в этот метод, будут внедрены в конструктор middleware после RequestDelegate next и запрошенных сервисов.
Конструктор middleware, принимающий дополнительно сервисы и параметры:

public XHttpHeaderOverrideMiddleware(RequestDelegate next, SomeServise1 service1,
    SomeServise2 service2, string param1, bool param2)
{
  _next = next;
}

Включение middleware в конвейер обработки запросов и передача ему параметров:

public void Configure(IApplicationBuilder app)
{
  app.UseMiddleware<XHttpHeaderOverrideMiddleware>(param1, param2);
}

По-соглашению, включение middleware в цепочку вызовов следует оформлять в виде "Use..." extension метода у IApplicationBuilder:

public static class BuilderExtensions
{
  public static IApplicationBuilder UseXHttpHeaderOverride(
    this IApplicationBuilder builder)
  {
    return builder.UseMiddleware<XHttpHeaderOverrideMiddleware>();
  }
}

Чтобы включить этот middleware в конвейер обработки запросов, вам необходимо вызвать этот extension метод в Configure методе:

public void Configure(IApplicationBuilder app)
{
    app.UseXHttpHeaderOverride();
}

ASP.NET 5 поставляется с большим набором встроенных middleware. Есть middleware для работы с файлами [38] docs, маршрутизации [39] docs, обработки ошибок, диагностики [40] docs и безопасности. Middleware поставляются как NuGet пакеты через nuget.org.

Сервисы

В ASP.NET 5 вводится понятие Сервисов — "общих" компонентов, доступ к которым может требоваться в нескольких местах приложения. Сервисы доступны приложению через систему внедрения зависимостей. ASP.NET 5 поставляется с простым IoC-контейнером [41] docs, поддерживающим внедрение зависимостей в конструктор, но вы легко можете заменить [42] docs его на другой контейнер.

Startup класс также поддерживает внедрение зависимостей, для этого достаточно запросить их в качестве параметров конструктора.

public Startup(IApplicationEnvironment appEnv)
{

}

По умолчанию вам доступны следующие сервисы:
Microsoft.Extensions.PlatformAbstractions.IApplicationEnvironment — информация о приложении (физический путь до папки приложения, его имя, версия, конфигурация (Release, Debug), используемый Runtime фреймворк).
Microsoft.Extensions.PlatformAbstractions.IRuntimeEnvironment — информация о DNX runtime и ОС.
Microsoft.AspNet.Hosting.IHostingEnvironment — доступ к Web-root вашего приложения (обычно папка "wwwroot"), а также информация о текущей среде (dev, stage, prod).
Microsoft.Extensions.Logging.ILoggerFactory — фабрика для создания логгеров [43] docs.
Microsoft.AspNet.Hosting.Builder.IApplicationBuilderFactory — фабрика для создания IApplicationBuilder (используется для построения request pipeline).
Microsoft.AspNet.Http.IHttpContextFactory — фабрика для создания Http-контекста.
Microsoft.AspNet.Http.IHttpContextAccessor — предоставляет доступ к текущему Http-контексту.

Вы можете добавить сервисы в приложение в ConfigureServices методе класса Startup, используя интерфейс IServiceCollection [44] github. Обычно фреймворки и библиотеки предоставляют "Add..." extension метод у IServiceCollection для добавления их сервисов в IoC-контейнер. Например, добавление сервисов используемых ASP.NET MVC 6 производится так:

public void ConfigureServices(IServiceCollection services)
{
  // Добавление сервисов MVC
  services.AddMvc();
}

Вы можете добавлять собственные сервисы в IoC-контейнер. Добавляемые сервисы могут быть одними из трех типов: transient (AddTransient метод IServiceCollection ), scoped (AddScoped метод IServiceCollection ) или singleton (AddSingleton метод IServiceCollection ).

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<CustomService1>();
    services.AddScoped<CustomService2>();
    services.AddSingleton<CustomService3>();
}

Transient сервисы создаются при каждом их запросе из контейнера. Scoped сервисы создаются, только если они еще не создавались в текущем scope. В веб-приложениях scope-контейнер создается для каждого запроса, поэтому можно думать о них как о сервисах, создаваемых для каждого http-запроса. Singleton сервисы создаются только один раз за цикл жизни приложения.

В консольном приложении, где доступ к dependency injection отсутствует, для доступа к сервисам: IApplicationEnvironment и IRuntimeEnvironment необходимо использовать статический объект Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.

Конфигурация приложения

Web.config и app.config файлы больше не поддерживаются. Вместо них ASP.NET 5 использует новое, упрощенное Configuration API [45] docs. Оно позволяет получать данные из разных источников. Используемые по умолчанию configuration-провайдеры поддерживают JSON, XML, INI, аргументы командной строки, environment variables, а также установку параметров прямо из кода (in-memory collection). Вы можете указать несколько источников, и они будут использоваться в порядке их добавления (добавленные последними будут переопределять настройки добавленных ранее). Также вы можете иметь разные настройки для каждой среды [46] docs: test, stage, prod. Что облегчает публикацию приложения в разные среды.

Пример файла appsettings.json:

{
  "Name": "Stas",
  "Surname": "Boyarincev"
}

Пример получения конфигурации приложения, используя Configuration API:

var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
var Configuration = builder.Build();

Запросить данные, вы можете используя метод GetSection и имя ключа:

var name = Configuration.GetSection("name");
var surname = Configuration.GetSection("surname");

Или обратившись по индексу:

var name = Configuration["name"];
var surname = Configuration["surname"];

Работать с Configuration API рекомендуется в Startup классе, а в дальнейшем разделять настройки на небольшие наборы данных, соответствующие какой-либо функциональности и передавать другим частям приложения с помощью механизма Options [47] docs.

Механизм Options позволяет использовать Plain Old CLR Object (POCO) классы в качестве объектов с настройками. Вы можете добавить его в ваше приложение, вызвав AddOptions extension-метод у IServiceCollection в ConfigureServices методе:

public void ConfigureServices(IServiceCollection services)
{
    //добавляем механизм Options в приложение
    services.AddOptions();
}

Фактически, вызов AddOptions добавляет IOptions<TOption> в систему внедрения зависимостей. Этот сервис может быть использован для получения Options разных типов везде, где внедрение зависимостей доступно (достаточно лишь запросить из нее IOption<TOption>, где TOption POCO класс с нужными вам настройками).
Для регистрации вашей options вы можете использовать Configure<TOption> extension-метод IServiceCollection:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options => options.Filters.Add(
      new MyGlobalFilter()));
}

В пример выше MvcOptions [48] github — это класс, который MVC-фреймворк использует для получения от пользователя своих настроек.

Вы также можете легко передать часть конфигурационных настроек в options:

public void ConfigureServices(IServiceCollection services)
{
    //Configuration - конфигурация приложения полученная в примерах выше
    services.Configure<MyOptions>(Configuration);
}

В этом случае ключи настроек из конфигурации будут мапиться на имена свойств POCO класса настроек.

А для получения MyOptions с установленными настройками внутри приложения, достаточно запросить из системы внедрения зависимостей IOption<MyOptions>, например, через конструктор контроллера.

public HomeController(IOptions<MyOptions> appOptions)
{

}

Внутренне механизм Options работает через добавление IConfigureOptions<TOptions> в сервис-контейнер, где TOptions — класс с настройками. Стандартная реализация IOptions<TOption> будет собирать все IConfigureOptions<TOptions> одного типа и "суммировать их свойства", а затем предоставлять конечный экземпляр — это происходит потому что вы можете множество раз добавлять объект с настройками одного и того же типа в сервис-контейнер, переопределяя настройки.

Веб-сервер

Как только веб-сервер стартует, он начинает ожидать входящие запросы и запускать процесс обработки для каждого из них. Уровень веб-сервера, поднимает запрос на уровень хостинга [27], отправляя ему набор feature интерфейсов. Есть feature интерфейсы для отправки файлов, веб-сокетов, поддержки сессий, клиентских сертификатов и многих других [49] docs.

Например, feature интерфейс для Http-request:

namespace Microsoft.AspNet.Http.Features
{
    public interface IHttpRequestFeature
    {
        string Protocol { get; set; }
        string Scheme { get; set; }
        string Method { get; set; }
        string PathBase { get; set; }
        string Path { get; set; }
        string QueryString { get; set; }
        IHeaderDictionary Headers { get; set; }
        Stream Body { get; set; }
    }
}

Веб-сервер использует feature интерфейсы для раскрытия низкоуровневой функциональности уровню хостинга [27]. А он в свою очередь делает доступными их всему приложению через HttpContext. Это позволяет разорвать тесные связи между уровнем веб-сервера и хостинга [27] и разместить приложение на различных веб-серверах. ASP.NET 5 поставляется с оберткой над HTTP.SYS (Microsoft.AspNet.Server.Web­Listener [50]) и новым кроссплатформенным веб-сервером под названием Kestrel [51] github.

Open Web Interface for .NET (OWIN) стандарт, разделяющий эти же цели. OWIN стандартизирует как .NET сервера и приложения должны общаться друг с другом. ASP.NET 5 поддерживает OWIN [52] docs с помощью Microsoft.AspNet.Owin [53] github пакета. Вы можете хостить [54] github ASP.NET 5 приложения на OWIN-based веб-серверах и вы можете использовать OWIN middleware [55] github в ASP.NET 5 pipeline.

Katana Project [56] была первой попыткой Microsoft реализовать поддержку OWIN на стеке ASP.NET и многие идеи и концепты были перенесены из нее в ASP.NET 5. Katana имеет похожую модель построения pipeline из middleware и хостинга [27] на различных веб-серверах. Однако, в отличие от Katana, открывающей ниже лежащий уровень OWIN приложению, ASP.NET 5 переходит к более удобным абстракциям. Но вы до сих пор можете использовать Katana middleware в ASP.NET 5 с помощью OWIN моста [57] github

Итоги

ASP.NET 5 runtime построен с нуля для поддержки кроссплатформенных веб-приложений. ASP.NET 5 имеет гибкую, многослойную архитектуру, которая может запускаться на полном .NET Framework, .NET Core и даже на Mono. Новая хостинг [27] модель позволяет легко компоновать приложения, используя middleware, хостить их на различных веб-серверах, а также поддерживает внедрение зависимостей и новые улучшенные возможности по конфигурированию приложений.

Cсылки

github.com/aspnet [58] — исходный код ASP.NET 5.
docs.asp.net [59] — документация ASP.NET 5.
github.com/aspnet/Home/wiki [60] — статьи про DNX Runtime.

Автор: masterL

Источник [61]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-2/106820

Ссылки в тексте:

[1] ASP.NET 5 — A Deep Dive into the ASP.NET 5 Runtime: https://msdn.microsoft.com/en-us/magazine/dn913182.aspx

[2] .NET Core: https://docs.asp.net/en/latest/conceptual-overview/dotnetcore.html

[3] Linux: https://docs.asp.net/en/latest/getting-started/installing-on-linux.html

[4] Mac OS: https://docs.asp.net/en/latest/getting-started/installing-on-mac.html

[5] .NET Runtime Environment: https://docs.asp.net/en/latest/dnx/overview.html

[6] DNX-structure: https://github.com/aspnet/Home/wiki/DNX-structure

[7] Запуск на IIS: https://docs.asp.net/en/latest/publishing/iis.html

[8] HTTPPlatformHandler: https://azure.microsoft.com/en-us/blog/announcing-the-release-of-the-httpplatformhandler-module-for-iis-8/

[9] Microsoft.DNX.Host: https://github.com/aspnet/dnx/tree/1.0.0-rc1-final/src/Microsoft.Dnx.Host

[10] RuntimeBootstrapper: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.Host/RuntimeBootstrapper.cs

[11] создание LoaderContainer: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.Host/Bootstrapper.cs#L29

[12] Создание корневого ILoader'а: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.Host/Bootstrapper.cs#L32

[13] Настройку: https://github.com/aspnet/dnx/blob/dev/src/Microsoft.Dnx.Host/Bootstrapper.cs#L59-L70

[14] Вызов entry point: https://github.com/aspnet/dnx/blob/dev/src/Microsoft.Dnx.Host/Bootstrapper.cs#L80

[15] Microsoft.DNX.ApplicationHost: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.ApplicationHost/Program.cs

[16] Microsoft.DNX.ApplicationHost: https://github.com/aspnet/dnx/tree/1.0.0-rc1-final/src/Microsoft.Dnx.ApplicationHost

[17] Добавление: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.ApplicationHost/Program.cs#L72

[18] Dependency-Resolution: https://github.com/aspnet/Home/wiki/Dependency-Resolution

[19] Вызов entry point: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.ApplicationHost/Program.cs#L230-L240

[20] entry point Microsoft.AspNet.Hosting: https://github.com/aspnet/Hosting/blob/1.0.0-rc1/src/Microsoft.AspNet.Hosting/Program.cs

[21] знает как вызвать: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.Runtime.Sources/Impl/EntryPointExecutor.cs#L20

[22] знает как найти: https://github.com/aspnet/dnx/blob/1.0.0-rc1-final/src/Microsoft.Dnx.Runtime.Sources/Impl/EntryPointExecutor.cs#L70-L110

[23] DNVM — DNX Version Manager: https://github.com/aspnet/Home/wiki/Version-Manager

[24] После установки: https://docs.asp.net/en/latest/getting-started/installing-on-windows.html#install-the-net-version-manager-dnvm

[25] DNU — DNX Utility: https://github.com/aspnet/Home/wiki/DNX-utility

[26] четвертая ответственность: #4-layer-call-entry-point

[27] Хостинг: https://www.reg.ru/?rlink=reflink-717

[28] слой хостинга: https://docs.asp.net/en/latest/fundamentals/hosting.html

[29] Microsoft.AspNet.Hosting: https://github.com/aspnet/Hosting/tree/1.0.0-rc1/src/Microsoft.AspNet.Hosting

[30] предоставляет приложению: https://github.com/aspnet/Hosting/blob/1.0.0-rc1/src/Microsoft.AspNet.Hosting/WebHostBuilder.cs#L69

[31] команд: https://docs.asp.net/en/latest/dnx/commands.html

[32] entry point Microsoft.AspNet.Server.Kestrel: https://github.com/aspnet/KestrelHttpServer/blob/dev/src/Microsoft.AspNet.Server.Kestrel/Program.cs

[33] здесь: https://github.com/aspnet/Announcements/issues/108

[34] запуск: https://github.com/aspnet/Hosting/blob/1.0.0-rc1/src/Microsoft.AspNet.Hosting/WebApplication.cs#L56

[35] стартовой логики: https://docs.asp.net/en/latest/fundamentals/startup.html

[36] IApplicationBuilder: https://github.com/aspnet/HttpAbstractions/blob/1.0.0-rc1/src/Microsoft.AspNet.Http.Abstractions/IApplicationBuilder.cs

[37] ASP.NET 5 middleware: https://docs.asp.net/en/latest/fundamentals/middleware.html

[38] файлами: https://docs.asp.net/en/latest/fundamentals/static-files.html

[39] маршрутизации: https://docs.asp.net/en/latest/fundamentals/routing.html

[40] диагностики: https://docs.asp.net/en/latest/fundamentals/diagnostics.html

[41] IoC-контейнером: https://docs.asp.net/en/latest/fundamentals/dependency-injection.html

[42] заменить: https://docs.asp.net/en/latest/fundamentals/dependency-injection.html#replacing-the-default-services-container

[43] логгеров: https://docs.asp.net/en/latest/fundamentals/logging.html

[44] IServiceCollection: https://github.com/aspnet/DependencyInjection/blob/1.0.0-rc1/src/Microsoft.Extensions.DependencyInjection.Abstractions/IServiceCollection.cs

[45] Configuration API: https://docs.asp.net/en/latest/fundamentals/configuration.html

[46] среды: https://docs.asp.net/en/latest/fundamentals/environments.html

[47] Options: https://docs.asp.net/en/latest/fundamentals/configuration.html#using-options-and-configuration-objects

[48] MvcOptions: https://github.com/aspnet/Mvc/blob/6.0.0-rc1/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs

[49] многих других: https://docs.asp.net/en/latest/fundamentals/request-features.html

[50] Microsoft.AspNet.Server.Web­Listener: https://www.nuget.org/packages/Microsoft.AspNet.Server.WebListener

[51] Kestrel: https://github.com/aspnet/KestrelHttpServer

[52] поддерживает OWIN: https://docs.asp.net/en/latest/fundamentals/owin.html

[53] Microsoft.AspNet.Owin: https://github.com/aspnet/HttpAbstractions/tree/1.0.0-rc1/src/Microsoft.AspNet.Owin

[54] можете хостить: https://github.com/aspnet/Entropy/tree/dev/samples/Owin.Nowin.HelloWorld

[55] использовать OWIN middleware: https://github.com/aspnet/Entropy/tree/dev/samples/Owin.HelloWorld

[56] Katana Project: http://katanaproject.codeplex.com

[57] OWIN моста: https://github.com/aspnet/Entropy/tree/dev/samples/Owin.IAppBuilderBridge

[58] github.com/aspnet: https://github.com/aspnet/

[59] docs.asp.net: https://docs.asp.net/en/latest/index.html

[60] github.com/aspnet/Home/wiki: https://github.com/aspnet/Home/wiki

[61] Источник: http://habrahabr.ru/post/273509/