1, http processing request
2, webhost configuration and startup
1) a custom configuration (json, commandLine)
public class mycly { public string cly { get; set; } public string name { get; set; } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration(configureDelegate => { configureDelegate.AddJsonFile("cly.json", true, true) .AddCommandLine(args); }) .UseUrls("http://localhost:5300") .UseStartup<Startup>();
services.Configure<mycly>(Configuration);
private readonly IOptionsSnapshot<mycly> _options; public HomeController(IOptionsSnapshot<mycly> options) { _options = options; } public IActionResult Index() { return Content(_options.Value.cly + _options.Value.name); }
3, IHostEnvironment 和 The ApplicationShowing estimates Lifetime
applicationLifetime.ApplicationStarted.Register(() => { Console.WriteLine("Started"); }); applicationLifetime.ApplicationStopped.Register(() => { Console.WriteLine("Stopped"); }); applicationLifetime.ApplicationStopping.Register(() => { Console.WriteLine("Stopping"); }); app.Run(async context => { await context.Response.WriteAsync(env.ApplicationName); await context.Response.WriteAsync(env.ContentRootPath); await context.Response.WriteAsync(env.EnvironmentName); await context.Response.WriteAsync(env.WebRootPath); });
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
4, Middleware duct (main treatment class RequestDelegate)
https://www.cnblogs.com/Vam8023/p/10700254.html
Source: HttpAbstractions project; main relevant class (ApplicationBuilder.cs UseExtensions.cs UseMiddlewareExtensions.cs MiddlewareFactory.cs)
/// <summary> /// Adds a middleware type to the application's request pipeline. /// </summary> /// <typeparam name="TMiddleware">The middleware type.</typeparam> /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param> /// <param name="args">The arguments to pass to the middleware type instance's constructor.</param> /// <returns>The <see cref="IApplicationBuilder"/> instance.</returns> public static IApplicationBuilder UseMiddleware<TMiddleware>(this IApplicationBuilder app, params object[] args) { return app.UseMiddleware(typeof(TMiddleware), args); } /// <summary> /// Adds a middleware type to the application's request pipeline. /// </summary> /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param> /// <param name="middleware">The middleware type.</param> /// <param name="args">The arguments to pass to the middleware type instance's constructor.</param> /// <returns>The <see cref="IApplicationBuilder"/> instance.</returns> public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, Type middleware, params object[] args) { if (typeof(IMiddleware).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo())) { // IMiddleware doesn't support passing args directly since it's // activated from the container if (args.Length > 0) { throw new NotSupportedException(Resources.FormatException_UseMiddlewareExplicitArgumentsNotSupported(typeof(IMiddleware))); } return UseMiddlewareInterface(app, middleware); } var applicationServices = app.ApplicationServices; return app.Use(next => { var methods = middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public); var invokeMethods = methods.Where(m => string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal) || string.Equals(m.Name, InvokeAsyncMethodName, StringComparison.Ordinal) ).ToArray(); if (invokeMethods.Length > 1) { throw new InvalidOperationException(Resources.FormatException_UseMiddleMutlipleInvokes(InvokeMethodName, InvokeAsyncMethodName)); } if (invokeMethods.Length == 0) { throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoInvokeMethod(InvokeMethodName, InvokeAsyncMethodName, middleware)); } var methodInfo = invokeMethods[0]; if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType)) { throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNonTaskReturnType(InvokeMethodName, InvokeAsyncMethodName, nameof(Task))); } var parameters = methodInfo.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType != typeof(HttpContext)) { throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoParameters(InvokeMethodName, InvokeAsyncMethodName, nameof(HttpContext))); } var ctorArgs = new object[args.Length + 1]; ctorArgs[0] = next; Array.Copy(args, 0, ctorArgs, 1, args.Length); var instance = ActivatorUtilities.CreateInstance(app.ApplicationServices, middleware, ctorArgs); if (parameters.Length == 1) { return (RequestDelegate)methodInfo.CreateDelegate(typeof(RequestDelegate), instance); } var factory = Compile<object>(methodInfo, parameters); return context => { var serviceProvider = context.RequestServices ?? applicationServices; if (serviceProvider == null) { throw new InvalidOperationException(Resources.FormatException_UseMiddlewareIServiceProviderNotAvailable(nameof(IServiceProvider))); } return factory(instance, context, serviceProvider); }; }); } private static IApplicationBuilder UseMiddlewareInterface(IApplicationBuilder app, Type middlewareType) { return app.Use(next => { return async context => { var middlewareFactory = (IMiddlewareFactory)context.RequestServices.GetService(typeof(IMiddlewareFactory)); if (middlewareFactory == null) { // No middleware factory throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoMiddlewareFactory(typeof(IMiddlewareFactory))); } var middleware = middlewareFactory.Create(middlewareType); if (middleware == null) { // The factory returned null, it's a broken implementation throw new InvalidOperationException(Resources.FormatException_UseMiddlewareUnableToCreateMiddleware(middlewareFactory.GetType(), middlewareType)); } try { await middleware.InvokeAsync(context, next); } finally { middlewareFactory.Release(middleware); } }; }); }
Custom middleware by looking UseMiddlewareExtensions.cs, you can understand the use of specific pipeline done. (IMiddleware does not support passing args directly since it's activated from the container)
5, MVC routing and analytic source RoutingMiddleware
MvcApplicationBuilderExtensions.cs ->RoutingBuilderExtensions.cs (UseRouter,builder.UseMiddleware<RouterMiddleware>(router))
MapRouteRouteBuilderExtensions.cs, RouteBase.cs, Route.cs, RouteBuilder.cs,RouteCollection.cs(RouteAsync),RouterMiddleware.cs