2017875139
3 years ago
44 changed files with 375 additions and 286 deletions
@ -0,0 +1,4 @@ |
|||||
|
[*.cs] |
||||
|
|
||||
|
# CA1848: 使用 LoggerMessage 委托 |
||||
|
dotnet_diagnostic.CA1848.severity = none |
@ -0,0 +1,38 @@ |
|||||
|
namespace Easy.Wapper; |
||||
|
|
||||
|
public record PagingRequest |
||||
|
{ |
||||
|
private int _pageIndex; |
||||
|
private int _pageSize; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 当前第几页
|
||||
|
/// </summary>
|
||||
|
public int PageIndex |
||||
|
{ |
||||
|
get => _pageIndex; |
||||
|
set |
||||
|
{ |
||||
|
if (value <= 0) value = 1; |
||||
|
_pageIndex = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 页面数量
|
||||
|
/// </summary>
|
||||
|
public int PageSize |
||||
|
{ |
||||
|
get => _pageSize; |
||||
|
set |
||||
|
{ |
||||
|
if (value <= 9) value = 10; |
||||
|
_pageSize = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 默认是降序
|
||||
|
/// </summary>
|
||||
|
public bool OrderByDescending { get; set; } = true; |
||||
|
} |
@ -1,4 +1,4 @@ |
|||||
namespace Easy.DDD.Realization; |
namespace Easy.Realization; |
||||
|
|
||||
public class ApiMapAuto |
public class ApiMapAuto |
||||
{ |
{ |
@ -0,0 +1,10 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<!--<Nullable>enable</Nullable>--> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
</Project> |
@ -1,6 +1,6 @@ |
|||||
using System.Diagnostics.CodeAnalysis; |
using System.Diagnostics.CodeAnalysis; |
||||
|
|
||||
namespace Easy.Result; |
namespace Easy; |
||||
|
|
||||
public static class Check |
public static class Check |
||||
{ |
{ |
@ -1,15 +1,15 @@ |
|||||
namespace Easy.Result.Exceptions; |
namespace Easy.Exceptions; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 服务异常
|
/// 服务异常
|
||||
/// </summary>
|
/// </summary>
|
||||
internal class SvcException : Exception |
public class BusinessException : Exception |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// 服务异常
|
/// 服务异常
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="message">消息</param>
|
/// <param name="message">消息</param>
|
||||
public SvcException(string message) |
public BusinessException(string message) |
||||
: base(message) |
: base(message) |
||||
{ |
{ |
||||
|
|
@ -1,4 +1,6 @@ |
|||||
namespace Easy.DI.Realization; |
using Easy.DI; |
||||
|
|
||||
|
namespace Easy.Realization; |
||||
|
|
||||
public class LazyServiceProvider : ILazyServiceProvider, ITransientDependency |
public class LazyServiceProvider : ILazyServiceProvider, ITransientDependency |
||||
{ |
{ |
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<!--<Nullable>enable</Nullable>--> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" Version="6.0.0" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="FluentValidation" Version="10.3.6" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Easy.Core\Easy.Core.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,17 @@ |
|||||
|
using Easy.Aop; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace Easy.Extensions; |
||||
|
public static class ServiceCollectionServiceExtensions |
||||
|
{ |
||||
|
public static IServiceCollection AddUow(this IServiceCollection services) |
||||
|
{ |
||||
|
services.Configure<MvcOptions>(options => |
||||
|
{ |
||||
|
options.Filters.Add<FluentValidationRegister>(); |
||||
|
}); |
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<!--<Nullable>enable</Nullable>--> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Easy.DI\Easy.DI.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
|
||||
|
</Project> |
@ -0,0 +1,19 @@ |
|||||
|
namespace Easy.Enums; |
||||
|
|
||||
|
public enum SequentialGuidType |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// MySql and PostgreSql.
|
||||
|
/// </summary>
|
||||
|
SequentialAsString, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Oracle.
|
||||
|
/// </summary>
|
||||
|
SequentialAsBinary, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SqlServer.
|
||||
|
/// </summary>
|
||||
|
SequentialAtEnd |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
namespace Easy.Guids; |
||||
|
|
||||
|
public interface IGuidGenerator |
||||
|
{ |
||||
|
Guid Create(); |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
using Easy.Enums; |
||||
|
|
||||
|
namespace Easy.Options; |
||||
|
|
||||
|
public class SequentialGuidGeneratorOptions |
||||
|
{ |
||||
|
public SequentialGuidType? SequentialGuidType { get; set; } |
||||
|
|
||||
|
public SequentialGuidType GetSequentialGuidType() |
||||
|
{ |
||||
|
if (SequentialGuidType == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(SequentialGuidType), |
||||
|
"not Configure<SequentialGuidGeneratorOptions>(options =>{ options.SequentialGuidType = ???; })"); |
||||
|
} |
||||
|
return SequentialGuidType.Value; |
||||
|
} |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
using Easy.DI; |
||||
|
using Easy.Enums; |
||||
|
using Easy.Guids; |
||||
|
using Easy.Options; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System.Security.Cryptography; |
||||
|
|
||||
|
namespace Easy.Realization; |
||||
|
|
||||
|
public class SequentialGuidGenerator : IGuidGenerator, ITransientDependency |
||||
|
{ |
||||
|
public SequentialGuidGeneratorOptions Options { get; } |
||||
|
|
||||
|
private static readonly RandomNumberGenerator RandomNumberGenerator = RandomNumberGenerator.Create(); |
||||
|
|
||||
|
public SequentialGuidGenerator(IOptions<SequentialGuidGeneratorOptions> options) |
||||
|
{ |
||||
|
Options = options.Value; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Guid Create() |
||||
|
{ |
||||
|
SequentialGuidType guidType = Options.GetSequentialGuidType(); |
||||
|
|
||||
|
var randomBytes = new byte[10]; |
||||
|
RandomNumberGenerator.GetBytes(randomBytes); |
||||
|
|
||||
|
long timestamp = DateTime.UtcNow.Ticks / 10000L; |
||||
|
|
||||
|
byte[] timestampBytes = BitConverter.GetBytes(timestamp); |
||||
|
|
||||
|
|
||||
|
if (BitConverter.IsLittleEndian) |
||||
|
{ |
||||
|
Array.Reverse(timestampBytes); |
||||
|
} |
||||
|
|
||||
|
byte[] guidBytes = new byte[16]; |
||||
|
|
||||
|
switch (guidType) |
||||
|
{ |
||||
|
case SequentialGuidType.SequentialAsString: |
||||
|
|
||||
|
case SequentialGuidType.SequentialAsBinary: |
||||
|
|
||||
|
Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6); |
||||
|
Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10); |
||||
|
|
||||
|
if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian) |
||||
|
{ |
||||
|
Array.Reverse(guidBytes, 0, 4); |
||||
|
Array.Reverse(guidBytes, 4, 2); |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
|
||||
|
case SequentialGuidType.SequentialAtEnd: |
||||
|
|
||||
|
Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10); |
||||
|
Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6); |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return new Guid(guidBytes); |
||||
|
} |
||||
|
} |
@ -1,24 +0,0 @@ |
|||||
using AutoMapper; |
|
||||
using Microsoft.Extensions.DependencyModel; |
|
||||
using System.Reflection; |
|
||||
using System.Runtime.Loader; |
|
||||
|
|
||||
namespace Easy.Result.Common; |
|
||||
|
|
||||
public class AutoMapReadonly |
|
||||
{ |
|
||||
private static IEnumerable<Assembly> Assemblies = DependencyContext.Default.CompileLibraries. |
|
||||
Where(lib => !lib.Serviceable && lib.Type != "package" && lib.Type != "referenceassembly"). |
|
||||
Select(lib => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name))); |
|
||||
|
|
||||
public readonly static IConfigurationProvider ConfigurationProvider = new MapperConfiguration(cfg => |
|
||||
{ |
|
||||
foreach (var assembly in Assemblies) |
|
||||
{ |
|
||||
foreach (var profileType in assembly.GetTypes().Where(o => typeof(Profile).IsAssignableFrom(o))) |
|
||||
{ |
|
||||
cfg.AddProfile(profileType); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
|
@ -0,0 +1,56 @@ |
|||||
|
using Easy.Exceptions; |
||||
|
using Easy.Result; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
|
||||
|
namespace Easy.Aop; |
||||
|
|
||||
|
public class ApiResultProxy : IAsyncActionFilter |
||||
|
{ |
||||
|
private readonly ILoggerFactory LoggerFactory; |
||||
|
public ApiResultProxy(ILoggerFactory loggerFactory) |
||||
|
{ |
||||
|
LoggerFactory = loggerFactory; |
||||
|
} |
||||
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
||||
|
{ |
||||
|
var response = context.HttpContext.Response; |
||||
|
var logger = LoggerFactory.CreateLogger(context.Controller.GetType().Name); |
||||
|
try |
||||
|
{ |
||||
|
await next(); |
||||
|
} |
||||
|
catch (BusinessException ex) |
||||
|
{ |
||||
|
await response.WriteAsJsonAsync(new ApiResult() |
||||
|
{ |
||||
|
Message = ex.Message, |
||||
|
Status = "RETRY", |
||||
|
}); |
||||
|
} |
||||
|
catch (ArgumentNullException ex) |
||||
|
{ |
||||
|
const string message = $"参数不能为空"; |
||||
|
logger.LogError(ex, message); |
||||
|
|
||||
|
await response.WriteAsJsonAsync(new ApiResult() |
||||
|
{ |
||||
|
Message = message, |
||||
|
Status = "RETRY", |
||||
|
}); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
const string message = $"出错了,请稍后再试。"; |
||||
|
logger.LogError(ex, message); |
||||
|
|
||||
|
await response.WriteAsJsonAsync(new ApiResult() |
||||
|
{ |
||||
|
Message = message, |
||||
|
Status = "RETRY", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -1,60 +0,0 @@ |
|||||
using Easy.Result.Exceptions; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Microsoft.AspNetCore.Mvc.Filters; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
|
|
||||
namespace Easy.Result.Middlewares; |
|
||||
|
|
||||
public class ErrApiResultMiddleware |
|
||||
{ |
|
||||
private readonly RequestDelegate _next; |
|
||||
|
|
||||
public ErrApiResultMiddleware(RequestDelegate next) |
|
||||
{ |
|
||||
_next = next; |
|
||||
} |
|
||||
public async Task InvokeAsync(HttpContext context, ILoggerFactory loggerFactory) |
|
||||
{ |
|
||||
if (context.Request.Path.Value.StartsWith("/api")) |
|
||||
{ |
|
||||
var logger = loggerFactory.CreateLogger(nameof(ErrApiResultMiddleware)); |
|
||||
try |
|
||||
{ |
|
||||
await _next(context); |
|
||||
} |
|
||||
catch (SvcException ex) |
|
||||
{ |
|
||||
await context.Response.WriteAsJsonAsync(new ApiResult() |
|
||||
{ |
|
||||
Message = ex.Message, |
|
||||
Status = "RETRY", |
|
||||
}); |
|
||||
} |
|
||||
catch (ArgumentNullException ex) |
|
||||
{ |
|
||||
string message = $"ParamName:{ex.ParamName} is not null!message:{ex.Message}"; |
|
||||
await context.Response.WriteAsJsonAsync(new ApiResult() |
|
||||
{ |
|
||||
Message = message, |
|
||||
Status = "RETRY", |
|
||||
}); |
|
||||
logger.LogError(new EventId(ex.HResult), ex, message); |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
string message = $"ErrMessage = {ex.Message}"; |
|
||||
logger.LogError(new EventId(ex.HResult), ex, message); |
|
||||
await context.Response.WriteAsJsonAsync(new ApiResult() |
|
||||
{ |
|
||||
Message = "出错了,请稍后再试。", |
|
||||
Status = "RETRY", |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
await _next(context); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
@ -1,4 +1,4 @@ |
|||||
namespace Easy.Result; |
namespace Easy.Consts; |
||||
|
|
||||
public class ApiResultConsts |
public class ApiResultConsts |
||||
{ |
{ |
@ -1,22 +0,0 @@ |
|||||
using Easy.Result.FluentValidation; |
|
||||
using Easy.Result.Middlewares; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
|
|
||||
namespace Easy.Result.Extensions; |
|
||||
|
|
||||
public static class ApplicationBuilderExtensions |
|
||||
{ |
|
||||
public static IApplicationBuilder UseErrApiResult(this IApplicationBuilder builder) |
|
||||
{ |
|
||||
return builder.UseMiddleware<ErrApiResultMiddleware>(); |
|
||||
} |
|
||||
public static IMvcBuilder AddEasyFluentValidation(this IMvcBuilder builder) |
|
||||
{ |
|
||||
return builder.AddMvcOptions(options => |
|
||||
{ |
|
||||
options.Filters.Add<FluentValidationFilter>(); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
@ -0,0 +1,17 @@ |
|||||
|
using Easy.Aop; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace Easy.Extensions; |
||||
|
public static class ServiceCollectionServiceExtensions |
||||
|
{ |
||||
|
public static IServiceCollection AddApiResultProxy(this IServiceCollection services) |
||||
|
{ |
||||
|
services.Configure<MvcOptions>(options => |
||||
|
{ |
||||
|
options.Filters.Add<ApiResultProxy>(); |
||||
|
}); |
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
} |
@ -1,65 +0,0 @@ |
|||||
namespace Easy.Result; |
|
||||
|
|
||||
public interface IEntities |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 返回结果
|
|
||||
/// </summary>
|
|
||||
public object Data { get; set; } |
|
||||
|
|
||||
|
|
||||
public static IEntities Create<TSource>(List<TSource> Data) |
|
||||
{ |
|
||||
return new Entites() |
|
||||
{ |
|
||||
Data = Data ?? new() |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public sealed class Entites : IEntities |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 返回结果
|
|
||||
/// </summary>
|
|
||||
public object Data { get; set; } |
|
||||
} |
|
||||
|
|
||||
public interface IPaged : IEntities |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 页面数量
|
|
||||
/// </summary>
|
|
||||
public long PageCount { get; set; } |
|
||||
/// <summary>
|
|
||||
/// 页面大小
|
|
||||
/// </summary>
|
|
||||
public int PageSize { get; set; } |
|
||||
|
|
||||
public static IPaged Create<TSource>(long PageCount, int PageSize, List<TSource> Data) |
|
||||
{ |
|
||||
return new Paged() |
|
||||
{ |
|
||||
PageCount = PageCount, |
|
||||
Data = Data ?? new(), |
|
||||
PageSize = PageSize, |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
public sealed class Paged : IPaged |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 页面数量
|
|
||||
/// </summary>
|
|
||||
public long PageCount { get; set; } |
|
||||
/// <summary>
|
|
||||
/// 页面大小
|
|
||||
/// </summary>
|
|
||||
public int PageSize { get; set; } |
|
||||
/// <summary>
|
|
||||
/// 返回结果
|
|
||||
/// </summary>
|
|
||||
public object Data { get; set; } |
|
||||
} |
|
@ -1,7 +0,0 @@ |
|||||
namespace Easy.Result; |
|
||||
|
|
||||
public interface IEntity |
|
||||
{ |
|
||||
public long Id { get; set; } |
|
||||
|
|
||||
} |
|
@ -1,8 +0,0 @@ |
|||||
using AutoMapper; |
|
||||
using Easy.Result.Common; |
|
||||
namespace Easy.Result; |
|
||||
|
|
||||
public interface IModel |
|
||||
{ |
|
||||
|
|
||||
} |
|
Loading…
Reference in new issue