♻️ feat(新增): 代码生成器
This commit is contained in:
parent
18e6c9adbf
commit
9a1024f0f7
|
@ -2,7 +2,19 @@
|
|||
<project version="4">
|
||||
<component name="GitCommitMessageStorage">
|
||||
<option name="messageStorage">
|
||||
<MessageStorage />
|
||||
<MessageStorage>
|
||||
<option name="commitTemplate">
|
||||
<CommitTemplate>
|
||||
<option name="body" value="" />
|
||||
<option name="changes" value="" />
|
||||
<option name="closes" value="" />
|
||||
<option name="scope" value="" />
|
||||
<option name="skipCi" value="" />
|
||||
<option name="subject" value="" />
|
||||
<option name="type" value="feat" />
|
||||
</CommitTemplate>
|
||||
</option>
|
||||
</MessageStorage>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -1,4 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise">
|
||||
<file url="file://$PROJECT_DIR$/Bunny.Generate/ServerTemplate/Controller.cs" charset="GBK" />
|
||||
</component>
|
||||
</project>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,12 +1,23 @@
|
|||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\Project\\web\\Bunny-Cli\\template\\CSharp\\CSharp-Single-EFCore\\",
|
||||
"WorkspaceRootPath": "D:\\MyFolder\\Bunny\\Bunny-cli\\CSharp\\CSharp-Single-EFCore\\",
|
||||
"Documents": [],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
"VerticalTabListWidth": 256,
|
||||
"DocumentGroups": []
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": -1,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
namespace Bunny.Common.Attribute;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class TransactionAttribute : System.Attribute
|
||||
{
|
||||
}
|
|
@ -37,7 +37,7 @@ public class EfCoreContext : DbContext
|
|||
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||
{
|
||||
Log.Info("EfCoreContext 数据库连接...");
|
||||
options.UseSqlServer(DbPath).AddInterceptors(new TransactionInterceptor());
|
||||
options.UseSqlServer(DbPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
using Bunny.Common.Exception;
|
||||
using Bunny.Dao.Common.Constant;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
|
||||
namespace Bunny.Common.Context.Database;
|
||||
|
||||
public class TransactionInterceptor : SaveChangesInterceptor
|
||||
{
|
||||
// 重写 SavingChanges 方法
|
||||
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
|
||||
{
|
||||
// 如果当前上下文存在事务,则直接返回结果
|
||||
if (eventData.Context!.Database.CurrentTransaction != null) return result;
|
||||
|
||||
// 开始数据库事务
|
||||
using var transaction = eventData.Context.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
// 调用基类方法继续保存更改
|
||||
result = base.SavingChanges(eventData, result);
|
||||
|
||||
// 如果保存更改成功,则提交事务
|
||||
transaction.Commit();
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
// 如果保存更改失败,则回滚事务并抛出自定义异常
|
||||
transaction.Rollback();
|
||||
throw new BunnyException(ExceptionConstant.DataBaseError);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System.Transactions;
|
||||
using Bunny.Common.Attribute;
|
||||
using Bunny.Common.Context;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace Bunny.Common.Filter;
|
||||
|
||||
public class TransactionIAsyncActionFilter : IAsyncActionFilter
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(TransactionIAsyncActionFilter));
|
||||
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
var actionDesc = context.ActionDescriptor as ControllerActionDescriptor;
|
||||
var hasNotTransactionalAttribute =
|
||||
actionDesc?.MethodInfo.IsDefined(typeof(TransactionAttribute), false) ?? false;
|
||||
|
||||
if (hasNotTransactionalAttribute)
|
||||
{
|
||||
await next();
|
||||
return;
|
||||
}
|
||||
|
||||
using var txScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
|
||||
var result = await next();
|
||||
if (result.Exception == null)
|
||||
{
|
||||
txScope.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage =
|
||||
$"执行数据库出错 用户Id:[{BaseContext.GetUserId()}] token [{BaseContext.GetToken()}]:{result.Exception}";
|
||||
Log.Error(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Template\Controller.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>Controller.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Template\IService.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>IService.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Template\Service.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>Service.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="ServerTemplate\Controller.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>Controller.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="ServerTemplate\IService.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>IService.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="WebTemplate\"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bunny.WebApi\Bunny.WebApi.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<#
|
||||
const string author = "Bunny";
|
||||
const string controllerName = "控制器名称";
|
||||
const string serviceName = "服务名称";
|
||||
const string iServiceName = "实现服务名称";
|
||||
#>
|
|
@ -0,0 +1,26 @@
|
|||
using Bunny.Dao.Common.Constant.Result;
|
||||
using Bunny.Dao.Common.Result;
|
||||
using Lazy.Captcha.Core;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
<#@ include file="./BaseConstants.tt" #>
|
||||
|
||||
<#@ template hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" encoding="utf-8" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
|
||||
namespace Bunny.WebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 控制器
|
||||
/// By <#= author #>
|
||||
/// <#= DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") #>
|
||||
/// </summary>
|
||||
[Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
|
||||
public class <#= controllerName #>Controller : ControllerBase
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(CaptchaTestController));
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<#@ template hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" encoding="utf-8" #>
|
||||
<#@ include file="./BaseConstants.tt" #>
|
||||
|
||||
namespace Bunny.Service.IService;
|
||||
|
||||
public interface I<#= serviceName #>Service
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<#@ template hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" encoding="utf-8" #>
|
||||
<#@ include file="./BaseConstants.tt" #>
|
||||
|
||||
namespace Bunny.Service.IService.Service;
|
||||
|
||||
public class <#= serviceName #>Service : I<#= iServiceName #>Service
|
||||
{
|
||||
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
using Bunny.Common.Context.Database;
|
||||
using Bunny.Common.Attribute;
|
||||
using Bunny.Common.Context.Database;
|
||||
using Bunny.Common.Exception;
|
||||
using Bunny.Common.Utils.Net;
|
||||
using Bunny.Dao.Common.Result;
|
||||
using Bunny.Dao.Dto.System;
|
||||
|
@ -59,9 +61,9 @@ public class BlogService : IBlogService
|
|||
/// 批量添加数据
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
[Transaction]
|
||||
public void AddBatchBlogs(string url)
|
||||
{
|
||||
using var transaction = DbContext.Database.BeginTransaction();
|
||||
var list = new List<Blog>();
|
||||
|
||||
for (var i = 0; i <= 100; i++)
|
||||
|
@ -69,7 +71,7 @@ public class BlogService : IBlogService
|
|||
|
||||
DbContext.Blogs.AddRange(list);
|
||||
DbContext.SaveChanges();
|
||||
transaction.Commit();
|
||||
throw new BunnyException("测试事务注解");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using NUnit.Framework;
|
||||
|
||||
namespace Bunny.Test.Until.Test;
|
||||
|
||||
public class Test2
|
||||
{
|
||||
[Test]
|
||||
public void Test1()
|
||||
{
|
||||
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
|
@ -5,13 +5,15 @@ VisualStudioVersion = 17.10.34928.147
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bunny.WebApi", "Bunny.WebApi\Bunny.WebApi.csproj", "{28753039-0C3B-4FE5-95F8-7EDC92DCBA26}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny.Common", "Bunny.Common\Bunny.Common.csproj", "{40D580AA-63CD-4912-835F-ECBB2C232F9E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bunny.Common", "Bunny.Common\Bunny.Common.csproj", "{40D580AA-63CD-4912-835F-ECBB2C232F9E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny.Test.Until", "Bunny.Test.Until\Bunny.Test.Until.csproj", "{945BE294-8057-40EE-9A98-5598D1A728B9}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bunny.Test.Until", "Bunny.Test.Until\Bunny.Test.Until.csproj", "{945BE294-8057-40EE-9A98-5598D1A728B9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny.Dao", "Bunny.Dao\Bunny.Dao.csproj", "{A0A986A6-A0A4-4627-B45A-94A882FC70ED}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bunny.Dao", "Bunny.Dao\Bunny.Dao.csproj", "{A0A986A6-A0A4-4627-B45A-94A882FC70ED}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny.Service", "Bunny.Service\Bunny.Service.csproj", "{7CEBC594-134C-48C1-96ED-263E047E7D96}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bunny.Service", "Bunny.Service\Bunny.Service.csproj", "{7CEBC594-134C-48C1-96ED-263E047E7D96}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bunny.Generate", "Bunny.Generate\Bunny.Generate.csproj", "{6594CE00-5781-4899-A4D9-D9E70CEFDF55}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -39,6 +41,10 @@ Global
|
|||
{7CEBC594-134C-48C1-96ED-263E047E7D96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7CEBC594-134C-48C1-96ED-263E047E7D96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7CEBC594-134C-48C1-96ED-263E047E7D96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6594CE00-5781-4899-A4D9-D9E70CEFDF55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6594CE00-5781-4899-A4D9-D9E70CEFDF55}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6594CE00-5781-4899-A4D9-D9E70CEFDF55}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6594CE00-5781-4899-A4D9-D9E70CEFDF55}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -19,15 +19,16 @@
|
|||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.JobTest.JobTest1.TestJob</TestId>
|
||||
</TestAncestor>
|
||||
</SessionState></s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=83126680_002Dc767_002D40a2_002Dadfd_002Daa4542ab8b4b/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="TestJob #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=83126680_002Dc767_002D40a2_002Dadfd_002Daa4542ab8b4b/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" Name="TestJob #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<TestAncestor>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.JobTest.JobTest1.TestJob</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test1.Start</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test1</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.NetUtilTest.NetTest2</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test2.Test1</TestId>
|
||||
</TestAncestor>
|
||||
</SessionState></s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=eb9da086_002D824a_002D4ac4_002Db755_002D94438e510122/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" Name="Test1" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=eb9da086_002D824a_002D4ac4_002Db755_002D94438e510122/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="Test1" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<Or>
|
||||
<And>
|
||||
<TestAncestor>
|
||||
|
@ -49,6 +50,7 @@
|
|||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test1.Start</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.NetUtilTest.NetTest2</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test1.Method1</TestId>
|
||||
<TestId>NUnit3x::945BE294-8057-40EE-9A98-5598D1A728B9::net8.0::Bunny.Test.Until.Test.Test2.Test1</TestId>
|
||||
</TestAncestor>
|
||||
</Or>
|
||||
</SessionState></s:String>
|
||||
|
|
|
@ -32,6 +32,7 @@ public static class ServiceRegistration
|
|||
{
|
||||
option.Filters.Add<GlobalExceptionFilter>();
|
||||
option.Filters.Add<ValidateModelStateAttribute>();
|
||||
option.Filters.Add<TransactionIAsyncActionFilter>();
|
||||
option.Filters.Add<AuthorizationFilter>();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,8 +9,9 @@ namespace Bunny.WebApi.Controllers;
|
|||
|
||||
/// <summary>
|
||||
/// 验证码测试
|
||||
/// 2024-9-11 09:02:18
|
||||
/// </summary>
|
||||
[Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
|
||||
[Microsoft.AspNetCore.Components.Route("/api/[controller]/[action]")]
|
||||
public class CaptchaTestController : ControllerBase
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(CaptchaTestController));
|
||||
|
|
|
@ -7,7 +7,7 @@ public class Program
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.Title = "Bunny Template";
|
||||
Console.Title = "Bunny ServerTemplate";
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// 基础配置
|
||||
|
|
|
@ -371,4 +371,6 @@ Exception Filter(异常过滤器):用于处理应用程序中发生的异
|
|||
|
||||
7. TypeFilterAttribute
|
||||
类似于ServiceFilterAttribute,但它是通过反射创建过滤器实例,不需要过滤器在DI容器中注册。
|
||||
可以接受参数,用于构造过滤器实例。
|
||||
可以接受参数,用于构造过滤器实例。
|
||||
|
||||
![](https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters/_static/filter-pipeline-2.png?view=aspnetcore-8.0)
|
Loading…
Reference in New Issue