基于接口自定义代理V2做了升级,加入了防并发
封装端代码:
/// <summary>
/// 代理执行带权限验证
/// </summary>
/// <typeparam name="T">请求参数类型</typeparam>
/// <typeparam name="R">返回参数类型</typeparam>
/// <param name="func">执行都方法</param>
/// <param name="request">请求参数</param>
/// <param name="serviceName">服务名称</param>
/// <param name="concurrencyTime">并发控制秒数,不传默认不控制并发</param>
/// <returns></returns>
protected ResultMessage<R> ProxyExecuteWithAuth<T, R>(Func<T, ResultMessage<R>> func, T request, string serviceName = "", int concurrencyTime = 0)
where T : BaseRequest
{
var result = Activator.CreateInstance<ResultMessage<R>>();
var logStr = new StringBuilder();
try
{
logStr.AppendFormat("请求参数:{0}", JsonConvert.SerializeObject(request)); // 记录请求日志
//参数验证
request.LoginId = AuthService.Validate(request);
//方法执行
if (concurrencyTime > 0)
{
if (string.IsNullOrWhiteSpace(serviceName))//建议保留,不然可能导致缓存Key会重复,导致并发误控制
{
throw new Exception(CustomExceptionType.ServiceNameIsEmpty.GetEnumDesc());
}
result = ExeConcurrencyFuc(func, request, request.GetCheckConcurrencyValue(serviceName, concurrencyTime));
}
else
{
result = ProxyExecute(func, request);
}
}
catch (Exception ex)
{
result.ResultCode = ResultCodeEnum.Exception.GetHashCode();
result.ResultMsg = ex.Message;
logStr.AppendFormat("异常信息:{0}", ex.Message); // 记录异常日志
}
finally
{
//记录日志
//WriteLog(logStr.ToString();)
}
return result;
}
/// <summary>
/// 防并发执行
/// </summary>
/// <typeparam name="T">请求参数类型</typeparam>
/// <typeparam name="R">返回参数类型</typeparam>
/// <param name="func">执行都方法</param>
/// <param name="request">请求参数</param>
/// <param name="concurrencyModel">防并发实体</param>
/// <returns></returns>
protected ResultMessage<R> ExeConcurrencyFuc<T, R>(Func<T, ResultMessage<R>> func, T request, CheckConcurrencyModel concurrencyModel)
where T : BaseRequest
{
//防并发控制
string redisKey = string.Empty;
redisKey = $"{concurrencyModel.ServiceName}_{request.LoginId}_{concurrencyModel.ExtKey}";
//if (!RedisCache.RedisSetNx(redisKey, "Lock", concurrencyModel.LimitSecord)) todo 换成自己的缓存方法
//{
// throw new Exception(CustomExceptionType.RepeatRequest.GetEnumDesc());
//}
var result = ProxyExecute(func, request);
if (result != null && result.ResultCode != ResultCodeEnum.Sucess.GetHashCode())//如果处理失败,则进行释放缓存
{
//RedisCache.RedisDel(redisKey);todo 换成自己的缓存方法
}
return result;
}
调用端代码:
/// <summary>
/// 新增学生(防并发执行)
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public ResultMessage<int> AddStudent(AddStudentRequest request)
{
return ProxyExecuteWithAuth(StuService.AddStudent, request, $"{GetType().Name}_{MethodBase.GetCurrentMethod().Name}", 10);
}
项目源码:https://pan.baidu.com/s/1XKg-1svbgZ4fkIkNM8_rwg r6gh
当前代理封装其实已经可以应付大部分开发场景了,更多的期待自己开发......