[toc]web
做为WebApi接口工程,性能效率是必不可少的,每次的访问请求,数据库读取,业务逻辑处理都或多或少耗费时间,偶尔再来个各类花式for循环,那就嗨翻天了,一些公有的数据,访问频繁且大体重复的数据,咱们能够考虑经过缓存来放置内存存储,之内存空间换取时间上的提高,至于缓存的方法,Cache,Session,Cookie等,为何用等呢,由于还有不少缓存的方法,如Redis,具体后面用到了会专门介绍。数据库
net core中没有Cache,可是它有MemoryCache,其实,大差不差,毕竟都是Cache。浏览器
Cache在项目工程中使用的范围仍是挺普遍的:缓存
首先,引入Microsoft.Extensions.Caching.Memory性能优化
这里我直接在Util引入,前面已经讲了,一个工程引入第三方,其余工程引入项目工程便可使用对应第三方类库。 引入完成后,咱们就开始来使用这个MemoryCache吧。服务器
//实例化 private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions()); /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过时时长(若是在过时时间内有操做,则以当前时间点延长过时时间)</param> /// <param name="expiressAbsoulte">绝对过时时长</param> /// <returns></returns> public static bool Set(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); Cache.Set(key, value, new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding) .SetAbsoluteExpiration(expiressAbsoulte)); return Exists(key); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过时(若是在过时时间内有操做,则以当前时间点延长过时时间)</param> /// <returns></returns> public static bool Set(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); Cache.Set(key, value, isSliding ? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn) : new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn)); return Exists(key); }
这个地方大体列下如何使用,其实对于第三方的包,咱们封装是为了减小其余开发人员的学习成本,后面的SqlSugar等类库同样,其实自己第三方已经作了一次封装整合,而咱们是由于实际开发须要来针对不一样的业务功能作不一样的封装整合,接口开放等。cookie
补个测试效果,写到Session才想起来,唉,果真写东西不能让打断,-,-||。session
注意观察时间,一段时间后Cache过时销毁。app
最初鼓捣net core的时候,我确实没有过多关注Session这个会话模式,毕竟只有浏览器才能使用,以前跟别人谈到Session多爽的时候,说道Session其实本质上相似Cookie(固然我也不清楚),由于用户访问后会有个SessionID,有状态的访问会留下Cookie也是情有可原的,若是用户本身整个隐私模式访问,那,再见(你就在登陆界面循环往复吧)。负载均衡
在用户登陆后,Session存储用户基本登陆信息这个是web端经常使用的手段,毕竟跟浏览器打交道Cookie少不了,对于无状态访问受权的JWT也是折腾过,不过仍是理解不透彻,统一的授发token的方式仍是挺可取的,若是是多服务,多应用,负载均衡的场景,单点登陆确实方便,可是我常规会本身生成token来经过Session或者Redis存储,实际效果应该是差很少吧。 好了,废话很少说,同样是引入Microsoft.AspNetCore.Session
引入完成后,在Startup.cs注册Session服务。
public void ConfigureServices(IServiceCollection services) { //…以前的代码 #region Session services.AddSession(options => { options.Cookie.Name = "April.Session"; options.IdleTimeout = TimeSpan.FromSeconds(2000);//设置session的过时时间 options.Cookie.HttpOnly = true;//设置在浏览器不能经过js得到该cookie的值,实际场景根据自身须要 }); #endregion }
注册服务后,须要在ConfigConfigure使用,注意全部的Use要在UserMvc以前才能生效。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //…以前的代码 app.UseSession();//这里使用 app.UseHttpsRedirection(); app.UseMvc(); }
在Util建立一个SessionUtil,来封装Session方法,这里只简单描述下如何使用,后续代码开源后可查看源码使用。
public class SessionUtil { /// <summary> /// 设置Session /// </summary> /// <param name="key">键</param> /// <param name="value">值</param> public void SetSession(HttpContext content,string key, string value) { content.Session.SetString(key, value); } /// <summary> /// 获取Session /// </summary> /// <param name="key">键</param> /// <returns>返回对应的值</returns> public string GetSession(HttpContext context, string key, string defaultValue = "") { string value = context.Session.GetString(key); if (string.IsNullOrEmpty(value)) { value = defaultValue; } return value; } }
咱们依然拿这个万恶的ValuesController开刀。
运行后,访问这个Values/接口,发现咱们的Session值已经获取到了。
HttpContext这个对象,能够经过IServiceProvider来获取,这样方便调用统一维护。 新建AprilConfig类文件,代码以下:
public class AprilConfig { public static IServiceProvider _provider; public static HttpContext HttpCurrent { get { object factory = _provider.GetService(typeof(IHttpContextAccessor)); HttpContext context = ((IHttpContextAccessor)factory).HttpContext; return context; } } }
写好后咱们须要回到Startup.cs,给IserviceProvider赋值。
SessionUtil代码修改调整,不须要再传HttpContext这个参数。
这样少传一个是一个,后续用到HttpContext这个上下文的时候,也不用考虑啥了,直接AprilConfig.HttpCurrent走起。
Cookie在web开发使用的仍是至关频繁的,毕竟不占用服务器内存,跟服务器基本上没半毛钱关系,客户端的内存想咋折腾咋折腾,客户端的资源想咋使用咋使用(ps:这就是为啥你的电脑愈来愈卡,软件开发不考虑性能优化的种种结果)。
Cookie自己在net core中已经支持,因此不须要引入啥NuGet包。
新建CookieUtil(不要吐槽个人命名方法,习惯了)。
public class CookieUtil { /// <summary> /// 设置本地cookie /// </summary> /// <param name="key">键</param> /// <param name="value">值</param> /// <param name="minutes">过时时长,单位:分钟</param> public static void SetCookies(string key, string value, int minutes = 10) { AprilConfig.HttpCurrent.Response.Cookies.Append(key, value, new CookieOptions { Expires = DateTime.Now.AddMinutes(minutes) }); } /// <summary> /// 删除指定的cookie /// </summary> /// <param name="key">键</param> public static void DeleteCookies(string key) { //这个地方想判断就判断下,不过内部封装的方法应该是已经作过处理 AprilConfig.HttpCurrent.Response.Cookies.Delete(key); } /// <summary> /// 获取cookies /// </summary> /// <param name="key">键</param> /// <returns>返回对应的值</returns> public static string GetCookies(string key,string defaultValue="") { string value = string.Empty; AprilConfig.HttpCurrent.Request.Cookies.TryGetValue(key, out value); if (string.IsNullOrEmpty(value)) { value = defaultValue; } return value; } }
写好以后,老规矩ValuesController走一波。
测试结果:
从建立工程到在线文档,日志管理,缓存机制基本上走了一遍了,下一步,就是数据层的操做,一个工程管理确定少不了数据的支撑,总不能每次都本身YY数据吧,下一节,数据库操做。
针对Session.SetString的方法没有问题,须要引入一个NuGet包,这个里面包含官方的扩展方法,Microsoft.AspNetCore.Http.Abstractions。