LayIM.AspNetCore Middleware 开发日记(二)预备知识介绍
前言
开发一个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中有一个类型为RequestDelegate的next变量。这样就使得调用链串联起来。我们通过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"),
});
可以看到,FileProvider是EmbeddedFileProvider,其中传入了两个参数,一个是程序集,一个是静态资源的命名空间。
不过当我们添加静态文件之后需要注意的是,要将文件生成操作属性设置成为嵌入的资源,否则访问不到。(不过还有使用配置文件的做法)
那么这样的话,我们访问一下静态资源,效果如下:
那么动态资源和静态资源都可以访问了,那么我们就可以进行下一步的工作了。
总结
本文简单介绍了中间件的基础知识和使用方式、嵌入资源的访问以及依赖注入的简单使用,之所以说是预备知识,是因为在后续的开发过程中都会使用到。
博客预告:LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建
项目地址:https://github.com/fanpan26/LayIM.AspNetCore (本文代码对应blog2分支)欢迎小伙伴们star 围观 提意见。
LayIM.AspNetCore Middleware 开发日记(二)预备知识介绍的更多相关文章
- LayIM.AspNetCore Middleware 开发日记(一)闲言碎语
前言 前几天写博客的时候突然看见了历史上的今天.不禁感慨时光如梭,这系列博客后来被我标注了已经过时,但是还有很多小伙伴咨询我.既然过时就要更新,正好 .NET Core 也出来很久了,于是乎想到把La ...
- LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建
前言 在上一篇中简单讲了一些基础知识,例如Asp.Net Core Middleware 的使用,DI的简单使用以及嵌入式资源的使用方法等.本篇就是结合基础知识来构建一个基础框架出来. 那么框架有什么 ...
- LayIM.AspNetCore Middleware 开发日记(四)主角登场(LayIM介绍)
前言 在前几篇中已经初步介绍了开发AspNetCore中间件的一些基础知识,不过都没有很深入的去研究,后续还是需要去看看源码.本篇呢,终于有点开头的味道了,就是要介绍LayIM了,其实标题写的是主角, ...
- LayIM.AspNetCore Middleware 开发日记(五)Init接口实现细节
前言 “一旦开始了就要坚持下去“.为什么本文的第一句话是这么一句话呢,因为我经常就是开头轰轰烈烈,结果越来越枯燥,就不想做下去了.但是版图就放弃又那么不甘心,继续加油吧. 吐槽完毕,进入正题.在上一篇 ...
- LayIM.AspNetCore Middleware 开发日记(六)嵌入资源的使用,layim.config的封装
前言 距离上一篇博客竟然已经10多天了...工作上的事,个人原因,种种吧.不多说废话,本文将会重点介绍layim的入口配置. LayIM配置 其实在开发者文档里面已经描述的很清楚了.除了几个重要的接口 ...
- LayIM.AspNetCore Middleware 开发日记(七)Asp.Net.Core.SignalR闪亮登场
前言 前几篇介绍了整个中间件的构成,路由,基本配置等等.基本上没有涉及到通讯部分.不过已经实现了融云的通讯功能,由于是第三方的就不在单独去写.正好.NET Core SignalR已经出来好久了, ...
- 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上)
为了介绍使用ASP.NET Core构建GraphQL服务器,本文需要介绍一下GraphQL,其实看官网的文档就行. 什么是GraphQL? GraphQL 既是一种用于 API 的查询语言也是一个满 ...
- 基于Golang的游戏服务器框架cellnet开发日记(二)
看官们肯定还有大部分不是很熟悉Actor模型. 我这里基于Erlang, Skynet等语言和框架库来实战型解释下Actor模型. Actor概念 Actor模型和OO类似, 都是符合人的思维模式进 ...
- 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下)
上一篇文章:https://www.cnblogs.com/cgzl/p/9734083.html 处理数据 嵌套字段 看例子: 我想查看viewer下的repositories.注意里面的edges ...
随机推荐
- sql语句优化总结
sql语句优化总结 数据库优化的几个原则: 1.尽量避免在列上做运算,这样会导致索引失败: 2.使用join是应该用小结果集驱动大结果集,同时把复杂的join查询拆分成多个query.不然join的越 ...
- Fill Table Row(it’s an IQ test question)
Here is a table include the 2 rows. And the cells in the first row have been filled with 0~4. Now yo ...
- 并发模型之Future设计模式
一.Futrue模式 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经 ...
- ajax+json+ashx实现一个页面多个tab的分页
1:项目功能需求:我的荣誉.审核中的荣誉.审核通过的荣誉在一个页面分别作列表展示.每个tab都需要分页,对实现的功能做个简单总结. 2:前台页面:引用的DBPage.js和pageCss.css实现分 ...
- WC2017 游记
你若安好,便是晴天. 其实本来是有一个写的比较详细的游记的……然而后来给断了,懒得补上了,简单一点好了. Day 0 早早爬起来去赶高铁…… 路上没太多可以写的……坐高铁的时候想起来了一些不开心的事情 ...
- HTML5之新增的元素和废除的元素 (声明:内容节选自《HTML 5从入门到精通》)
新增结构元素: section元素 section元素定义文档或应用程序中的一个区段,比如章节.页眉.页脚或文档中的其他部分.它可以与h1,h2,h3,h4,h5,h6元素结合起来使用,标示文档结构. ...
- 04.CSS动画示例-->烟花
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 利用localStorage事件来跨标签页共享sessionStorage
//干货 利用localStorage事件来跨标签页共享sessionStorage //因为cookie保存字节数量有限,很多童鞋考虑用html5 storage来保存临时数据,Sessionsto ...
- Android学习笔记(2)----LocationManager的使用
今天使用Android的LocationManager制作了一款获取当前经纬坐标位置的软件. LocationManager获取的只是经纬坐标点,为了解析出当前经纬坐标点的实际位置,可以使用Googl ...
- vue之computed(计算属性)
所谓计算属性就是计算data里的数据属性. computed:实时监听的该功能. 即监听是否有修改(浏览器未打开时即开始监听了),监听的值有修改则添加 所监听的data数据属性变化了,自动实时修改. ...