ICacheService, SharpCache
This commit is contained in:
parent
7b05bbf4fa
commit
7b9572625c
|
|
@ -36,6 +36,7 @@
|
|||
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Rougamo.Fody" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
public interface ICacheKey
|
||||
{
|
||||
string GetCacheKey();
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
public interface ICacheService
|
||||
{
|
||||
Task<T?> GetAsync<T>(string key);
|
||||
Task<object> GetAsync(string key, Type type);
|
||||
Task SetAsync<T>(string key, T value, TimeSpan? expiry);
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using BotSharp.Abstraction.Infrastructures;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Rougamo;
|
||||
using Rougamo.Context;
|
||||
|
||||
namespace BotSharp.Core.Infrastructures;
|
||||
|
||||
public class SharpCacheAttribute : MoAttribute
|
||||
{
|
||||
public static IServiceProvider Services { get; set; } = null!;
|
||||
|
||||
private int _minutes;
|
||||
public SharpCacheAttribute(int minutes)
|
||||
{
|
||||
_minutes = minutes;
|
||||
}
|
||||
|
||||
public override void OnEntry(MethodContext context)
|
||||
{
|
||||
var cache = Services.GetRequiredService<ICacheService>();
|
||||
|
||||
var key = GetCacheKey(context);
|
||||
var value = cache.GetAsync(key, context.TaskReturnType).Result;
|
||||
if (value != null)
|
||||
{
|
||||
context.ReplaceReturnValue(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSuccess(MethodContext context)
|
||||
{
|
||||
var cache = Services.GetRequiredService<ICacheService>();
|
||||
|
||||
if (context.ReturnValue != null)
|
||||
{
|
||||
var key = GetCacheKey(context);
|
||||
cache.SetAsync(key, context.ReturnValue, new TimeSpan(0, _minutes, 0)).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCacheKey(MethodContext context)
|
||||
{
|
||||
// 根据用户级别生成缓存key
|
||||
var key = string.Empty;
|
||||
foreach (var arg in context.Arguments)
|
||||
{
|
||||
if (arg is null)
|
||||
{
|
||||
key += "-" + "<NULL>";
|
||||
}
|
||||
else if (arg is ICacheKey withCacheKey)
|
||||
{
|
||||
key += "-" + withCacheKey.GetCacheKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
key += "-" + arg.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
using BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
namespace BotSharp.Abstraction.Utilities;
|
||||
|
||||
public class Pagination
|
||||
public class Pagination : ICacheKey
|
||||
{
|
||||
private int _page;
|
||||
private int _size;
|
||||
|
|
@ -39,6 +41,9 @@ public class Pagination
|
|||
}
|
||||
|
||||
public bool ReturnTotal { get; set; } = true;
|
||||
|
||||
public string GetCacheKey()
|
||||
=> $"{_page}_{_size}_{Sort}_{Order}";
|
||||
}
|
||||
|
||||
public class PagedItems<T>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
using BotSharp.Abstraction.Functions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Core.Plugins;
|
||||
using BotSharp.Abstraction.Settings;
|
||||
using BotSharp.Abstraction.Options;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using BotSharp.Abstraction.Users.Settings;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
namespace BotSharp.Core;
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ public static class BotSharpCoreExtensions
|
|||
{
|
||||
services.AddScoped<ISettingService, SettingService>();
|
||||
services.AddScoped<IUserService, UserService>();
|
||||
services.AddSingleton<ICacheService, CacheService>();
|
||||
services.AddSingleton<DistributedLocker>();
|
||||
|
||||
RegisterPlugins(services, config);
|
||||
|
|
@ -54,6 +56,9 @@ public static class BotSharpCoreExtensions
|
|||
|
||||
app.ApplicationServices.GetRequiredService<PluginLoader>().Configure(app);
|
||||
|
||||
// Set root services for SharpCacheAttribute
|
||||
SharpCacheAttribute.Services = app.ApplicationServices;
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
using BotSharp.Abstraction.Infrastructures;
|
||||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace BotSharp.Core.Infrastructures;
|
||||
|
||||
public class CacheService : ICacheService
|
||||
{
|
||||
private readonly BotSharpDatabaseSettings _settings;
|
||||
private static ConnectionMultiplexer redis = null!;
|
||||
|
||||
public CacheService(BotSharpDatabaseSettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task<T?> GetAsync<T>(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_settings.Redis))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
if (redis == null)
|
||||
{
|
||||
redis = ConnectionMultiplexer.Connect(_settings.Redis);
|
||||
}
|
||||
|
||||
var db = redis.GetDatabase();
|
||||
var value = await db.StringGetAsync(key);
|
||||
|
||||
if (value.HasValue)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(value);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public async Task<object> GetAsync(string key, Type type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_settings.Redis))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
if (redis == null)
|
||||
{
|
||||
redis = ConnectionMultiplexer.Connect(_settings.Redis);
|
||||
}
|
||||
|
||||
var db = redis.GetDatabase();
|
||||
var value = await db.StringGetAsync(key);
|
||||
|
||||
if (value.HasValue)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(value, type);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
|
||||
public async Task SetAsync<T>(string key, T value, TimeSpan? expiry)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_settings.Redis))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var db = redis.GetDatabase();
|
||||
await db.StringSetAsync(key, JsonConvert.SerializeObject(value), expiry);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue