.NET6一些常用组件的配置及使用
软件架构
分为模型层,服务层,接口层来做测试使用
0.如何使用iconfiguration、environment
直接在builder后的主机中使用。
builder.configuration; builder.environment
1.如何使用swagger
.net 6 自带模板已经默认添加swagger,直接使用即可。
builder.services.addswaggergen(); if (app.environment.isdevelopment()) { app.useswagger(); app.useswaggerui(); }
2. 如何添加efcore到.net 6中
按照efcore常规使用方法,申明表的entity及dbcontext后,在program.cs文件中添加
builder.services.adddbcontext<service.datacontext>(opt => { opt.usesqlserver(builder.configuration.getconnectionstring("default")); });
即可在其他地方注入使用 datacontext
使用sqlite数据库,需要引用 microsoft.entityframeworkcore.sqlite,并在添加服务时,改为
opt.usesqlite(builder.configuration.getconnectionstring("default"));
包管理控制台数据库结构生成方法:
- 使用 add-migration 创建迁移
- 使用 update-database 更新数据结构
3.如何注入一个服务
builder.services.addscoped<useridentyservice>();
4.如何定义全局的using引用
在根目录下新建一个 cs文件,比如globalusing.cs,在里面添加你的全局引用,和常规引用不同的是,在using前面添加 global
global using service; global using entity; global using entity.dto;
5.如何使用autofac
添加 nuget 引用
autofac.extensions.dependencyinjection
program.cs文件添加autofac的使用和注入配置
builder.host.useserviceproviderfactory(new autofacserviceproviderfactory()); builder.host.configurecontainer<containerbuilder>(builder => { assembly assembly = assembly.load("service.dll"); builder.registerassemblytypes(assembly) //.asimplementedinterfaces()// 无接口的注入方式 .instanceperdependency(); });
此时即可构造函数注入使用。
6.如何使用log4net
添加引用
microsoft.extensions.logging.log4net.aspnetcore
新建配置文件 log4net.config;
添加service配置
//注入log4net builder.services.addlogging(cfg => { //默认的配置文件路径是在根目录,且文件名为log4net.config //cfg.addlog4net(); //如果文件路径或名称有变化,需要重新设置其路径或名称 //比如在项目根目录下创建一个名为config的文件夹,将log4net.config文件移入其中,并改名为log4net.config //则需要使用下面的代码来进行配置 cfg.addlog4net(new log4netprovideroptions() { log4netconfigfilename = "config/log4net.config", watch = true }); });
即可在需要的地方定义使用
_logger = logmanager.getlogger(typeof(usercontroller));
7.如何使用全局异常过滤器
首先新建 globalexceptionfilter 全局异常过滤器,继承于 exceptionfilter ,用于接收处理抛出的异常
public class globalexceptionfilter : iexceptionfilter { readonly iwebhostenvironment hostenvironment; readonly ilog logger; public globalexceptionfilter(iwebhostenvironment _hostenvironment) { this.hostenvironment = _hostenvironment; this.logger = logmanager.getlogger(typeof(globalexceptionfilter)); } public void onexception(exceptioncontext context) { if (!context.exceptionhandled)//如果异常没有处理 { var result = new apiresult { code = 500, issuccess = false, message = "服务器发生未处理的异常" }; if (hostenvironment.isdevelopment()) { result.message += "," + context.exception.message; result.data = context.exception.stacktrace; } logger.error(result); context.result = new jsonresult(result); context.exceptionhandled = true;//异常已处理 } } }
然后在service中添加全局异常过滤器
builder.services.addcontrollers(option => { option.filters.add<globalexceptionfilter>(); } );
添加控制器方法完成测试
[httpget("exception")] public apiresult exceptionaction() { throw new notimplementedexception(); }
8.如何使用redis做缓存
使用 stackexchange.redis 作为缓存组件(其他组件类似的使用方式)。nuget 安装 stackexchange.redis.extensions.core
首先,先建立一个类 redisclient ,用于管理redis的连接和操作,再建立一个 redisclientfactory 类,用于创建 redis的连接;
public class redisclient{...} public class redisclientfactory{...}
appsettings.json 中添加redis的配置
"redisconfig": { "redis_default": { "connection": "127.0.0.1:6379", "instancename": "redis1:" }, "redis_6": { "connection": "127.0.0.1:6379", "defaultdatabase": 6, "instancename": "redis2:" } }
service中添加 redis客户端的引用
//添加redis的使用 builder.services.addsingleton<redisclient>(_=> redisclientfactory.getinstance(builder.configuration));
一顿操作后,就可以在你想要使用redis的地方引用了
redisclient redisclient ... this.redisdb = redisclient.getdatabase("redis_default"); redisdb.stringset("clientid", "clientid", timespan.fromseconds(10));
要使用redis做分布式缓存,先引用 microsoft.extensions.caching.stackexchangeredis
//将redis分布式缓存服务添加到服务中 builder.services.addstackexchangerediscache(options => { //用于连接redis的配置 configuration.getconnectionstring("redisconnectionstring")读取配置信息的串 options.configuration = "redis_6";// configuration.getconnectionstring("redisconnectionstring"); //redis实例名redisdistributedcache options.instancename = "redisdistributedcache"; });
引用自 "分布式 redis 缓存"
9 如何添加使用定时任务组件
此处使用 hangfire 定时任务组件,轻便,可持久化,还有面板。
引用 hangfire 后,即可新增定时任务。
//启用hangfire服务. builder.services.addhangfire(x => x.usestorage(new memorystorage())); builder.services.addhangfireserver(); ... //启用hangfire面板 app.usehangfiredashboard(); //开启一个定时任务 recurringjob.addorupdate("test",() => console.writeline("recurring!"), cron.minutely());
访问 https://localhost:7219/hangfire 即可看到任务面板
10. 如何使用业务锁锁住下单或者支付操作
首先,做这个事需要能先构建出一个锁出来,这个锁有个锁的标识key,可以根据这个key判定key对应的锁是否存在,这样的话,在某个用户支付或者下单减库存啥的时候,就可以按照这个key先上锁,后面有用户走其他渠道进行同样的操作的时候,就可以根据是否上锁了,来判断操作能否继续。
比如一个支付订单的业务,可以在手机上操作,也可以在电脑上操作,这个时候就可以给支付接口上锁,只要一个支付过程存在着,并且没有超时,那就不能在其他渠道进行操作。
我们上面已经使用了redis,下面就用redis构建个锁来模拟这个操作,具体看代码:
/// <summary> /// 测试业务锁 /// </summary> /// <returns></returns> [httpget("lockhandle")] public async task<apiresult> lockhandle(int userid) { var key = "user"; var token = $"id:{userid}"; try { if (redisdb.locktake(key, token, timespan.fromseconds(50))) { await task.delay(30 * 1000); return await task.fromresult(apiresult.success($"id:{userid} 获取到锁了,操作正常,connectid:{request.httpcontext.connection.id}")); } else { return await task.fromresult(apiresult.fail($"有正在操作的锁,connectid:{request.httpcontext.connection.id}")); } } catch (exception) { throw; } finally { redisdb.lockrelease(key, token); } }
11. 如何配置跨域
此处主要记录全局跨域,不包括指定api跨域。先增加一个配置 "cors": "http:127.0.0.1:5001",配置可以跨域的url,也可以使用默认跨域配置。
host配置以下服务,按需使用:
builder.services.addcors(delegate (corsoptions options) { options.addpolicy("corspolicy", delegate (corspolicybuilder corsbuilder) { //指定url跨域 corsbuilder.withorigins(builder.configuration.getvalue<string>("cors").split(',')); //默认跨域 corsbuilder.setisoriginallowed((string _) => true).allowanymethod().allowanyheader() .allowcredentials(); }); });
12. 如何使用newtonsoftjson
.net6 默认的系列化库是内置的 system.text.json,使用中如果有诸多不熟悉的地方,那肯定是想换回 newtonsoftjson,需要nuget 引用 microsoft.aspnetcore.mvc.newtonsoftjson 来配置使用,常用配置包括日期格式、大小写规则、循环引用配置。。。等,下面是一个配置
builder.services.addcontrollers(option => { option.filters.add<globalexceptionfilter>(); } ).addnewtonsoftjson(options => { options.serializersettings.contractresolver = new camelcasepropertynamescontractresolver(); //序列化时key为驼峰样式 options.serializersettings.datetimezonehandling = datetimezonehandling.local; options.serializersettings.dateformatstring = "yyyy-mm-dd hh:mm:ss"; options.serializersettings.referenceloophandling = referenceloophandling.ignore;//忽略循环引用 });
13. 如何使用signalr
首先添加一个 chathub 作为 交互中心处理器
public class chathub : hub { public async task sendmessage(string user, string message) { await clients.all.sendasync("receivemessage", user, message); } }
在主机中使用服务
builder.services.addsignalr(); ... app.useendpoints(endpoints => { endpoints.maphub<chathub>("/chathub"); });
到此这篇关于.net6一些常用组件的配置及使用的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。