前言

  开发一个AspNetCore的中间件需要理解RequestDelegate。另外,还需要理解.NET Core中的依赖注入。还有一个就是内嵌资源的访问。例如:EmbeddedFileProvider 的使用。那么本文就这三点做一个简单的介绍。理解了这些那么基本上开发下去就不难了。

RequestDelegate

  对于RequestDelegate的介绍,大家可以看一下这篇文章:https://www.cnblogs.com/artech/p/inside-asp-net-core-pipeline-01.html

  我这里就简单通过代码过一下,下面是一个简单的HelloWorld的例子。

  

namespace LayIM.AspNetCore.WebDemo.Middleware
{
public class HelloWorldMiddleWare
{
private readonly RequestDelegate next;
public HelloWorldMiddleWare(RequestDelegate next)
{
this.next = next;
} public async Task Invoke(HttpContext context)
{
await context.Response.WriteAsync("hello world");
}
} public static class HelloWorldExtensions
{
public static void UseHelloWorld(IApplicationBuilder builder)
{
builder.UseMiddleware<HelloWorldMiddleWare>();
}
}
}

  然后在Startup中将这个中间件注册到IApplicationBuilder中即可。就像 app.UseMvc() 一样。

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHelloWorld();
}

  看一下运行效果:

  那么这个就是RequestDelegate的用法,那么我们可以看到,在HelloWorldMiddleware中有一个类型为RequestDelegatenext变量。这样就使得调用链串联起来。我们通过RequestDelegate 就能做一些全局性的工作了,比如请求校验,筛选,日志,统计等等,看需求吧。然后在根据情况选择是否执行 next?.Invoke(context) 方法,将请求流程走下去,直到走完所有流程或者走到某个被拦截掉的流程为止。同样的道理,在LayIM.AspNetCore 中拦截了开头为{/layim}的请求。否则继续 执行其他业务逻辑。示例代码如下:

 if (context.IsLayIMRequest(options) == false)
{
await next?.Invoke(context);
return;
}

  虽然没有加注释,但是也能看得出来,判断是否是LayIM的请求,如果不是,直接跳过。

DependencyInjection

  依赖注入相信大家都很熟悉了,要说他有什么好处,最直观的一个好处就是解耦。在之前的LayIM_NetClient项目中,我是直接将融云的实现放到中间件中,这种就是耦合性太高。用户如果不想使用融云的话,就没法用了。那么在LayIM.AspNetCore 项目中,通过使用依赖注入的方式,将核心接口与实现类分离,达到不用改核心代码,直接扩展新的实现类即可做到业务实现转换。这里我直接用项目中的例子作为介绍:

  在初始化Middleware的时候,系统会自动将IServiceProvider注入到中间件中

 public LayIMMiddleware(RequestDelegate next, LayIMOptions options,IServiceProvider serviceProvider)
{
this.next = next;
this.options = options;
this.serviceProvider = serviceProvider;
LayIMServiceLocator.SetServiceProvider(this.serviceProvider);
}

  我通过LayIMServiceLocator 来保存IServiceProvider的实例,那么在使用的时候。通过它就可以得到我们想要的服务了。下面是一个获取Token的例子。在ILayIMServer 接口中定义了如下方法:

 TokenResult GetToken(string userId);

  然后在新的RongCloud项目中实现该方法,并且扩展IServiceCollection

 public class RongCloudServer : ILayIMServer
{
private readonly RongCloudConfig config;
public RongCloudServer(RongCloudConfig config)
{
this.config = config;
}
public TokenResult GetToken(string userId)
{
return new TokenResult
{
code = ,
msg = "ok",
token = ""
};
}
}
 public static void AddLayIM(this IServiceCollection services, RongCloudConfig config)
{
services.AddSingleton(config);
services.AddSingleton<ILayIMServer, RongCloudServer>();
}

  那么,在Demo中我们可以这么使用了:

 public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); services.AddLayIM(config =>
{
config.AppKey = "";
config.AppSecret = "";
});
}

  这里呢,如果不想使用融云通讯的话,可以自己去实现ILayIMServer接口,然后做自己的扩展即可。

  核心端依赖于接口,处理逻辑如下:(其他代码可先忽略,暂时看中间两行代码)

 //获取连接websocket的token
routes.AddQueryCommand("/token", context =>
{
var server = LayIMServiceLocator.GetService<ILayIMServer>();
return server.GetToken(context.Request.Query["uid"]);
});

  可以看到,先通过ServiceLocator获取了ILayIMServer接口,然后调用接口方法即可。这样就达到了框架代码与实现代码解耦的目的。我们看一下效果:

  

  代码运行正常,在这里呢不在演示其他实现。如果不明白的小伙伴可以去下载代码调试,或者直接私信我即可。

EmbeddedFileProvider 

  好文推荐:https://www.cnblogs.com/artech/p/net-core-file-provider-04.html

  大家知道,正如SwaggerUI那样,为什么我们配置了,就能访问到UI界面呢?他的资源文件在哪里呢?其实这就是内嵌资源起到的作用。想深入理解的小伙伴可以查阅其他资料,这里我只是简单介绍如何去实现内嵌资源的访问。

  其实很简单,如下几句代码就搞定:

  app.UseFileServer(new FileServerOptions
{
RequestPath = options.ApiPrefix,
FileProvider = new EmbeddedFileProvider(assembly, "namespace"),
});

  可以看到,FileProviderEmbeddedFileProvider,其中传入了两个参数,一个是程序集,一个是静态资源的命名空间。

  不过当我们添加静态文件之后需要注意的是,要将文件生成操作属性设置成为嵌入的资源,否则访问不到。(不过还有使用配置文件的做法)

  那么这样的话,我们访问一下静态资源,效果如下:

  

  那么动态资源和静态资源都可以访问了,那么我们就可以进行下一步的工作了。

总结

  本文简单介绍了中间件的基础知识和使用方式、嵌入资源的访问以及依赖注入的简单使用,之所以说是预备知识,是因为在后续的开发过程中都会使用到。

   博客预告:LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建

   项目地址:https://github.com/fanpan26/LayIM.AspNetCore (本文代码对应blog2分支)欢迎小伙伴们star 围观 提意见。

LayIM.AspNetCore Middleware 开发日记(二)预备知识介绍的更多相关文章

  1. LayIM.AspNetCore Middleware 开发日记(一)闲言碎语

    前言 前几天写博客的时候突然看见了历史上的今天.不禁感慨时光如梭,这系列博客后来被我标注了已经过时,但是还有很多小伙伴咨询我.既然过时就要更新,正好 .NET Core 也出来很久了,于是乎想到把La ...

  2. LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建

    前言 在上一篇中简单讲了一些基础知识,例如Asp.Net Core Middleware 的使用,DI的简单使用以及嵌入式资源的使用方法等.本篇就是结合基础知识来构建一个基础框架出来. 那么框架有什么 ...

  3. LayIM.AspNetCore Middleware 开发日记(四)主角登场(LayIM介绍)

    前言 在前几篇中已经初步介绍了开发AspNetCore中间件的一些基础知识,不过都没有很深入的去研究,后续还是需要去看看源码.本篇呢,终于有点开头的味道了,就是要介绍LayIM了,其实标题写的是主角, ...

  4. LayIM.AspNetCore Middleware 开发日记(五)Init接口实现细节

    前言 “一旦开始了就要坚持下去“.为什么本文的第一句话是这么一句话呢,因为我经常就是开头轰轰烈烈,结果越来越枯燥,就不想做下去了.但是版图就放弃又那么不甘心,继续加油吧. 吐槽完毕,进入正题.在上一篇 ...

  5. LayIM.AspNetCore Middleware 开发日记(六)嵌入资源的使用,layim.config的封装

    前言 距离上一篇博客竟然已经10多天了...工作上的事,个人原因,种种吧.不多说废话,本文将会重点介绍layim的入口配置. LayIM配置 其实在开发者文档里面已经描述的很清楚了.除了几个重要的接口 ...

  6. LayIM.AspNetCore Middleware 开发日记(七)Asp.Net.Core.SignalR闪亮登场

    前言   前几篇介绍了整个中间件的构成,路由,基本配置等等.基本上没有涉及到通讯部分.不过已经实现了融云的通讯功能,由于是第三方的就不在单独去写.正好.NET Core SignalR已经出来好久了, ...

  7. 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上)

    为了介绍使用ASP.NET Core构建GraphQL服务器,本文需要介绍一下GraphQL,其实看官网的文档就行. 什么是GraphQL? GraphQL 既是一种用于 API 的查询语言也是一个满 ...

  8. 基于Golang的游戏服务器框架cellnet开发日记(二)

    看官们肯定还有大部分不是很熟悉Actor模型. 我这里基于Erlang, Skynet等语言和框架库来实战型解释下Actor模型.  Actor概念 Actor模型和OO类似, 都是符合人的思维模式进 ...

  9. 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下)

    上一篇文章:https://www.cnblogs.com/cgzl/p/9734083.html 处理数据 嵌套字段 看例子: 我想查看viewer下的repositories.注意里面的edges ...

随机推荐

  1. 七、并发容器ConcurrentHashMap

    一.简介 我们知道,HashMap是线程不安全的.而HashTable是线程安全的,但是JDK已经不建议使用HashTable,它已经被作为废除的实现. 在JDK并发包里面,ConcurrentHas ...

  2. centos 网络很慢且无法远程登陆的解决办法

    安装了centOS,但是发现网速实在是卡得几乎不能上网,连百度都打不开 后来想到偶然记得有一次看过一段话,说到关闭ipv6,测试来一下,果然有效,关闭来ipv6打开网速飞快. 关闭方法,在/etc/m ...

  3. 基于SSM框架配置多数据源

    项目基于ssm + maven,通过注解可以实现自动切换数据源. 一.pom.xml <?xml version="1.0" encoding="UTF-8&quo ...

  4. java:模拟栈操作

    import java.util.ArrayList; public class MyStack { private ArrayList<Object> arrayList; public ...

  5. RegExp对象的exec方法

    RegExp对象的exec方法和String对象的match方法用法十分相似,分两篇博客讲讲其各自的用法和它们之间的异同. 下一篇讨论match方法的用法和两者的异同. 定义及语法 [定义] exec ...

  6. 007Spring Security

    01.基于Spring AOP 和 Servlet规范中Filter实现  的安全框架 <dependency> <groupId>org.springframework.se ...

  7. vue-cli构建项目 npm run build后应该怎么运行在本地查看效果

    问题: 就是 bulid 打包后,想本地看看效果,本地看不了.... 网上看到一个....   具体更多在: http://www.dabaipm.cn/static/frontend/346.htm ...

  8. 一键清理 Nexus 中无用的 Docker 镜像

    现许多团队使用 Nexus 来管理 Docker 镜像,产品不断迭代,镜像仓库占用的磁盘空间也越来越大.由于 Nexus 的控制台并未提供批量操作镜像功能,清理镜像十分不便.本文分享一个清理 Nexu ...

  9. 自定义BaseActivity

    思路很简单:将软件里用到的大量重复的页面布局抽象出来,编写成一个抽象的Activity类,然后在实现具体页面时继承它,并且在主内容空白区填入需要的内容. 例如在最近开发的一款资讯类应用中,每张页面上面 ...

  10. 《ArcGIS Runtime SDK for Android开发笔记》——(4)、基于Android Studio构建ArcGIS Android开发环境

    1.前言 2015年1月15日,发布ArcGIS Runtime SDK for Android v10.2.5版本.从该版本开始默认支持android studio开发环境,示例代码的默认开发环境也 ...