Net6 托管服务、FluentValidation

托管服务

1、场景,代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据导出到备份数据库,每隔5秒钟在两张表之间同步一次数据。 2、托管服务实现IHostedService接口,一般编写从BackgroundService继承的类。 测试:延迟若干秒再读取文件,再延迟,再输出。 3、services.AddHostedService< DemoBgService >();

4、从.NET 6开始,当托管服务中发生未处理异常的时候,程序就会自动停止并退出。可以把HostOptions.BackgroundServiceExceptionBehavior设置为Ignore,程序会忽略异常,而不是停止程序。不过推荐采用默认的设置,因为“异常应该被妥善的处理,而不是被忽略”。 5、要在ExecuteAsync方法中把代码用try……catch包裹起来,当发生异常的时候,记录日志中或发警报等。

在Program注入服务
 builder.Services.AddHostedService<DemoBgService>();
DemoBgService
 public class DemoBgService : BackgroundService
 {
  private ILogger<DemoBgService> logger;
  public DemoBgService(ILogger<DemoBgService> logger)
  {
  this.logger = logger;
  }
  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
  await Task.Delay(5000);
  string s = await File.ReadAllTextAsync("d:/1.txt");
  await Task.Delay(20000);
  logger.LogInformation(s);
  }
 }

托管服务中使用DI

1、托管服务是以单例的生命周期注册到依赖注入容器中的。因此不能注入生命周期为范围或者瞬态的服务。 比如注入EF Core的上下文的话,程序就会抛出异常。 2、可以通过构造方法注入一个IServiceScopeFactory服务,它可以用来创建一个IServiceScope对象,这样我们就可以通过IServiceScope来创建短生命周期的服务了。记得在Dispose中释放IServiceScope。

核心代码如下
     private readonly TestDbContext ctx;
  private readonly ILogger<ExplortStatisticBgService> logger;
  private readonly IServiceScope serviceScope;
  public ExplortStatisticBgService(IServiceScopeFactory scopeFactory)
  {
         //用IServiceScopeFactory创建一个IServiceScope对象
  this.serviceScope = scopeFactory.CreateScope();
  var sp = serviceScope.ServiceProvider;
  this.ctx = sp.GetRequiredService<TestDbContext>();
  this.logger = sp.GetRequiredService<ILogger<ExplortStatisticBgService>>();
  }
 //ExecuteAsync 方法里面按照上面的正常写逻辑即可
 ​
 //override Dispose方法
 public override void Dispose()
  {
  base.Dispose();
  serviceScope.Dispose();
  }

1、常驻后台的托管服务并不需要特殊的技术,我们只要让ExecuteAsync中的代码一直执行不结束就行了。 2、实现的功能就是每隔五秒钟对数据库中的数据做一下汇总,然后把汇总结果写入一个文本文件。

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
  while (!stoppingToken.IsCancellationRequested)
  {
  try
  {
  await DoExecuteAsync();
  await Task.Delay(5000);
  }
  catch (Exception ex)
  {
  logger.LogError(ex, "获取用户统计数据失败");
  await Task.Delay(1000);
  }
  }
  }
  private async Task DoExecuteAsync()
  {
  var items = ctx.Users.GroupBy(u => u.CreationTime.Date)
  .Select(e => new { Date = e.Key, Count = e.Count() });
  StringBuilder sb = new StringBuilder();
  sb.AppendLine($"Date:{DateTime.Now}");
  foreach (var item in items)
  {
  sb.Append(item.Date).AppendLine($":{item.Count}");
  }
  await File.WriteAllTextAsync("d:/1.txt", sb.ToString());
  logger.LogInformation($"导出完成");
  }

如果是写定时服务每隔一段时间要执行什么,

Hangfire 定时服务框架 自己看资料(学完整个书籍后面再来)

参考博客:https://www.cnblogs.com/Can-daydayup/p/11610747.html

Net6内置的数据校验

内置数据校验机制

1、.NET Core中内置了对数据校验的支持,在System.ComponentModel.DataAnnotations这个命名空间下,比如[Required]、[EmailAddress] 、[RegularExpression]。CustomValidationAttribute、IValidatableObject。 2、演示其在ASP.NET Core中请求中的使用。 3、内置的校验机制的问题:校验规则都是和模型类耦合在一起,违反“单一职责原则”;很多常用的校验都需要编写自定义校验规则,而且写起来麻烦。

 using System.ComponentModel.DataAnnotations;
 ​
 public class Login1Request
 {
  [Required]
  [EmailAddress]
  [RegularExpression("^.*@(qq|163)\\.com$", ErrorMessage = "只支持QQ和163邮箱")]
  public string Email { get; set; }
  [Required]
  [StringLength(10, MinimumLength = 3)]
  public string Password { get; set; }
  [Compare(nameof(Password2), ErrorMessage = "两次密码必须一致")]
  public string Password2 { get; set; }
 }
FluentValidation的基本使用

1、FluentValidation:用类似于EF Core中Fluent API的方式进行校验规则的配置,也就是我们可以把对模型类的校验放到单独的校验类中。 2、 FluentValidation在ASP.NET Core项目中的用法 (NuGet:FluentValidation.AspNetCore)

Entity(为了方便写成record类型 打印测试也方便一些)
 namespace FluentValidations;
 {
    public record Login2Request(string Email, string Password, string Password2);
 }
EntityValidation
 using FluentValidation;
 ​
 namespace FluentValidations;
 public class Login2RequestValidator : AbstractValidator<Login2Request>
 {
  public Login2RequestValidator()
  {
  RuleFor(x => x.Email).NotNull().EmailAddress()
  .Must(v => v.EndsWith("@qq.com") || v.EndsWith("@163.com"))
  .WithMessage("只支持QQ和163邮箱");
  RuleFor(x => x.Password).NotNull().Length(3, 10)
  .WithMessage("密码长度必须介于3到10之间")
  .Equal(x => x.Password2).WithMessage("两次密码必须一致");
  }
 }
Program 注入Validation
 builder.Services.AddFluentValidation(fv => {
     Assembly assembly = Assembly.GetExecutingAssembly();
     fv.RegisterValidatorsFromAssembly(assembly);
 });

FluentValidation + DI(可以在Validation通过DI使用对应的服务)

 using FluentValidation;
 using FluentValidations;
 ​
 public class Login3RequestValidator : AbstractValidator<Login3Request>
 {
  public Login3RequestValidator(TestDbContext dbCtx)
  {
  RuleFor(x => x.UserName).NotNull()
  .Must(name => dbCtx.Users.Any(u => u.UserName == name))
  .WithMessage(c => $"用户名{c.UserName}不存在");
  }
 }

本文内容大部分都为杨中科老师《ASP.NET Core技术内幕与项目实战》一书中内容,此文只是做学习记录,如有侵权,联系立马删除。

 

Net6 托管服务、FluentValidation的更多相关文章

  1. Asp.NetCore3.1开源项目升级为.Net6.0

    概述 自从.Net6.0出来后,一直想之前开发的项目升级.Net6.0,有时想想毕竟中间还跨了个5.0版本,升级起来不知道坑大不大,最近抽时间对升级的方案做了些研究,然后将代码升级为.Net6.0.本 ...

  2. .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)

    在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...

  3. .NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一)

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下FluentValidation验证组件.那里只是概述了一下,并没有对其使用和强大功能做深入研究 ...

  4. 常用Git代码托管服务分享

    Git Repository代码托管服务越来越流行,目前有很多商业公司和个人团队逐渐切换项目到 Git平台进行代码托管.本文分享一些常用的Git代码托管服务,其中一些提供私有项目保护服务,特别有利于远 ...

  5. FluentValidation

    git :https://github.com/JeremySkinner/FluentValidation Example using FluentValidation; public class ...

  6. 手动删除portal中托管服务。

    在portal中将server作为托管联合服务器,然后发布了托管服务.若中间取消了托管联合服务器,再重新连接,那么会出现之前的托管服务无法删除的现象. 下文为怎样手动删除这些服务的方法,(不过貌似之后 ...

  7. Git 的深入理解与GitHub托管服务(转)

    源代码管理系统(SCM)与版本控制   版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统.   本地版本控制系统   许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会 ...

  8. FluentValidation验证

    参考:http://www.c-sharpcorner.com/UploadFile/3d39b4/Asp-Net-mvc-validation-using-fluent-validation/ 创建 ...

  9. ASP.NET MVC中使用FluentValidation验证实体

    1.FluentValidation介绍 FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开来的 ...

  10. 使用GIT进行源码管理——GIT托管服务

    虽然GIT是分布式代码管理,但是仍然需要一个集中存储服务以实现团队协作和代码备份的.对于企业的私有代码来说,大多是自建GIT托管服务.但对于开源项目和个人的私有项目,往往是选择一个GIT托管网站,这样 ...

随机推荐

  1. ELK分布式日志系统的搭建

    前言 ELK即分别为ElasticSearch.Logstash(收集.分析.过滤日志的工具).Kibana(es的可视化工具),其主要工作原理就是由不同机器上的logstash收集日志后发送给es, ...

  2. Launchpad是什么?Launchpad使用教程

    ​ Launchpad是什么?Launchpad 是用来查找和打开Mac系统下的 app 的最快捷方式,通过 Launchpad,您可以查看.整理并轻松打开Mac里面几乎所有的应用软件.下面带来Mac ...

  3. kunkun

    <html> <head> <title>cxk</title> </head> <body><h1>给设计师:字体 ...

  4. Pytest 插件

    1. 执行标记用例执行次数 首先安装 repeat: pip install pytest-repeat @pytest.mark.repeat(n)执行当前用例 n 次 然后再往下执行其他用例 im ...

  5. Ping命令的基本使用

    一.Ping命令的基本使用 在网络中 ping 是一个十分强大的 TCP/IP 工具.我们通常会用它来直接 ping ip 地址,来测试网络的连通情况.它的作用主要为: 1.用来检测网络的连通情况和分 ...

  6. TCAM and CAM memory usage inside networking devices(转)

    TCAM and CAM memory usage inside networking devices Valter Popeskic Equipment and tools, Physical la ...

  7. Request processing failed;

    用 ssm 框架修改数据库数据时,出现了 Request processing failed; nested exception is org.mybatis.spring.MyBatisSystem ...

  8. random随机数模块

    #wuyanfengimport random'''random.random()#随机数0到1的浮点数模块random.randint(1,7)#随机1到7闭区间的整数random.randrang ...

  9. What does int main(int argc, char *argv[]) mean?

    忽然发现自己不理解许多代码中这行的含义是什么...(汗颜) 下面贴一段stackoverflow上面的回答: argv and argc are how command line arguments ...

  10. 【BOOK】数据存储--MongoDB

    MongoDB存储 1.链接MongoDB        指定数据库        指定集合 import pymongo ## 连接数据库 client = pymongo.MongoClient( ...