课程网站模板,深圳建筑工程交易服务中心网,绚丽网站模板,网站有哪些区别是什么意思这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能#xff1a;获取每日汇率。下面我们一起来编写代码吧。
一、需求
根据文章标题可知#xff0c;在这片文章中我们只进行汇率的获取和写入数据库。
编号需求说明1获取每日汇率1. 从第三方汇率API中获取汇率信…这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能获取每日汇率。下面我们一起来编写代码吧。
一、需求
根据文章标题可知在这片文章中我们只进行汇率的获取和写入数据库。
编号需求说明1获取每日汇率1. 从第三方汇率API中获取汇率信息并存入数据库中2. 每天凌晨1点获取汇率3. 目前仅支持人民币、日元、欧元、韩元、美元、港币、澳门元、英镑、新台币之间的汇率
二、功能编写
网上有很多获取汇率的API有收费的也有免费的由于我们开发的项目只是用于实战练习而不会真正的发布出去让别人使用因此我们选择免费的API。但是免费的API有好有坏有的API只提供有限的免费请求额度有的API只能免费使用很短的几天。所以即使是使用免费的API我们也要谨慎选择以免耽误我们的练习。 但是大家不用担心我已经为大家选好了一个不错的获取汇率的APIExchange Rate API 。它对免费用户提供每月1500次的接口调用并且可以一直使用免费的接口对于我们的项目来说已经足够了。
2.1 编写数据库映射类
我们的需求是获取每天的汇率因此我们的数据库映射类应该包含汇率日期字段Data。并且我们还需要保存币种之间的汇率因此还需要币种转换关系字段ConvertCurrency以及币种汇率字段ExchangeRate。 以下的代码就是根据前面分析所编写的数据库映射类ExchangeRateRecord再次强调的是ExchangeRateRecord 编写完后别忘了迁移数据库
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using SporeAccounting.BaseModels;namespace SporeAccounting.Models;/// summary
/// 汇率记录表
/// /summary
[Table(name: ExchangeRate)]
public class ExchangeRateRecord : BaseModel
{/// summary/// 汇率/// /summary[Column(TypeName decimal(10,2))][Required]public decimal ExchangeRate { get; set; }/// summary/// 币种转换/// /summary[Column(TypeName nvarchar(20))][Required]public string ConvertCurrency { get; set; }/// summary/// 汇率日期/// /summary[Column(TypeName date)][Required]public DateTime Date { get; set; }
}2.2 编写定时器
需求上说需要在每天凌晨1点获取当天的汇率因此需要编写一个定时器来定时执行获取汇率的工作。我们可以选择的定时器很多有.NET 原生的也有第三方的。在这里我们选择 Quartz.NETQuartz.NET 是 Quartz 的.NET版它在.NET领域中使用的最多。下面我们使用Quartz.NET一起来编写定时器。
安装 Quartz.NET 我们不直接使用Quartz.NET而是使用Quartz.NET的ASP.NET Core集成版。在Nuget中搜索Quartz.AspNetCore选择支持.NET8的最新版点击安装即可。编写Job 在Quartz中一个定时器就是一个Job。新建Job类ExchangeRateTimer它继承Quartz的IJob接口并实现Execute方法。在Execute方法中我们要实现向Exchange Rate API获取汇率的接口发送请求并获取汇率信息的功能以及将汇率信息存入数据库的功能。这里不多说直接上代码using System.Text.Json;
using Quartz;
using SporeAccounting.Models;
using SporeAccounting.Server.Interface;
using SporeAccounting.Task.Timer.Model;namespace SporeAccounting.Task.Timer;/// summary
/// 获取汇率定时器
/// /summary
public class ExchangeRateTimer : IJob
{private readonly IHttpClientFactory _httpClientFactory;private readonly IConfiguration _configuration;private readonly IServiceScopeFactory _serviceScopeFactory;private readonly ICurrencyService _currencyService;public ExchangeRateTimer(IHttpClientFactory httpClientFactory,IConfiguration configuration, IServiceScopeFactory serviceScopeFactory,ICurrencyService currencyService){_httpClientFactory httpClientFactory;_configuration configuration;_serviceScopeFactory serviceScopeFactory;_currencyService currencyService;}public System.Threading.Tasks.Task Execute(IJobExecutionContext context){string exchangeRateUrl _configuration[ExchangeRate];//获取全部币种ListCurrency currencies _currencyService.Query().ToList();//获取对每种币种的汇率foreach (var currency in currencies){_httpClientFactory.CreateClient().GetAsync(${exchangeRateUrl}{currency.Abbreviation}).ContinueWith(response {using var scope _serviceScopeFactory.CreateScope();var exchangeRateRecordService scope.ServiceProvider.GetRequiredServiceIExchangeRateRecordService();ListExchangeRateRecord exchangeRateRecords new();if (response.Result.IsSuccessStatusCode){var result response.Result.Content.ReadAsStringAsync().Result;var resultModel JsonSerializer.DeserializeExchangeRateApiData(result);if (resultModel?.Result success){foreach (var rate in resultModel.ConversionRates){//只获取人民币、日元、欧元、韩元、美元、港币、澳门元、英镑、新台币之间的汇率//其他币种的汇率直接跳过if (currencies.All(c c.Abbreviation ! rate.Key)){continue;}exchangeRateRecords.Add(new ExchangeRateRecord{Id Guid.NewGuid().ToString(),ExchangeRate rate.Value,//汇率记录的币种代码是基础币种代码和目标币种代码的组合ConvertCurrency ${resultModel.BaseCode}_{rate.Key},Date DateTime.Now,CreateDateTime DateTime.Now,CreateUserId System,IsDeleted false});}//存入数据库exchangeRateRecordService.Add(exchangeRateRecords);}}});}return System.Threading.Tasks.Task.CompletedTask;}
}这段代码看着很复杂其实是完全按照前面的需求实现的功能因此这里就不多讲解的。唯一需要注意的是的我们在ContinueWith方法的回调函数中使用了如下代码来获取IExchangeRateRecordService的实例 using var scope _serviceScopeFactory.CreateScope();
var exchangeRateRecordService scope.ServiceProvider.GetRequiredServiceIExchangeRateRecordService 为什么要这么做呢为什么不在构造函数中通过注入的方式获取呢这是因为我们使用异步的方式来获取汇率数据的因此ContinueWith内的方法是在另一个线程上运行的如果通过注入的方式在构造函数中获取IExchangeRateRecordService实例的话在Execute方法执行完毕后实例就被释放回收了因此这时如果在ContinueWith内的方法中使用IExchangeRateRecordService的实例就会出发链接已被关闭的异常。
2.3 配置定时器
Job的逻辑已经编写完了那么最后要做的就是配置定时器让它在凌晨一点是定时获取汇率信息。在Program类中加入如下代码 // 添加定时任务
builder.Services.AddQuartz(q
{var exchangeRateTimerJobKeynew JobKey(ExchangeRateTimer);q.AddJobExchangeRateTimer(optsopts.WithIdentity(exchangeRateTimerJobKey));q.AddTrigger(optsopts.ForJob(exchangeRateTimerJobKey).WithIdentity(ExchangeRateTimerTrigger).StartNow().WithCronSchedule(0 0 1 * * ?));
});
builder.Services.AddQuartzHostedService(options
{//启用 Quartz 的托管服务WaitForJobsToComplete true 表示在应用程序停止时等待任务完成后再关闭。options.WaitForJobsToComplete true;
});这段代码通过 AddQuartz 方法注册了 Quartz 服务容器在配置定时Job和触发器时我们先创建了一个唯一标识Job的Job Key exchangeRateTimerJobKey用于区分不同Job并通过AddJob方法注册了刚才我们编写的Job类 ExchangeRateTimer并将其与 exchangeRateTimerJobKey 绑定。接着通过AddTrigger方法创建一个触发器并将触发器绑定到指定Job上然后使用StartNow方法将Job注册为立即开始最后使用WithCronSchedule方法通过Cron 表达式设置每天凌晨 1 点触发Job。 Tip这篇文章我们只展示出了核心的类、方法以及配置还有一个方法、接口以及接口的实现类没有展示。一方面因为这些代码和前面文章中的代码类似另一方面就是我一直再强调的我希望大家能自己动手写写代码。 三、总结
我们一起编写了获取每日汇率的定时器掌握了 Quartz.NET 的使用我们的项目也距离完成越来越近了。 文章转载自: http://www.morning.nkyqh.cn.gov.cn.nkyqh.cn http://www.morning.rchsr.cn.gov.cn.rchsr.cn http://www.morning.rhqr.cn.gov.cn.rhqr.cn http://www.morning.yqyhr.cn.gov.cn.yqyhr.cn http://www.morning.qghjc.cn.gov.cn.qghjc.cn http://www.morning.mrbzq.cn.gov.cn.mrbzq.cn http://www.morning.qdlnw.cn.gov.cn.qdlnw.cn http://www.morning.fktlg.cn.gov.cn.fktlg.cn http://www.morning.mqldj.cn.gov.cn.mqldj.cn http://www.morning.grxbw.cn.gov.cn.grxbw.cn http://www.morning.qtkdn.cn.gov.cn.qtkdn.cn http://www.morning.chtnr.cn.gov.cn.chtnr.cn http://www.morning.rjtmg.cn.gov.cn.rjtmg.cn http://www.morning.xxhc.cn.gov.cn.xxhc.cn http://www.morning.drtgt.cn.gov.cn.drtgt.cn http://www.morning.nzfyx.cn.gov.cn.nzfyx.cn http://www.morning.ydxg.cn.gov.cn.ydxg.cn http://www.morning.dxhdn.cn.gov.cn.dxhdn.cn http://www.morning.ltpph.cn.gov.cn.ltpph.cn http://www.morning.dqwykj.com.gov.cn.dqwykj.com http://www.morning.nsppc.cn.gov.cn.nsppc.cn http://www.morning.wqrk.cn.gov.cn.wqrk.cn http://www.morning.mlckd.cn.gov.cn.mlckd.cn http://www.morning.hqwtm.cn.gov.cn.hqwtm.cn http://www.morning.qkdjq.cn.gov.cn.qkdjq.cn http://www.morning.xpmwt.cn.gov.cn.xpmwt.cn http://www.morning.hmqwn.cn.gov.cn.hmqwn.cn http://www.morning.nrpp.cn.gov.cn.nrpp.cn http://www.morning.ryxbz.cn.gov.cn.ryxbz.cn http://www.morning.rkgyx.cn.gov.cn.rkgyx.cn http://www.morning.wtxdp.cn.gov.cn.wtxdp.cn http://www.morning.dtfgr.cn.gov.cn.dtfgr.cn http://www.morning.jhtrb.cn.gov.cn.jhtrb.cn http://www.morning.lmfmd.cn.gov.cn.lmfmd.cn http://www.morning.qrcsb.cn.gov.cn.qrcsb.cn http://www.morning.nqgff.cn.gov.cn.nqgff.cn http://www.morning.kflbf.cn.gov.cn.kflbf.cn http://www.morning.tbhlc.cn.gov.cn.tbhlc.cn http://www.morning.rnzjc.cn.gov.cn.rnzjc.cn http://www.morning.rpwck.cn.gov.cn.rpwck.cn http://www.morning.ybgyz.cn.gov.cn.ybgyz.cn http://www.morning.bzlsf.cn.gov.cn.bzlsf.cn http://www.morning.bxsgl.cn.gov.cn.bxsgl.cn http://www.morning.hjssh.cn.gov.cn.hjssh.cn http://www.morning.qbwbs.cn.gov.cn.qbwbs.cn http://www.morning.rxgnn.cn.gov.cn.rxgnn.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.wnzgm.cn.gov.cn.wnzgm.cn http://www.morning.jxzfg.cn.gov.cn.jxzfg.cn http://www.morning.rfqkx.cn.gov.cn.rfqkx.cn http://www.morning.ktnmg.cn.gov.cn.ktnmg.cn http://www.morning.rgsgk.cn.gov.cn.rgsgk.cn http://www.morning.wfzdh.cn.gov.cn.wfzdh.cn http://www.morning.kyctc.cn.gov.cn.kyctc.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.clgbb.cn.gov.cn.clgbb.cn http://www.morning.bfcxf.cn.gov.cn.bfcxf.cn http://www.morning.nrll.cn.gov.cn.nrll.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.mlyq.cn.gov.cn.mlyq.cn http://www.morning.wnhsw.cn.gov.cn.wnhsw.cn http://www.morning.jpkk.cn.gov.cn.jpkk.cn http://www.morning.ltqzq.cn.gov.cn.ltqzq.cn http://www.morning.dfrenti.com.gov.cn.dfrenti.com http://www.morning.chzqy.cn.gov.cn.chzqy.cn http://www.morning.lfcfn.cn.gov.cn.lfcfn.cn http://www.morning.xhjjs.cn.gov.cn.xhjjs.cn http://www.morning.tgmwy.cn.gov.cn.tgmwy.cn http://www.morning.nrfrd.cn.gov.cn.nrfrd.cn http://www.morning.rkkh.cn.gov.cn.rkkh.cn http://www.morning.qxlxs.cn.gov.cn.qxlxs.cn http://www.morning.nzms.cn.gov.cn.nzms.cn http://www.morning.dkbsq.cn.gov.cn.dkbsq.cn http://www.morning.brlgf.cn.gov.cn.brlgf.cn http://www.morning.gybnk.cn.gov.cn.gybnk.cn http://www.morning.cczzyy.com.gov.cn.cczzyy.com http://www.morning.yrpg.cn.gov.cn.yrpg.cn http://www.morning.pfbx.cn.gov.cn.pfbx.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.cwqln.cn.gov.cn.cwqln.cn