添加缓存

This commit is contained in:
zpc 2024-10-11 21:36:58 +08:00
parent b58cc5f229
commit 32d30a2746
21 changed files with 819 additions and 14 deletions

View File

@ -0,0 +1,23 @@
using AutoMapper;
using CloudGaming.Code.DataAccess;
using Microsoft.AspNetCore.Mvc;
namespace CloudGaming.Api.Base
{
/// <summary>
/// 基础父类
/// </summary>
/// <param name="_serviceProvider"></param>
[ApiController]
[Route("api/[controller]/[action]")]
public class CloudGamingControllerBase(IServiceProvider _serviceProvider) : ControllerBase
{
/// <summary>
/// 数据库使用
/// </summary>
public IServiceProvider ServiceProvider { get; set; } = _serviceProvider;
}
}

View File

@ -20,9 +20,15 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,27 @@
using CloudGaming.Api.Base;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace CloudGaming.Api.Controllers
{
/// <summary>
///
/// </summary>
public class AppController : CloudGamingControllerBase
{
public AppController(IServiceProvider _serviceProvider) : base(_serviceProvider)
{
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<object> GetConfig()
{
return "a";
}
}
}

View File

@ -10,10 +10,29 @@ using HuanMeng.DotNetCore.SwaggerUtile;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
#region
// Add services to the container.
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext());
builder.Services.AddSingleton(typeof(ILogger<CloudGamingBase>), serviceProvider =>
{
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
return loggerFactory.CreateLogger<CloudGamingBase>();
});
//
builder.Services.AddSingleton(typeof(ILogger<ExceptionMiddleware>), serviceProvider =>
{
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
return loggerFactory.CreateLogger<ExceptionMiddleware>();
});
#endregion
#region
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
@ -27,8 +46,10 @@ builder.Services.AddControllers()
//options.SerializerSettings.Converters.Add()
// 其他配置...
});
#endregion
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
#region jwt
builder.Services.AddSwaggerGen(c =>
{
@ -66,6 +87,9 @@ builder.Services.AddSwaggerGen(c =>
c.ParameterFilter<LowercaseParameterFilter>();
c.RequestBodyFilter<LowercaseRequestFilter>();
});
#endregion
builder.AddAppConfigClient();
//添加jwt验证
builder.AddJwtConfig();
@ -83,7 +107,7 @@ var app = builder.Build();
//if (app.Environment.IsDevelopment())
//{
// app.UseSwagger();
// app.UseSwaggerUI();
// app.UseSwaggerUI();
//}
app.UseSwagger();
app.UseSwaggerUI(c =>

View File

@ -4,5 +4,13 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
//
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:8080"
}
}
}
}

View File

@ -1,9 +1,81 @@
{
"ConnectionStrings": {
"UserConnectionString": "Server=192.168.1.17;Database=CloudGamingUser;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;",
"GameConnectionString": "Server=192.168.1.17;Database=CloudGamingGame;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;",
"PhoneConnectionString": "Server=192.168.1.17;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;",
"ExtConnectionString": "Server=192.168.1.17;Database=CloudGamingCBT;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "../output/logs/info/log-.txt",
"rollingInterval": "Day",
"restrictedToMinimumLevel": "Information", //
"shared": true
//"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "../output/logs/error/log-.txt",
"rollingInterval": "Day", //
"restrictedToMinimumLevel": "Error", // // VerboseDebugInformationWarningError Fatal
"shared": true //
// "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "../output/logs/debug/log-.txt",
"rollingInterval": "Day", //
"restrictedToMinimumLevel": "Debug", // // VerboseDebugInformationWarningError Fatal
"shared": true //
// "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
},
"JwtTokenConfig": {
//
"secret": "XtrtwJIcxRHWInEMsCyUdwcRKLNHHAcQ1",
//
"issuer": "steamcloud.co",
//
"audience": "steamcloud.co",
//token,
"accessTokenExpiration": 10080,
//token.
"refreshTokenExpiration": 10100
},
//
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:80"
}
}
}
}

View File

@ -3,7 +3,6 @@ using CloudGaming.Code.DataAccess.MultiTenantUtil;
using System.Collections.Concurrent;
using System.Collections.Frozen;
using XLib.DotNetCore.CacheHelper;
namespace CloudGaming.Code.AppExtend
{
@ -36,7 +35,6 @@ namespace CloudGaming.Code.AppExtend
{
if (AppConfigs.TryGetValue(domainName, out var appConfig))
{
return appConfig;
}
if (AppConfigs.TryGetValue("default", out appConfig))

View File

@ -0,0 +1,174 @@
using AutoMapper;
using CloudGaming.Code.DataAccess;
using HuanMeng.DotNetCore.JwtInfrastructure.Interface;
using HuanMeng.DotNetCore.Redis;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
namespace CloudGaming.Code.AppExtend
{
/// <summary>
/// bll基础类
/// </summary>
public class CloudGamingBase : BLLBase<DAO>
{
public CloudGamingBase(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
#region
private DAO _dao;
/// <summary>
/// dao 数据库
/// </summary>
public override DAO Dao
{
get
{
if (_dao == null)
{
_dao = new DAO(_serviceProvider);
}
return _dao;
}
}
#endregion
#region
private IMapper _mapper;
/// <summary>
/// dto映射
/// </summary>
//[FromServices]
public virtual IMapper Mapper
{
get
{
if (_mapper == null)
{
_mapper = _serviceProvider.GetRequiredService<IMapper>();
}
return _mapper;
}
set { _mapper = value; }
}
#endregion
#region AppConfig
/// <summary>
///
/// </summary>
private AppConfig? appConfig;
/// <summary>
/// AppConfig 配置
/// </summary>
public AppConfig AppConfig
{
get
{
if (appConfig == null)
{
appConfig = _serviceProvider.GetService<AppConfig>();
}
return appConfig;
}
}
#endregion
#region
private IHttpContextAccessor _HttpContextAccessor;
/// <summary>
/// HttpContextAccessor
/// </summary>
public IHttpContextAccessor HttpContextAccessor
{
get
{
if (_HttpContextAccessor == null)
{
_HttpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
}
return _HttpContextAccessor;
}
}
#endregion
#region http请求
private IHttpClientFactory? _httpClientFactory;
/// <summary>
/// http请求
/// </summary>
public IHttpClientFactory HttpClientFactory
{
get
{
if (_httpClientFactory == null)
{
_httpClientFactory = _serviceProvider.GetRequiredService<IHttpClientFactory>();
}
return _httpClientFactory;
}
}
#endregion
#region JWT管理
private IJwtAuthManager _jwtAuthManager;
/// <summary>
/// jwt管理
/// </summary>
public IJwtAuthManager JwtAuthManager
{
get
{
if (_jwtAuthManager == null)
{
_jwtAuthManager = _serviceProvider.GetService<IJwtAuthManager>();
}
return _jwtAuthManager;
}
}
#endregion
#region
private ILogger<CloudGamingBase>? _logger;
public ILogger<CloudGamingBase> _Logger
{
get
{
if (_logger == null)
{
_logger = _serviceProvider.GetRequiredService<ILogger<CloudGamingBase>>();
}
return _logger;
}
}
#endregion
#region Redis
private IDatabase? _redis;
/// <summary>
/// 妙语实现类
/// </summary>
public IDatabase RedisCache
{
get
{
if (_redis == null)
{
_redis = RedisConnection.GetRedis(AppConfig.RedisConnectionString);
}
return _redis;
}
}
#endregion
}
}

View File

@ -0,0 +1,31 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Cache
{
/// <summary>
///
/// </summary>
public class CacheBaseConfig
{
/// <summary>
///
/// </summary>
public AppConfig AppConfig { get; set; }
/// <summary>
///
/// </summary>
public IMapper Mapper { get; set; }
/// <summary>
/// 数据库
/// </summary>
public DbContext DbContext { get; set; }
}
}

View File

@ -0,0 +1,146 @@
using HuanMeng.DotNetCore.CacheHelper;
using System.Collections.Concurrent;
using System.Linq.Expressions;
namespace CloudGaming.Code.Cache
{
/// <summary>
/// 缓存数据表
/// </summary>
/// <param name="gamingBase"></param>
public class CloudGamingCache(CloudGamingBase gamingBase)
{
#region
/// <summary>
/// 图片缓存表
/// </summary>
public CommonDataEntityCache<T_Image_Config>? ImageConfigCache { get; set; }
/// <summary>
/// 图片
/// </summary>
public List<T_Image_Config> ImageConfigList
{
get
{
if (ImageConfigCache == null)
{
ImageConfigCache = CloudGamingCacheExtend.GetDataEntityCache<T_Image_Config>(gamingBase);
}
return ImageConfigCache.DataList ?? new List<T_Image_Config>();
}
}
#endregion
#region
/// <summary>
/// 配置缓存表
/// </summary>
public CommonDataEntityCache<T_App_Config>? AppConfigCache { get; set; }
/// <summary>
/// 配置
/// </summary>
public List<T_App_Config> AppConfigList
{
get
{
if (AppConfigCache == null)
{
AppConfigCache = CloudGamingCacheExtend.GetDataEntityCache<T_App_Config>(gamingBase);
}
return AppConfigCache.DataList ?? new List<T_App_Config>();
}
}
#endregion
}
/// <summary>
/// 游戏
/// </summary>
public static class CloudGamingCacheExtend
{
/// <summary>
/// 缓存锁字典
/// </summary>
private static readonly ConcurrentDictionary<Type, object> ExtCacheLockList = new ConcurrentDictionary<Type, object>();
private static readonly ConcurrentDictionary<Type, object> GameCacheLockList = new ConcurrentDictionary<Type, object>();
private static readonly ConcurrentDictionary<Type, object> AppCacheLockList = new ConcurrentDictionary<Type, object>();
private static readonly ConcurrentDictionary<Type, object> UserCacheLockList = new ConcurrentDictionary<Type, object>();
/// <summary>
/// 命名空间与缓存映射
/// </summary>
private static readonly Dictionary<string, (ConcurrentDictionary<Type, object> cacheList, AppDataBaseType dbType)> NamespaceMapping;
static CloudGamingCacheExtend()
{
NamespaceMapping = new Dictionary<string, (ConcurrentDictionary<Type, object> cacheList, AppDataBaseType dbType)>
{
{ "CloudGaming.GameModel.Db.Db_Ext", (ExtCacheLockList, AppDataBaseType.Ext) },
{ "CloudGaming.GameModel.Db.Db_Game", (GameCacheLockList, AppDataBaseType.Game) },
{ "CloudGaming.Model.DbSqlServer.Db_Phone", (AppCacheLockList, AppDataBaseType.App) },
{ "CloudGaming.Model.DbSqlServer.Db_User", (UserCacheLockList, AppDataBaseType.User) }
};
}
/// <summary>
/// 获取实体缓存
/// </summary>
public static CommonDataEntityCache<T> GetDataEntityCache<T>(CloudGamingBase cloudGamingBase, Expression<Func<T, bool>>? expWhere = null) where T : class
{
var typeLock = typeof(T);
var namespaceKey = typeLock.Namespace;
if (namespaceKey == null || !NamespaceMapping.ContainsKey(namespaceKey))
{
throw new Exception($"缓存数据不存在或命名空间不匹配:{namespaceKey}");
}
var (cacheList, dbType) = NamespaceMapping[namespaceKey];
object cacheLock = GetOrAddCacheLock(typeLock, cacheList);
CacheBaseConfig cacheBaseConfig = cloudGamingBase.ToCacheBaseConfig(dbType);
return new DataBaseEntityCache<T>(cacheBaseConfig, cacheLock, expWhere: expWhere);
}
/// <summary>
/// 获取或添加缓存锁对象
/// </summary>
private static object GetOrAddCacheLock(Type typeLock, ConcurrentDictionary<Type, object> cacheList)
{
return cacheList.GetOrAdd(typeLock, _ =>
{
Log("没有找到锁对象==>" + typeLock.Name);
return new object();
});
}
/// <summary>
/// 根据数据库类型生成缓存配置
/// </summary>
public static CacheBaseConfig ToCacheBaseConfig(this CloudGamingBase cloudGamingBase, AppDataBaseType appDataBaseType)
{
return appDataBaseType switch
{
AppDataBaseType.App => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoPhone.Context },
AppDataBaseType.User => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoUser.Context },
AppDataBaseType.Ext => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoExt.Context },
AppDataBaseType.Game => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoGame.Context },
_ => throw new Exception("未找到对应的数据连接")
};
}
/// <summary>
/// 日志方法
/// </summary>
private static void Log(string message)
{
// 这里可以替换为更好的日志记录系统,例如 NLog, Serilog 等
Console.WriteLine(message);
}
}
}

View File

@ -0,0 +1,54 @@
using HuanMeng.DotNetCore.CacheHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Cache
{
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="baseConfig"></param>
/// <param name="lockObj"></param>
/// <param name="cacheTime"></param>
/// <param name="expWhere"></param>
public class DataBaseEntityCache<T>(CacheBaseConfig baseConfig, object lockObj, int cacheTime = 36000, Expression<Func<T, bool>> expWhere = null)
: CommonDataEntityCache<T>(lockObj, cacheTime) where T : class
{
/// <summary>
/// 缓存的key
/// </summary>
public override string key
{
get
{
return $"Cache:{baseConfig.AppConfig.Identifier}:CloudGaming:{typeof(T).Name}";
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override List<T> GetDataList()
{
var dbSet = baseConfig.DbContext.Set<T>().AsNoTracking();
if (dbSet == null)
{
return new List<T>();
}
if (expWhere != null)
{
dbSet = dbSet.Where(expWhere);
}
return dbSet.ToList();
}
}
}

View File

@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
</ItemGroup>

View File

@ -40,8 +40,8 @@ namespace CloudGaming.Code.DataAccess
public DAO(IServiceProvider serviceProvider, AppConfig appConfig) : base(serviceProvider)
{
this._tenantInfo = appConfig.ToITenantInfo();
}
#region
private EfCoreDaoBase<CloudGamingCBTContext>? _daoExt;
/// <summary>
@ -62,6 +62,7 @@ namespace CloudGaming.Code.DataAccess
}
}
#endregion
#region
private EfCoreDaoBase<CloudGamingGameContext>? _daoGame;
/// <summary>

View File

@ -47,19 +47,19 @@ public partial class CloudGamingCBTContext : DbContext
/// <summary>
/// App配置
/// </summary>
public virtual DbSet<T_Config> T_Config { get; set; }
public virtual DbSet<T_App_Config> T_App_Config { get; set; }
/// <summary>
/// 图片列表
/// </summary>
public virtual DbSet<T_Images> T_Images { get; set; }
public virtual DbSet<T_Image_Config> T_Image_Config { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Server=192.168.1.17;Database=CloudGamingCBT;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<T_Config>(entity =>
modelBuilder.Entity<T_App_Config>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK_T_APP_CONFIG");
@ -94,7 +94,7 @@ public partial class CloudGamingCBTContext : DbContext
});
modelBuilder.Entity<T_Images>(entity =>
modelBuilder.Entity<T_Image_Config>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK_T_VL_UI_IMAGES");

View File

@ -0,0 +1,47 @@
using System;
namespace CloudGaming.GameModel.Db.Db_Ext;
/// <summary>
/// App配置
/// </summary>
public partial class T_App_Config
{
public T_App_Config() { }
public virtual int Id { get; set; }
public virtual int? ConfigType { get; set; }
public virtual int? ConfigId { get; set; }
public virtual bool? IsShow { get; set; }
public virtual string? ShowName { get; set; }
public virtual string? Desc { get; set; }
public virtual DateTime? UpdateTime { get; set; }
public virtual DateTime? CreatTime { get; set; }
public virtual int? ConfigNum { get; set; }
public virtual int? ConfigNum2 { get; set; }
public virtual string? ConfigStr { get; set; }
public virtual string? BossId { get; set; }
public virtual string? Plat { get; set; }
/// <summary>
/// 州 例:亚洲
/// </summary>
public virtual string? Continent { get; set; }
/// <summary>
/// 国家 例:中国
/// </summary>
public virtual string? CountryName { get; set; }
}

View File

@ -5,9 +5,9 @@ namespace CloudGaming.GameModel.Db.Db_Ext;
/// <summary>
/// 图片列表
/// </summary>
public partial class T_Images
public partial class T_Image_Config
{
public T_Images() { }
public T_Image_Config() { }
public virtual int Id { get; set; }

View File

@ -0,0 +1,98 @@
using HuanMeng.DotNetCore.CacheHelper.Contract;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.DotNetCore.CacheHelper
{
/// <summary>
/// 缓存扩展-
/// </summary>
public abstract class CommonDataEntityCache<T> : ICacheClearData, ICacheReloadData where T : class
{
/// <summary>
///
/// </summary>
protected object lockObj;
/// <summary>
/// 过期时间
/// </summary>
protected int cacheTime;
protected CommonDataEntityCache(object lockObj, int cacheTime = 36000)
{
this.lockObj = lockObj;
this.cacheTime = cacheTime;
}
/// <summary>
///
/// </summary>
public abstract string key { get; }
/// <summary>
/// 缓存数据
/// </summary>
protected List<T>? _dataList;
/// <summary>
/// 数据
/// </summary>
public virtual List<T> DataList
{
get
{
if (_dataList == null)
{
var tempDataList = MemoryCacheHelper.GetCache<List<T>>(key);
if (tempDataList == null)
{
lock (lockObj)
{
tempDataList = MemoryCacheHelper.GetCache<List<T>>(key);
if (tempDataList == null)
{
tempDataList = GetDataList();
MemoryCacheHelper.SetCache(key, tempDataList, cacheTime);
}
}
}
_dataList = JsonConvert.DeserializeObject<List<T>>(JsonConvert.SerializeObject(tempDataList));
}
return _dataList ?? new List<T>();
}
}
/// <summary>
/// 获取缓存数据
/// </summary>
public abstract List<T> GetDataList();
public bool ClearData()
{
lock (lockObj)
{
MemoryCacheHelper.DelCache(key);
_dataList = null;
}
return true;
}
public void ReloadData()
{
lock (lockObj)
{
var tempDataList = GetDataList();
MemoryCacheHelper.SetCache(key, tempDataList, cacheTime);
_dataList = tempDataList;
}
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.DotNetCore.CacheHelper.Contract
{
/// <summary>
/// 清除缓存
/// </summary>
public interface ICacheClearData
{
/// <summary>
/// 清除数据
/// </summary>
/// <returns></returns>
bool ClearData();
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.DotNetCore.CacheHelper.Contract
{
/// <summary>
/// 重新加载数据
/// </summary>
public interface ICacheReloadData
{
/// <summary>
/// 重新加载数据
/// </summary>
void ReloadData();
}
}

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XLib.DotNetCore.CacheHelper
namespace HuanMeng.DotNetCore.CacheHelper
{
/// <summary>
/// 内存缓存帮助类

View File

@ -0,0 +1,56 @@
using Microsoft.Identity.Client;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IDatabase = StackExchange.Redis.IDatabase;
namespace HuanMeng.DotNetCore.Redis
{
/// <summary>
/// 数据库连接字符串
/// </summary>
public static class RedisConnection
{
/// <summary>
/// 数据库连接
/// </summary>
public static ConcurrentDictionary<string, IDatabase> Redis { get; set; } = new ConcurrentDictionary<string, IDatabase>();
/// <summary>
///
/// </summary>
/// <param name="redisConnection"></param>
/// <returns></returns>
public static IDatabase GetRedis(string redisConnection)
{
if (!Redis.TryGetValue(redisConnection, out var database))
{
var redis = ConnectionMultiplexer.Connect(redisConnection);
database = redis.GetDatabase();
Redis.TryAdd(redisConnection, database);
}
return database;
}
/// <summary>
///
/// </summary>
/// <param name="database"></param>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="time"></param>
/// <returns></returns>
public static bool StringSetLock(this IDatabase database, string key, string value, int time = 10)
{
return database.StringSet(key, value, TimeSpan.FromSeconds(time), when: When.NotExists);
}
}
}