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. 一次eureka的事故

    本地起了一个微服务(不知道怎么起的),导致注册到微服务上了,不知所措.. 想了下,杀死对应微服务的进程id就可以了(记不住啊!!)

  2. 【CDH】cdh搭建遇到的坑和解决过程

    本人安装CDH时,使用的是在线安装方式,就是yum install XXX XXX XXX这种.所以安装目录都是默认的目录. Linxu:centos 7 一,启动cloudera-scm-agent ...

  3. 高校github课程资源汇总

    序号 学校名称 学校类型 课程资源链接 1 清华大学 Top 计算机系课程攻略 https://github.com/Salensoft/thu-cst-cracker https://github. ...

  4. JAVA诞生历史【转载】

    一.计算机语言的发展史 1.第一代语言(只有机器能读懂,人根本读不懂) 纯机器语言 2.第二代语言(机器能读懂,人可以读懂,但是很难懂) 汇编语言(符号语言) 3.第三代语言(机器能读懂,也非常便于人 ...

  5. PHP_递归实现无限级分类

    <?php /** * 递归方法实现无限级别分类 * @param array $list 要生成树形列表的数组[该数组中必须要有主键id 和 父级pid] * @param int $pid= ...

  6. T137233 魔术增幅

    设答案为$g$,那么肯定有$g\mid M$. 再设$M=\sum\limits_{i=1}^N a_i=g\times \sum\limits_{i=1}^N t_i$. 因为$t_i$都是正整数, ...

  7. 多个if...else和switch...case语句的区别和分析

    1.场景: 当我们有一个判断条件的时候,显然用if语句比较方便有效. 但当判断条件很多的时候,我们可以使用if语句或者if....eles 语句和switch  case 语句. 2.如何选择 一般情 ...

  8. Linux 配置共享目录方法

    配置共享目录有三种方法: 第一种:使用Vmware自带的文件共享的功能,进入Vmware,点击虚拟机选项,然后点击"设置",再点击标签"选项"这一项,找到&qu ...

  9. nginx 结合tomcat 双机热备

    相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能很多人都听说,但具体什么是反向代理,很多人估计就不清楚了 ...

  10. appium遇到的问题

    问题1:权限问题:java.lang.SecurityException: Injecting to another application requires INJECT_EV ENTS permi ...