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 |
|||
{ |
@ -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; |
|||
|
|||
namespace Easy.Result; |
|||
namespace Easy; |
|||
|
|||
public static class Check |
|||
{ |
@ -1,15 +1,15 @@ |
|||
namespace Easy.Result.Exceptions; |
|||
namespace Easy.Exceptions; |
|||
|
|||
/// <summary>
|
|||
/// 服务异常
|
|||
/// </summary>
|
|||
internal class SvcException : Exception |
|||
public class BusinessException : Exception |
|||
{ |
|||
/// <summary>
|
|||
/// 服务异常
|
|||
/// </summary>
|
|||
/// <param name="message">消息</param>
|
|||
public SvcException(string message) |
|||
public BusinessException(string message) |
|||
: base(message) |
|||
{ |
|||
|
@ -1,4 +1,6 @@ |
|||
namespace Easy.DI.Realization; |
|||
using Easy.DI; |
|||
|
|||
namespace Easy.Realization; |
|||
|
|||
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 |
|||
{ |
@ -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