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. redis底层数据结构之双向链表(linkedlist)

    双向链表(linkedlist) redis的双向链表(linkedlist)是基于链表的一种数据结构 链表是一种常见的基础数据结构,是一种非顺序存储数据的线性表,在每一个节点里存储了下一个节点的指针 ...

  2. CentOS7 搭建 PXE 安装系统

    1. PXE介绍 2. 服务的搭建 2.1 DHCP服务搭建 2.1.1 安装DHCP软件包 2.1.2 修改dhcp配置文件 2.1.3 开启DHCP服务 2.1.4 查看dhcp服务是否开启 2. ...

  3. django源码剖析(steup、runserver、生命周期)

    工作上会经常用到不熟悉的第三方模块,大多数时候会选择看文档.百度谷歌.看源码等形式去把它用起来.几年工作经验下来源码看的不少了,但当面试被问到django的生命周期时,只能浅谈根据wsgi协议会走ap ...

  4. 【Java】取n工作日后的日期(仅排除周六周日)

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java. ...

  5. Web安全与渗透测试笔记

    Web安全与渗透测试笔记 @author: lamaper 一.基本网络知识 (一)网络是怎样联通的 TCP/IP协议 Internet Http协议 (二)Http协议 http请求 一个完整的Ht ...

  6. [Swift]创建桥接文件,Swift使用MJRefresh刷新插件

    刚开始玩Swift,想做个下拉刷新的功能,发现在OC中用得比较多的第三方插件是MJRefresh.查了一下,在Swift中使用OC的插件要通过桥接文件,然后又百度一下怎么创建桥接文件,发现很多都是老司 ...

  7. idea启动项目,报java.lang.OutOfMemoryError: PermGen space 和启动项目很慢的问题解决

    启动一个老的项目,报错,查是内存溢出 进入 VM options 加上   -Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m   在 ...

  8. 通过一个简单的实例来展示 Java 编程,创建文件 HelloWorld.java

    public class HelloWorld { public static void main(String[] args) { System.out.println("Hello Wo ...

  9. SQL_TIP_JOIN_x

    没有条件的JOIN会导致数据数量变为两表的数据量的乘积结果. 用ON来在这些结果里进行筛选 on T1.A = T2.A的时候,如果T1的A是不重复的,则实际上是在对T2现有数据做筛选,结果数据量&l ...

  10. ansible笔记第三章(Ansible--tasks任务控制)

    (1)when判断语句 实践案例一.根据不同操作系统,安装相同的软件包 [root@m01 project1]# cat tasks_1.yml - hosts: oldboy tasks: - na ...