.NET6中一些常用组件的配置及使用记录,持续更新中。。。
NET6App
介绍
.NET 6的CoreApp框架,用来学习.NET6的一些变动和新特性,使用EFCore,等一系列组件的运用,每个用单独的文档篇章记录,持续更新文档哦。
如果对您有帮助,点击右上角Star关注 ,感谢支持开源!
软件架构
分为模型层,服务层,接口层来做测试使用
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中一些常用组件的配置及使用记录,持续更新中。。。的更多相关文章
- JavaScript中一些你不一定知道的问题(持续更新中。。。。)
一些js的问题与解析 1) ["1","2","3"].map(parseInt);的运行结果是? A.["1",&qu ...
- 平时常用的Visual Studio操作技巧,持续更新中……
移除未使用的命名空间--方法1:右键--"组织using"--"移除未使用的using"--方法2:Shift+F10--"O"-" ...
- C# 知识点记录(持续更新中)
从看C#入门经典开始系统的学习C#,本文主要记录学习过程中的一些知识点,也是我博客生涯的开始,比较重要成体系的部分会单重新写文章整理归纳. 1.一字不变的字符串 @字符 使转义序列不被处理,按照原样输 ...
- Linux系统编程重要细节记录(持续更新中)
1.在打印rlim_t值时,需要将其转换为long long并使用%lld printf()修饰符.
- vue项目常用方法封装,持续更新中。。。
vue项目中可以直接使用 1.常用工具类untils.js中 /* * 验证手机号是否合格 * true--说明合格 */ export function isPhone(phoneStr){ let ...
- iOS --- 总结Objective-C中经常使用的宏定义(持续更新中)
将iOS开发中经常使用的宏定义整理例如以下,仅包括Objective-C. 而对于Swift,不能使用宏,则能够定义全局函数或者extension.请參考博客iOS - 总结Swift中经常使用的全局 ...
- RN中的常用组件-----图片
1.RN中的常用组件-----图片 本地图片: <Image source={require('../src/assets/x.jpg')}/> 本地图片可以无需指定尺寸(因为导入/打包 ...
- 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)
Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...
- git常用命令(持续更新中)
git常用命令(持续更新中) 本地仓库操作git int 初始化本地仓库git add . ...
随机推荐
- 洛谷 P4564 [CTSC2018]假面(期望+dp)
题目传送门 题意: 有 \(n\) 个怪物,第 \(i\) 个怪物初始血量为 \(m_i\).有 \(Q\) 次操作: 0 x u v,有 \(p=\frac{u}{v}\) 的概率令 \(m_x\) ...
- Topcoder 12519 ScotlandYard(点对 dp+最长路)
题面传送门 题意: 有两个人 A 和 B 玩一个游戏.游戏规则大致是这样的: 有 \(n\) 个城市和三种交通工具公交.地铁和出租车. 给出三个 \(n\times n\) 的字符矩阵 \(b,m,t ...
- Codeforces 446C - DZY Loves Fibonacci Numbers(斐波那契数列+线段树)
Codeforces 题目传送门 & 洛谷题目传送门 你可能会疑惑我为什么要写 *2400 的题的题解 首先一个很明显的想法是,看到斐波那契数列和 \(10^9+9\) 就想到通项公式,\(F ...
- windows系统开/关机日志位置
邮件计算机=>管理 =>系统工具=>事件查看器=>Windows日志=>系统 过滤:关机:事件ID=6006 开机:事件ID=6005
- C++ and OO Num. Comp. Sci. Eng. - Part 5.
类 class 关键字提供了一种包含机制,将数据和操作数据的方法结合到一起,作为内置类型来使用. 类可以包含私有部分,仅其成员和 friend 类访问,公有部分可以在程序中任意位置处访问. 构造函数与 ...
- annovar 注释除人类以外的SNP
1. 准备文件: ref.fa ref.gtf或者gff3,最好是gtf3,可将gff3转化为gtf sample.vcf 2. 用gff3ToGenePred与gtfToGenePred工具将gtf ...
- Linux服务器I/O性能分析-2
一.如何正确分析IO性能 1.1 BLKTRACE分析IO性能 之前的文章已经说明,要是系统发生I/O性能问题,我们常用的命令是无法精确定位问题(内核I/O调度器消耗的时间和硬件消耗的时间,这个不能作 ...
- 什么是GP、LP、PE、VC、FOF?
GP GP是General Partner的缩写,意思是普通合伙人.投资者经常听到的一些基金.风投等投资公司采用的就是普通合伙人的制度,在美国等发达国家,普通合伙人很常见. 其实,说白了,GP最开始指 ...
- mysql-计算排名
mysql计算排名,获取行号rowno 学生成绩表数据 SELECT * FROM table_score ORDER BY score DESC; 获取某个学生成绩排名并计算该学生和上一名学生成绩差 ...
- Excel—在Excel中利用宏定义实现MD5对字符串(如:手机号)或者文件加密
下载宏文件[md5宏] 加载宏 试验md5加密 可能遇到的问题 解决办法 下载宏文件[md5宏] 下载附件,解压,得md5宏.xla md5宏.zip 加载宏 依次打开[文件]-[选项]-[自定义功能 ...