这个方法其实是工作的核心方法,通过这里可以看出来,自定义中间件的大致执行过程。代码中的注释我写的比较详细,有兴趣的可以仔细了解一下,如果懒得看我们就大致总结一下大致的核心点
首先UseMiddleware的本质确实还是执行的Use方法
实现IMiddleware接口的中间件走的是独立的处理逻辑,而且构造函数传递自定义的参数,因为它的数据来自于容器的注入。
基于约定定义中间件的情况,即不实现IMiddleware的情况下。
①基于约定定义的中间件,构造函数的第一个参数需要是RequestDelegate类型
②查找方法名可以为Invoke或InvokeAsync,且存在而且只能存在一个
③Invoke或InvokeAsync方法返回值需为Task,且方法的第一个参数必须为HttpContext类型
④Invoke或InvokeAsync方法如果只包含HttpContext类型参数,则该方法直接转换为RequestDelegate
⑤我们之所以可以通过构造注入在中间件中获取服务是因为基于约定的方式是通过ActivatorUtilities类创建的实例
通过上面的源码我们了解到了实现IMiddleware接口的方式自定义中间件的方式是单独处理的即在UseMiddlewareInterface方法中[],接下来我们查看一下该方法的代码
private static IApplicationBuilder UseMiddlewareInterface(IApplicationBuilder app, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type middlewareType) { return app.Use(next => { return async context => { var middlewareFactory = (IMiddlewareFactory?)context.RequestServices.GetService(typeof(IMiddlewareFactory)); if (middlewareFactory == null) { // 没有middlewarefactory直接抛出异常 throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoMiddlewareFactory(typeof(IMiddlewareFactory))); } //创建middleware实例 var middleware = middlewareFactory.Create(middlewareType); if (middleware == null) { throw new InvalidOperationException(Resources.FormatException_UseMiddlewareUnableToCreateMiddleware(middlewareFactory.GetType(), middlewareType)); } try { //执行middleware的InvokeAsync方法 await middleware.InvokeAsync(context, next); } finally { //释放middleware middlewareFactory.Release(middleware); } }; }); }