Merge branch 'sqlsugar' into sqlsugar-dev
This commit is contained in:
@@ -16,6 +16,7 @@ using Yi.Framework.Job;
|
||||
using Yi.Framework.Language;
|
||||
using Yi.Framework.Model.Models;
|
||||
using Yi.Framework.Repository;
|
||||
using Yi.Framework.Uow.Interceptors;
|
||||
using Yi.Framework.WebCore;
|
||||
using Yi.Framework.WebCore.AttributeExtend;
|
||||
using Yi.Framework.WebCore.AuthorizationPolicy;
|
||||
@@ -62,10 +63,10 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
||||
ThumbnailSharpInvoer thumbnailSharpInvoer,
|
||||
CacheInvoker cacheInvoker) =>
|
||||
|
||||
(_logger,_iUserService, _iRoleService, _quartzInvoker, _hub, _local, _thumbnailSharpInvoer, _cacheDb) =
|
||||
(_logger, _iUserService, _iRoleService, _quartzInvoker, _hub, _local, _thumbnailSharpInvoer, _cacheDb) =
|
||||
|
||||
(logger, iUserService, iRoleService, quartzInvoker, hub, local, thumbnailSharpInvoer, cacheInvoker);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// swagger跳转
|
||||
@@ -109,6 +110,15 @@ namespace Yi.Framework.ApiMicroservice.Controllers
|
||||
return Result.Success().SetData(await _iUserService.DbTest());
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<Result> TestUnitOfWork()
|
||||
{
|
||||
var userId = await _iUserService.AddInfo(new DTOModel.UserInfoDto { User = new UserEntity { Address = "", UserName = "lisi", Password = "123456" }.BuildPassword() });
|
||||
throw new ApplicationException("测试uow");
|
||||
await _iRoleService._repository.InsertReturnSnowflakeIdAsync(new RoleEntity { RoleName = "测试", RoleCode = "tt" });
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行Sql返回
|
||||
/// </summary>
|
||||
|
||||
@@ -18,6 +18,9 @@ using Yi.Framework.WebCore.LogExtend;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Yi.Framework.WebCore.AutoFacExtend;
|
||||
using AspectCore.Extensions.DependencyInjection;
|
||||
using AspectCore.Extensions.Hosting;
|
||||
using Yi.Framework.Uow.Interceptors;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Configuration.AddCommandLine(args);
|
||||
@@ -31,6 +34,9 @@ builder.Host.ConfigureAppConfiguration((hostBuilderContext, configurationBuilder
|
||||
#endregion
|
||||
configurationBuilder.AddApolloService("Yi");
|
||||
});
|
||||
|
||||
builder.Services.AddUnitOfWork();
|
||||
|
||||
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
|
||||
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
||||
{
|
||||
@@ -47,6 +53,7 @@ builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
||||
#endregion
|
||||
containerBuilder.AddAutoIocService("Yi.Framework.Repository", "Yi.Framework.Service");
|
||||
});
|
||||
|
||||
////<2F><><EFBFBD><EFBFBD>ע<EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mvcģ<63><C4A3>ת<EFBFBD>Ӹ<EFBFBD>ioc
|
||||
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
|
||||
|
||||
@@ -154,6 +161,7 @@ builder.Services.AddHttpContextAccessor();
|
||||
#endregion
|
||||
builder.Services.AddSingleton<ThumbnailSharpInvoer>();
|
||||
|
||||
|
||||
#region
|
||||
//ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʼ<EFBFBD><CABC>ֵ
|
||||
#endregion
|
||||
@@ -237,6 +245,5 @@ app.UseEndpoints(endpoints =>
|
||||
endpoints.MapHub<MainHub>("/api/hub/main");
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
|
||||
//<><D7BC><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6>⻧
|
||||
app.Run();
|
||||
@@ -21,6 +21,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspectCore.Extensions.Hosting" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Uow\Yi.Framework.Uow.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.WebCore\Yi.Framework.WebCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Binary file not shown.
@@ -23,7 +23,7 @@ namespace Yi.Framework.Model.Models
|
||||
/// <summary>
|
||||
/// 构建密码,MD5盐值加密
|
||||
/// </summary>
|
||||
public void BuildPassword(string password = null)
|
||||
public UserEntity BuildPassword(string password = null)
|
||||
{
|
||||
//如果不传值,那就把自己的password当作传进来的password
|
||||
if (password == null)
|
||||
@@ -32,6 +32,7 @@ namespace Yi.Framework.Model.Models
|
||||
}
|
||||
this.Salt = Common.Helper.MD5Helper.GenerateSalt();
|
||||
this.Password = Common.Helper.MD5Helper.SHA2Encode(password, this.Salt);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
13
Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs
Normal file
13
Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Data;
|
||||
|
||||
namespace Yi.Framework.Uow
|
||||
{
|
||||
public interface IUnitOfWork : IDisposable
|
||||
{
|
||||
public void Init(bool isTransactional, IsolationLevel? isolationLevel, int? timeout);
|
||||
public void BeginTran();
|
||||
|
||||
public void CommitTran();
|
||||
public void RollbackTran();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.Uow.Interceptors
|
||||
{
|
||||
public class UnitOfWorkAttribute : Attribute// : AbstractInterceptorAttribute
|
||||
{
|
||||
public UnitOfWorkAttribute(bool isTransactional = true)
|
||||
{
|
||||
IsTransactional = isTransactional;
|
||||
}
|
||||
public UnitOfWorkAttribute(IsolationLevel isolationLevel, bool isTransactional = true) : this(isTransactional)
|
||||
{
|
||||
IsolationLevel = isolationLevel;
|
||||
}
|
||||
public UnitOfWorkAttribute(IsolationLevel isolationLevel, int timeout, bool isTransactional = true) : this(isolationLevel, isTransactional)
|
||||
{
|
||||
Timeout = timeout;
|
||||
}
|
||||
|
||||
public bool IsTransactional { get; }
|
||||
|
||||
public IsolationLevel? IsolationLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds
|
||||
/// </summary>
|
||||
public int? Timeout { get; }
|
||||
public bool IsDisabled { get; }
|
||||
|
||||
|
||||
//public override Task Invoke(AspectContext context, AspectDelegate next)
|
||||
//{
|
||||
// if (IsTransactional)
|
||||
// {
|
||||
// ServiceLocator.in.getservice()
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Castle.DynamicProxy;
|
||||
using Nest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.Uow.Interceptors
|
||||
{
|
||||
public class UnitOfWorkInterceptor : IInterceptor
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
public UnitOfWorkInterceptor(IUnitOfWork unitOfWork)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
}
|
||||
|
||||
public void Intercept(IInvocation invocation)
|
||||
{
|
||||
if (!IsUnitOfWorkMethod(invocation.Method, out var uowAttr))
|
||||
{
|
||||
invocation.Proceed();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_unitOfWork.BeginTran();
|
||||
//执行被拦截的方法
|
||||
invocation.Proceed();
|
||||
_unitOfWork.CommitTran();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_unitOfWork.RollbackTran();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsUnitOfWorkMethod( MethodInfo methodInfo,out UnitOfWorkAttribute unitOfWorkAttribute)
|
||||
{
|
||||
|
||||
//Method declaration
|
||||
var attrs = methodInfo.GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
|
||||
if (attrs.Any())
|
||||
{
|
||||
unitOfWorkAttribute = attrs.First();
|
||||
return !unitOfWorkAttribute.IsDisabled;
|
||||
}
|
||||
|
||||
if (methodInfo.DeclaringType != null)
|
||||
{
|
||||
//Class declaration
|
||||
attrs = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
|
||||
if (attrs.Any())
|
||||
{
|
||||
unitOfWorkAttribute = attrs.First();
|
||||
return !unitOfWorkAttribute.IsDisabled;
|
||||
}
|
||||
|
||||
////Conventional classes
|
||||
//if (typeof(IUnitOfWorkEnabled).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType))
|
||||
//{
|
||||
// unitOfWorkAttribute = null;
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
|
||||
unitOfWorkAttribute = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Uow;
|
||||
using Yi.Framework.Uow.Interceptors;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class UowIServiceCollectionExtensions
|
||||
{
|
||||
public static void AddUnitOfWork(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork));
|
||||
|
||||
services.AddSingleton<UnitOfWorkInterceptor>();
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs
Normal file
75
Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Framework.Uow
|
||||
{
|
||||
public class UnitOfWork : IUnitOfWork
|
||||
{
|
||||
|
||||
public bool IsTransactional { get; protected set; }
|
||||
|
||||
public IsolationLevel? IsolationLevel { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds
|
||||
/// </summary>
|
||||
public int? Timeout { get; protected set; }
|
||||
|
||||
public void Init(bool isTransactional, IsolationLevel? isolationLevel, int? timeout)
|
||||
{
|
||||
IsTransactional = isTransactional;
|
||||
IsolationLevel = isolationLevel;
|
||||
Timeout = timeout;
|
||||
}
|
||||
|
||||
public ISqlSugarClient SugarClient { get; set; }
|
||||
/// <summary>
|
||||
/// 因为sqlsugarclient的生命周期是作用域的,也就是说一个请求线程内是共用一个client,暂时先直接注入
|
||||
/// </summary>
|
||||
/// <param name="sqlSugarClient"></param>
|
||||
public UnitOfWork(ISqlSugarClient sqlSugarClient)
|
||||
{
|
||||
this.SugarClient = sqlSugarClient;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SugarClient?.Dispose();
|
||||
SugarClient?.Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void BeginTran()
|
||||
{
|
||||
if (IsTransactional)
|
||||
{
|
||||
if (IsolationLevel.HasValue)
|
||||
{
|
||||
SugarClient.Ado.BeginTran(IsolationLevel.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
SugarClient.Ado.BeginTran();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CommitTran()
|
||||
{
|
||||
if (IsTransactional)
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
public void RollbackTran()
|
||||
{
|
||||
if (IsTransactional)
|
||||
SugarClient.Ado.RollbackTran();
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj
Normal file
17
Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Castle.Core" Version="5.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Repository\Yi.Framework.Repository.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -15,6 +15,7 @@ using Yi.Framework.Interface;
|
||||
using Yi.Framework.Job;
|
||||
using Yi.Framework.Repository;
|
||||
using Yi.Framework.Service;
|
||||
using Yi.Framework.Uow.Interceptors;
|
||||
using Yi.Framework.WebCore.AutoFacExtend;
|
||||
using Module = Autofac.Module;
|
||||
|
||||
@@ -48,7 +49,8 @@ namespace Yi.Framework.WebCore.AutoFacExtend
|
||||
containerBuilder.RegisterAssemblyTypes(assemblysServices)
|
||||
.AsImplementedInterfaces()
|
||||
.InstancePerLifetimeScope()
|
||||
.EnableInterfaceInterceptors();
|
||||
.EnableInterfaceInterceptors()
|
||||
.InterceptedBy(typeof(UnitOfWorkInterceptor));
|
||||
|
||||
///反射注册任务调度层
|
||||
var assemblysJob = GetDll("Yi.Framework.Job.dll");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
using Autofac;
|
||||
using Autofac.Extras.DynamicProxy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
@@ -9,6 +10,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Attribute;
|
||||
using Yi.Framework.Uow.Interceptors;
|
||||
|
||||
namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
{
|
||||
@@ -44,41 +46,41 @@ namespace Yi.Framework.WebCore.MiddlewareExtend
|
||||
case LifeTime.Singleton:
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
build.RegisterGeneric(type).As(serviceType).SingleInstance();
|
||||
build.RegisterGeneric(type).As(serviceType).SingleInstance().EnableInterfaceInterceptors();
|
||||
}
|
||||
else
|
||||
{
|
||||
build.RegisterType(type).As(serviceType).SingleInstance();
|
||||
build.RegisterType(type).As(serviceType).SingleInstance().EnableInterfaceInterceptors();
|
||||
}
|
||||
break;
|
||||
case LifeTime.Scoped:
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerLifetimeScope();
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerLifetimeScope().EnableInterfaceInterceptors();
|
||||
}
|
||||
else
|
||||
{
|
||||
build.RegisterType(type).As(serviceType).InstancePerLifetimeScope();
|
||||
build.RegisterType(type).As(serviceType).InstancePerLifetimeScope().EnableInterfaceInterceptors();
|
||||
}
|
||||
break;
|
||||
case LifeTime.Transient:
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerDependency();
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
|
||||
}
|
||||
else
|
||||
{
|
||||
build.RegisterType(type).As(serviceType).InstancePerDependency();
|
||||
build.RegisterType(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerDependency();
|
||||
build.RegisterGeneric(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
|
||||
}
|
||||
else
|
||||
{
|
||||
build.RegisterType(type).As(serviceType).InstancePerDependency();
|
||||
build.RegisterType(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.Service\Yi.Framework.Service.csproj" />
|
||||
<ProjectReference Include="..\Yi.Framework.Uow\Yi.Framework.Uow.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -47,7 +47,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.WeChatPay", "Y
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Template", "Yi.Framework.Template\Yi.Framework.Template.csproj", "{A51E9091-3745-461A-A3CB-32598BF0DC77}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.XUnitTest", "Yi.Framework.XUnitTest\Yi.Framework.XUnitTest.csproj", "{88E3298A-135D-4D9C-B98D-41A2C4268385}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.XUnitTest", "Yi.Framework.XUnitTest\Yi.Framework.XUnitTest.csproj", "{88E3298A-135D-4D9C-B98D-41A2C4268385}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Uow", "Yi.Framework.Uow\Yi.Framework.Uow.csproj", "{657E4EA0-5A34-4D09-A39C-419C31E740FE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -127,6 +129,10 @@ Global
|
||||
{88E3298A-135D-4D9C-B98D-41A2C4268385}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{88E3298A-135D-4D9C-B98D-41A2C4268385}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{88E3298A-135D-4D9C-B98D-41A2C4268385}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{657E4EA0-5A34-4D09-A39C-419C31E740FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{657E4EA0-5A34-4D09-A39C-419C31E740FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{657E4EA0-5A34-4D09-A39C-419C31E740FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{657E4EA0-5A34-4D09-A39C-419C31E740FE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -150,6 +156,7 @@ Global
|
||||
{C307189D-C42C-4C09-BB65-5A386C9F182B} = {9ABAF6B1-6C02-498A-90A2-ABC1140CF89A}
|
||||
{A51E9091-3745-461A-A3CB-32598BF0DC77} = {9ABAF6B1-6C02-498A-90A2-ABC1140CF89A}
|
||||
{88E3298A-135D-4D9C-B98D-41A2C4268385} = {C90E38FB-69EA-4997-8B3A-2C71EFA65B2B}
|
||||
{657E4EA0-5A34-4D09-A39C-419C31E740FE} = {DB2506F5-05FD-4E76-940E-41D7AA148550}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {1ED77A6E-377F-4EEF-A3D0-D65C94657DAF}
|
||||
|
||||
Reference in New Issue
Block a user