public static class A { private static readonly MethodInfo GetServiceInfo; public static IApplicationBuilder My_UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options) { //检查参数 if (app == null) { throw new ArgumentNullException("app"); } if (options == null) { throw new ArgumentNullException("options"); } var t = Microsoft.Extensions.Options.Options.Create<StaticFileOptions>(options); object[] args = new object[] { t }; //执行该方法 会自动注入 该类中所需要的对象 RequestDelegate next //return builder.UseMiddleware<RequestCultureMiddleware>(); return app.UseMiddleware<StaticFileMiddleware>(args); } public static IApplicationBuilder My_UseMiddleware<T>(this IApplicationBuilder app, params object[] args) { return app.My_UseMiddleware(typeof(T), args); } public static IApplicationBuilder My_UseMiddleware(this IApplicationBuilder app, Type middleware, params object[] args) { if (typeof(IMiddleware).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo())) { if (args.Length != 0) { throw new NotSupportedException(My_Resources.FormatException_UseMiddlewareExplicitArgumentsNotSupported(typeof(IMiddleware))); } return My_UseMiddlewareInterface(app, middleware); } IServiceProvider applicationServices = app.ApplicationServices; return app.Use ( delegate (RequestDelegate next) { MethodInfo[] array = (from m in middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public) where string.Equals(m.Name, "Invoke", StringComparison.Ordinal) || string.Equals(m.Name, "InvokeAsync", StringComparison.Ordinal) select m).ToArray(); if (array.Length > 1) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddleMutlipleInvokes("Invoke", "InvokeAsync")); } if (array.Length == 0) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareNoInvokeMethod("Invoke", "InvokeAsync", middleware)); } MethodInfo methodInfo = array[0]; if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType)) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareNonTaskReturnType("Invoke", "InvokeAsync", "Task")); } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType != typeof(HttpContext)) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareNoParameters("Invoke", "InvokeAsync", "HttpContext")); } object[] array2 = new object[args.Length + 1]; array2[0] = next; Array.Copy(args, 0, array2, 1, args.Length); object instance = ActivatorUtilities.CreateInstance(app.ApplicationServices, middleware, array2); if (parameters.Length == 1) { return (RequestDelegate)methodInfo.CreateDelegate(typeof(RequestDelegate), instance); } Func<object, HttpContext, IServiceProvider, Task> factory = My_Compile<object>(methodInfo, parameters); return delegate (HttpContext context) { IServiceProvider serviceProvider = context.RequestServices ?? applicationServices; if (serviceProvider == null) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareIServiceProviderNotAvailable("IServiceProvider")); } return factory(instance, context, serviceProvider); }; } ); } private static Func<T, HttpContext, IServiceProvider, Task> My_Compile<T>(MethodInfo methodInfo, ParameterInfo[] parameters) { ParameterExpression expression = Expression.Parameter((Type)typeof(HttpContext), "httpContext"); ParameterExpression expression2 = Expression.Parameter((Type)typeof(IServiceProvider), "serviceProvider"); ParameterExpression expression3 = Expression.Parameter((Type)typeof(T), "middleware"); Expression[] expressionArray = new Expression[] { expression }; for (int i = 1; i < parameters.Length; i++) { Type type = parameters[i].ParameterType; if (type.IsByRef) { throw new NotSupportedException(My_Resources.FormatException_InvokeDoesNotSupportRefOrOutParams("Invoke")); } Expression[] expressionArray2 = new Expression[] { (Expression)expression2, (Expression)Expression.Constant(type, (Type)typeof(Type)), (Expression)Expression.Constant(methodInfo.DeclaringType, (Type)typeof(Type)) }; expressionArray[i] = (Expression)Expression.Convert((Expression)Expression.Call(GetServiceInfo, expressionArray2), type); } Expression expression4 = (Expression)expression3; if (methodInfo.DeclaringType != typeof(T)) { expression4 = (Expression)Expression.Convert(expression4, methodInfo.DeclaringType); } ParameterExpression[] expressionArray3 = new ParameterExpression[] { expression3, expression, expression2 }; return Expression.Lambda<Func<T, HttpContext, IServiceProvider, Task>>((Expression)Expression.Call(expression4, methodInfo, expressionArray), expressionArray3).Compile(); } private static IApplicationBuilder My_UseMiddlewareInterface(IApplicationBuilder app, Type middlewareType) { return app.Use ( (RequestDelegate next) => async delegate (HttpContext context) { IMiddlewareFactory middlewareFactory = (IMiddlewareFactory)context.RequestServices.GetService(typeof(IMiddlewareFactory)); if (middlewareFactory == null) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareNoMiddlewareFactory(typeof(IMiddlewareFactory))); } IMiddleware middleware = middlewareFactory.Create(middlewareType); if (middleware == null) { throw new InvalidOperationException(My_Resources.FormatException_UseMiddlewareUnableToCreateMiddleware(middlewareFactory.GetType(), middlewareType)); } try { await middleware.InvokeAsync(context, next); } finally { middlewareFactory.Release(middleware); } } ); } } internal static class My_Resources { // Fields private static readonly ResourceManager _resourceManager; internal static string FormatException_UseMiddlewareNoMiddlewareFactory(object p0) { return string.Format(CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareNoMiddlewareFactory"), p0); } internal static string FormatException_UseMiddlewareUnableToCreateMiddleware(object p0, object p1) { return string.Format(CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareUnableToCreateMiddleware"), p0, p1); } // Methods static My_Resources() { _resourceManager = new ResourceManager( "Microsoft.AspNetCore.Http.Abstractions.Resources", IntrospectionExtensions.GetTypeInfo((Type)typeof(My_Resources)).Assembly); } private static string GetString(string name, params string[] formatterNames) { string str = _resourceManager.GetString(name); if (formatterNames != null) { for (int i = 0; i < formatterNames.Length; i++) { str = str.Replace("{" + formatterNames[i] + "}", "{" + ((int)i) + "}"); } } return str; } internal static string FormatException_UseMiddleMutlipleInvokes(object p0, object p1) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddleMutlipleInvokes", Array.Empty<string>()), p0, p1); internal static string FormatException_UseMiddlewareNoInvokeMethod(object p0, object p1, object p2) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareNoInvokeMethod", Array.Empty<string>()), p0, p1, p2); internal static string FormatException_UseMiddlewareNonTaskReturnType(object p0, object p1, object p2) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareNonTaskReturnType", Array.Empty<string>()), p0, p1, p2); internal static string FormatException_UseMiddlewareNoParameters(object p0, object p1, object p2) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareNoParameters", Array.Empty<string>()), p0, p1, p2); internal static string FormatException_UseMiddlewareIServiceProviderNotAvailable(object p0) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareIServiceProviderNotAvailable", Array.Empty<string>()), p0); internal static string FormatException_UseMiddlewareExplicitArgumentsNotSupported(object p0) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_UseMiddlewareExplicitArgumentsNotSupported", Array.Empty<string>()), p0); //-- internal static string FormatException_InvokeDoesNotSupportRefOrOutParams(object p0) => string.Format((IFormatProvider)CultureInfo.CurrentCulture, GetString("Exception_InvokeDoesNotSupportRefOrOutParams", Array.Empty<string>()), p0); }