.Net Core控制台在微服务中实现后台任务
主要实现代码
该代码主要实现获取微信小程序的访问凭证,并保存到Sqlite数据库中。
主要使用了以下组件
Microsoft.CSharp //用于处理动态类型
NLog.Extensions.Logging //日志
Newtonsoft.Json //json序列号和反序列化,可以使用dynamic
Microsoft.Extensions.Hosting //重中之重,实现后台任务关键
Microsoft.Extensions.Http //实现HttpClient
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Tools
program.cs主要代码
namespace ConsoleAppWithDI
{
class Program
{
static Task Main(string[] args)=>
CreateHostBuilder(args).Build().RunAsync();
static IHostBuilder CreateHostBuilder(string[] arg) =>
Host.CreateDefaultBuilder(arg)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Information);
logging.AddNLog(new NLogProviderOptions
{
CaptureMessageProperties = true,
CaptureMessageTemplates = true
});
})
.ConfigureServices((hostContext,services)=> {
services.AddHostedService<ExampleHostedService>();
services.AddHttpClient();
services.AddDbContext<ExampleDbContext>(options => options.UseSqlite("Data Source=db/dataBase.db"));
});
}
}
继承BackgroundService类的ExampleHostedService :
namespace ConsoleAppWithDI
{
class ExampleHostedService : BackgroundService
{
private readonly ILogger _logger;
private readonly HttpClient _httpClient;
private readonly ExampleDbContext _context;
public ExampleHostedService(ILogger<ExampleHostedService> logger, HttpClient httpClient, IServiceScopeFactory scopeFactory )
{
//依赖注入获取实例
_logger = logger;
_httpClient = httpClient;
_context = scopeFactory.CreateScope().ServiceProvider.GetRequiredService<ExampleDbContext>();//控制台不能像asp.net那样很方便的获取_context;
}
protected override async Task<Task> ExecuteAsync(CancellationToken stoppingToken)
{
var token= _context.AppAccessTokens.OrderByDescending(x => x.Time).FirstOrDefault();
bool isExpired = true;
if(token!=null)
{
//比较时间
TimeSpan timeSpan1 = new TimeSpan(token.Time.Ticks);
TimeSpan timeSpan2 = new TimeSpan(DateTime.Now.Ticks);
TimeSpan timeSpan3 = timeSpan2 - timeSpan1;
if (timeSpan3.TotalSeconds < token.ExpiresIn-600)
{
isExpired = false;
}
}
if (isExpired)
{
DateTime now = DateTime.Now;
var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret";
var response = await _httpClient.GetAsync(url);
//获取请求到数据,并转化为字符串
var result = response.Content.ReadAsStringAsync().Result;
var newToken= JsonConvert.DeserializeObject<dynamic>(result);
if (newToken.access_token!=null)
{
if (token != null)//如果已存在则更新,否则添加
{
token.AccessToken = newToken.access_token;
token.ExpiresIn = newToken.expires_in;
token.Time = now;
_context.AppAccessTokens.Update(token);
}
else
{
_context.AppAccessTokens.Add(new AppAccessToken
{
AccessToken = newToken.access_token,
ExpiresIn = newToken.expires_in,
Time = now
});
}
_context.SaveChanges();
}
}
return Task.CompletedTask;
}
}
}
ExampleDbContext类
namespace ConsoleAppWithDI.Models
{
class ExampleDbContext: DbContext
{
public DbSet<AppAccessToken> AppAccessTokens { get; set; }
public ExampleDbContext(DbContextOptions<ExampleDbContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AppAccessToken>()
.Property(x => x.ExpiresIn)
.HasDefaultValue(7200);
modelBuilder.Entity<AppAccessToken>()
.Property(x => x.Time)
.HasDefaultValueSql("datetime('now', 'localtime')");//时间默认值 sqlServer 使用 GETDATE()
}
}
}