添加缓存
This commit is contained in:
parent
b58cc5f229
commit
32d30a2746
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -4,5 +4,13 @@
|
|||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
//服务器配置
|
||||
"Kestrel": {
|
||||
"Endpoints": {
|
||||
"Http": {
|
||||
"Url": "http://*:8080"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 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", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
146
src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs
Normal file
146
src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace XLib.DotNetCore.CacheHelper
|
||||
namespace HuanMeng.DotNetCore.CacheHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 内存缓存帮助类
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user