feat(优化): 添加AutoFac

This commit is contained in:
bunny 2024-09-02 09:31:34 +08:00
commit d7c9d8e425
28 changed files with 268 additions and 147 deletions

View File

@ -1,15 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="bunny" uuid="1a151f4f-7b33-40a5-b425-02b84edb60e6"> <data-source source="LOCAL" name="bunny" uuid="b6cf8a1e-027c-4a20-8eff-d18024c58281">
<driver-ref>sqlite.xerial</driver-ref> <driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize> <synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver> <jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:D:\MyFolder\Bunny\Bunny-cli\CSharp\CSharp-Single-EFCore\Bunny.WebApi\bunny.db</jdbc-url> <jdbc-url>jdbc:sqlite:D:\Project\web\Bunny-Cli\template\CSharp\CSharp-Single-EFCore\Bunny.WebApi\Database\bunny.db</jdbc-url>
<jdbc-additional-properties> <jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" /> <property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
</jdbc-additional-properties> </jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir> <working-dir>$ProjectFileDir$</working-dir>
<libraries>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
</library>
</libraries>
</data-source> </data-source>
</component> </component>
</project> </project>

View File

@ -28,14 +28,9 @@ public class EfCoreContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
// 添加过滤器 foreach (var entityType in modelBuilder.Model.GetEntityTypes())
modelBuilder.Entity<BaseEntity>() if (typeof(BaseEntity).IsAssignableFrom(entityType.ClrType))
.HasQueryFilter(e => !e.IsDeleted); entityType.AddSoftDeleteQueryFilter();
// 默认值为false表示未删除
modelBuilder.Entity<BaseEntity>()
.Property(e => e.IsDeleted)
.HasDefaultValue(false);
base.OnModelCreating(modelBuilder); base.OnModelCreating(modelBuilder);
} }
@ -74,7 +69,7 @@ public class EfCoreContext : DbContext
if (item.Entity is BaseEntity entity) if (item.Entity is BaseEntity entity)
switch (item.State) switch (item.State)
{ {
//添加操作 // 添加操作
case EntityState.Added: case EntityState.Added:
{ {
if (entity.Id == string.Empty) entity.Id = Guid.NewGuid().ToString(); if (entity.Id == string.Empty) entity.Id = Guid.NewGuid().ToString();
@ -84,10 +79,10 @@ public class EfCoreContext : DbContext
entity.UpdateUserId = BaseContext.GetUserId()!.Value; entity.UpdateUserId = BaseContext.GetUserId()!.Value;
break; break;
} }
//修改操作 // 修改操作
case EntityState.Modified: case EntityState.Modified:
entity.UpdateTime = DateTime.Now; entity.UpdateTime = DateTime.Now;
entity.UpdateUserId = BaseContext.GetUserId()!.Value; if (BaseContext.GetUserId() != null) entity.UpdateUserId = BaseContext.GetUserId()!.Value;
break; break;
case EntityState.Detached: case EntityState.Detached:
break; break;
@ -97,8 +92,6 @@ public class EfCoreContext : DbContext
entity.UpdateTime = DateTime.Now; entity.UpdateTime = DateTime.Now;
entity.UpdateUserId = BaseContext.GetUserId()!.Value; entity.UpdateUserId = BaseContext.GetUserId()!.Value;
break; break;
default:
throw new ArgumentOutOfRangeException();
} }
} }
} }

View File

@ -5,7 +5,7 @@ namespace Bunny.Common.Connect;
public static class RedisContext public static class RedisContext
{ {
public static IDatabase RedisDatabase; public static IDatabase? RedisDatabase;
private static readonly EndPointCollection EndPointCollection = new(); private static readonly EndPointCollection EndPointCollection = new();
public static void AddRedisContext(this WebApplicationBuilder builder) public static void AddRedisContext(this WebApplicationBuilder builder)

View File

@ -0,0 +1,36 @@
using System.Linq.Expressions;
using System.Reflection;
using Bunny.Dao.Entity.Base;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Bunny.Common.Connect;
/// <summary>
/// 软删除过滤器
/// </summary>
public static class SoftDeleteQueryExtension
{
/// <summary>
/// 软删除过滤器
/// </summary>
/// <param name="entityData"></param>
public static void AddSoftDeleteQueryFilter(this IMutableEntityType entityData)
{
var methodToCall = typeof(SoftDeleteQueryExtension)
.GetMethod(nameof(GetSoftDeleteFilter), BindingFlags.NonPublic | BindingFlags.Static)
?.MakeGenericMethod(entityData.ClrType);
var filter = methodToCall?.Invoke(null, []);
entityData.SetQueryFilter((LambdaExpression)filter!);
}
/// <summary>
/// 软删除
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
private static LambdaExpression GetSoftDeleteFilter<TEntity>() where TEntity : BaseEntity
{
Expression<Func<TEntity, bool>> filter = x => !x.IsDeleted;
return filter;
}
}

View File

@ -3,33 +3,33 @@
public class BaseContext public class BaseContext
{ {
// 使用Lazy初始化确保线程安全 // 使用Lazy初始化确保线程安全
public static readonly ThreadLocal<long?> UserId = new(); public static readonly ThreadLocal<long?>? UserId = null;
public static readonly ThreadLocal<string?> Token = new(); public static readonly ThreadLocal<string?>? Token = null;
// 用户id相关 // 用户id相关
public static long? GetUserId() public static long? GetUserId()
{ {
return UserId.Value; return UserId?.Value;
} }
public static void SetUserId(long? userId) public static void SetUserId(long? userId)
{ {
UserId.Value = userId; UserId!.Value = userId;
} }
public static string? GetToken() public static string? GetToken()
{ {
return Token.Value; return Token?.Value;
} }
public static void SetToken(string token) public static void SetToken(string token)
{ {
Token.Value = token; Token!.Value = token;
} }
public static void RemoveUser() public static void RemoveUser()
{ {
Token.Value = null; if (Token != null) Token.Value = null;
UserId.Value = null; if (UserId != null) UserId.Value = null;
} }
} }

View File

@ -2,7 +2,7 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Bunny.Dao.Model.Constant; using Bunny.Dao.Model.Constant;
namespace Bunny.Common.Configuration; namespace Bunny.Common.Context;
/// <summary> /// <summary>
/// 自定义Json转换器用于将DateTime类型转换为JSON格式 /// 自定义Json转换器用于将DateTime类型转换为JSON格式

View File

@ -12,7 +12,5 @@ public class BaseEntity
public long UpdateUserId { get; set; } public long UpdateUserId { get; set; }
public string? OperationMessage { get; set; }
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
} }

View File

@ -5,5 +5,5 @@ namespace Bunny.Dao.Entity.System;
public class Blog : BaseEntity public class Blog : BaseEntity
{ {
[Required(ErrorMessage = "邮箱是必填项")] public string Url { get; set; } [Required(ErrorMessage = "Url是必填项")] public string Url { get; set; }
} }

View File

@ -168,7 +168,7 @@ public class Result<T>(HttpStatusCode code, T? data, string? message)
/// <param name="message">消息内容</param> /// <param name="message">消息内容</param>
/// <param name="data">数据内容分</param> /// <param name="data">数据内容分</param>
/// <returns>返回的数据内容</returns> /// <returns>返回的数据内容</returns>
public static Result<T> Error(string message, T data) public static Result<T> Error(T data, string message)
{ {
return new Result<T>(HttpStatusCode.InternalServerError, data, message); return new Result<T>(HttpStatusCode.InternalServerError, data, message);
} }

View File

@ -1,17 +1,13 @@
using Bunny.Common.Connect; using Bunny.Common.Connect;
using Bunny.Dao.Entity.System; using Bunny.Dao.Entity.System;
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Microsoft.AspNetCore.Components;
namespace Bunny.Service.IService.Service; namespace Bunny.Service.IService.Service;
public class BlogService : IBlogService public class BlogService : IBlogService
{ {
private readonly EfCoreContext _dbContext; [Inject] public required EfCoreContext DbContext { get; set; }
public BlogService(EfCoreContext dbContext)
{
_dbContext = dbContext;
}
/// <summary> /// <summary>
/// 添加Blog /// 添加Blog
@ -20,8 +16,8 @@ public class BlogService : IBlogService
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public void AddBlog(Blog dto) public void AddBlog(Blog dto)
{ {
_dbContext.Add(dto); DbContext.Add(dto);
_dbContext.SaveChanges(); DbContext.SaveChanges();
} }
/// <summary> /// <summary>
@ -30,7 +26,7 @@ public class BlogService : IBlogService
/// <returns></returns> /// <returns></returns>
public List<Blog> QueryBlog() public List<Blog> QueryBlog()
{ {
return _dbContext.Blogs.ToList(); return DbContext.Blogs.ToList();
} }
/// <summary> /// <summary>
@ -39,8 +35,8 @@ public class BlogService : IBlogService
/// <param name="dto"></param> /// <param name="dto"></param>
public void UpdateBlog(Blog dto) public void UpdateBlog(Blog dto)
{ {
_dbContext.Blogs.Update(dto); DbContext.Blogs.Update(dto);
_dbContext.SaveChanges(); DbContext.SaveChanges();
} }
/// <summary> /// <summary>
@ -50,8 +46,8 @@ public class BlogService : IBlogService
public void DeleteBlog(string id) public void DeleteBlog(string id)
{ {
var blog = new Blog { Id = id }; var blog = new Blog { Id = id };
_dbContext.Blogs.Remove(blog); DbContext.Blogs.Remove(blog);
_dbContext.SaveChanges(); DbContext.SaveChanges();
} }
/// <summary> /// <summary>
@ -72,8 +68,8 @@ public class BlogService : IBlogService
CreateUserId = Random.Shared.NextInt64() CreateUserId = Random.Shared.NextInt64()
}); });
_dbContext.Blogs.AddRange(list); DbContext.Blogs.AddRange(list);
_dbContext.SaveChanges(); DbContext.SaveChanges();
} }
@ -89,8 +85,8 @@ public class BlogService : IBlogService
list.Add(blog); list.Add(blog);
} }
_dbContext.Blogs.RemoveRange(list); DbContext.Blogs.RemoveRange(list);
_dbContext.SaveChanges(); DbContext.SaveChanges();
} }
/// <summary> /// <summary>
@ -99,7 +95,7 @@ public class BlogService : IBlogService
public void UseTransaction() public void UseTransaction()
{ {
// 还可以使用异步的 // 还可以使用异步的
var transaction = _dbContext.Database.BeginTransaction(); var transaction = DbContext.Database.BeginTransaction();
// 执行批量更新操作 // 执行批量更新操作
var list = new List<Blog>(); var list = new List<Blog>();
@ -110,8 +106,8 @@ public class BlogService : IBlogService
} }
// 更新内容 // 更新内容
_dbContext.Blogs.UpdateRange(list); DbContext.Blogs.UpdateRange(list);
_dbContext.SaveChanges(); DbContext.SaveChanges();
// 还可以使用异步方式 // 还可以使用异步方式
transaction.Commit(); transaction.Commit();
@ -124,7 +120,7 @@ public class BlogService : IBlogService
/// <param name="limit"></param> /// <param name="limit"></param>
public PageResult<Blog> QueryPage(int page, int limit) public PageResult<Blog> QueryPage(int page, int limit)
{ {
var items = _dbContext.Blogs.ToList(); var items = DbContext.Blogs.ToList();
var total = items.Count; var total = items.Count;
var pages = (int)Math.Ceiling(total / (double)limit); var pages = (int)Math.Ceiling(total / (double)limit);

View File

@ -13,7 +13,6 @@ public class JobService : IJobService
public void StartSimpleJob() public void StartSimpleJob()
{ {
var schedulerFactory = new StdSchedulerFactory(); var schedulerFactory = new StdSchedulerFactory();
// TODO 如果使用异步必须使用await 和 async
// var scheduler = schedulerFactory.GetScheduler(); // var scheduler = schedulerFactory.GetScheduler();
var scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult(); var scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult();
@ -32,10 +31,6 @@ public class JobService : IJobService
// 使用同步方法 // 使用同步方法
scheduler.ScheduleJob(jobDetail, trigger).GetAwaiter().GetResult(); scheduler.ScheduleJob(jobDetail, trigger).GetAwaiter().GetResult();
scheduler.Start().GetAwaiter().GetResult(); scheduler.Start().GetAwaiter().GetResult();
// TODO 使用异步
// await _scheduler.ScheduleJob(jobDetail, trigger);
// await _scheduler.Start();
} }
/// <summary> /// <summary>
@ -49,8 +44,8 @@ public class JobService : IJobService
var jobDetail = JobBuilder.Create<SimpleJob>() var jobDetail = JobBuilder.Create<SimpleJob>()
.UsingJobData("username", "用户名") .UsingJobData("username", "用户名")
.UsingJobData("password", "密码") .UsingJobData("password", "密码")
// TODO 如果不设置持久的会报错; // 如果不设置持久的会报错;
// TODO Jobs added with no trigger must be durable.Quartz.SchedulerException: Jobs added with no trigger must be durable. // Jobs added with no trigger must be durable.Quartz.SchedulerException: Jobs added with no trigger must be durable.
.StoreDurably() // 设置作业为持久的 .StoreDurably() // 设置作业为持久的
.WithIdentity("simpleJob", "简单的JOB") .WithIdentity("simpleJob", "简单的JOB")
.Build(); .Build();
@ -63,9 +58,9 @@ public class JobService : IJobService
.UsingJobData("trigger", "trigger值") .UsingJobData("trigger", "trigger值")
.WithIdentity("testTrigger", "测试发出器") .WithIdentity("testTrigger", "测试发出器")
.StartNow() .StartNow()
// TODO 设置调度时间单位 // 设置调度时间单位
// .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).WithRepeatCount(10)) // .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).WithRepeatCount(10))
// TODO 自定义调度时间单位 // 自定义调度时间单位
.WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromMinutes(1)).WithRepeatCount(10)) .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromMinutes(1)).WithRepeatCount(10))
.Build(); .Build();
@ -95,9 +90,9 @@ public class JobService : IJobService
.UsingJobData("trigger", "trigger值") .UsingJobData("trigger", "trigger值")
.WithIdentity("testTrigger", "测试发出器") .WithIdentity("testTrigger", "测试发出器")
.StartNow() .StartNow()
// TODO StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(20, 0))触发器从每天的20:00晚上8点开始。 // StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(20, 0))触发器从每天的20:00晚上8点开始。
// TODO EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(22, 0))触发器在每天的22:00晚上10点结束。 // EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(22, 0))触发器在每天的22:00晚上10点结束。
// TODO WithIntervalInSeconds(2)在开始和结束时间之间触发器将每2秒触发一次作业。 // WithIntervalInSeconds(2)在开始和结束时间之间触发器将每2秒触发一次作业。
.WithDailyTimeIntervalSchedule(x => x.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(16, 0)) .WithDailyTimeIntervalSchedule(x => x.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(16, 0))
.EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(22, 0)) .EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(22, 0))
// 设置工作时间在每周的星期几 // 设置工作时间在每周的星期几

View File

@ -27,6 +27,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0"/>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0"/>
<PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.16"/> <PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.16"/>
<PackageReference Include="log4net" Version="2.0.17"/> <PackageReference Include="log4net" Version="2.0.17"/>
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0"/> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0"/>

View File

@ -0,0 +1,30 @@
using Autofac;
using Bunny.Common.Connect;
using Bunny.Service.IService;
using Bunny.Service.IService.Service;
using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Configuration;
public static class AddAutofacConfig
{
public static void BuildContainer(ContainerBuilder builder)
{
// 如果不在在 Controller 层写构造函数可以打开这个,自动完成注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired(); //支持属性注入
// 注入EfCore上下文对象
builder.RegisterType<EfCoreContext>();
// 注入Service服务
builder.RegisterType<BaseService>().As<IBaseService>();
builder.RegisterType<BlogService>().As<IBlogService>();
builder.RegisterType<RedisOptionService>().As<IRedisOptionService>();
builder.RegisterType<JobService>().As<IJobService>();
builder.RegisterType<MinioService>().As<IMinioService>();
}
}

View File

@ -1,9 +1,13 @@
using Bunny.Common; using Autofac;
using Bunny.Common.Configuration; using Autofac.Extensions.DependencyInjection;
using Bunny.Common;
using Bunny.Common.Connect; using Bunny.Common.Connect;
using Bunny.Common.Context;
using Bunny.Service.WebSocket; using Bunny.Service.WebSocket;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Bunny.WebApi.Config; namespace Bunny.WebApi.Configuration;
public class BaseConfig(WebApplicationBuilder builder) public class BaseConfig(WebApplicationBuilder builder)
{ {
@ -15,21 +19,22 @@ public class BaseConfig(WebApplicationBuilder builder)
// 配置跨域 // 配置跨域
UseCors(); UseCors();
// 配置日志相关 // 配置日志相关
// builder.Logging.AddLog4Net("Config/log4net.config"); // builder.Logging.AddLog4Net("Configuration/log4net.config");
// 自定义时间格式 // 自定义时间格式
builder.Services.AddControllers().AddJsonOptions(options => builder.Services.AddControllers().AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter())); options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter()));
// 添加使用自定义配置文件 // 添加使用自定义配置文件
builder.Services.AddSingleton(new AppSettings(builder.Configuration)); builder.Services.AddSingleton(new AppSettings(builder.Configuration));
// 添加 SignalR
builder.Services.AddSignalR();
builder.WebHost.ConfigureKestrel((_, options) => builder.WebHost.ConfigureKestrel((_, options) =>
{ {
// 设置文件最大上传大小 // 设置文件最大上传大小
options.Limits.MaxRequestBodySize = 1024 * 1024 * 100; options.Limits.MaxRequestBodySize = 1024 * 1024 * 100;
}); });
// 添加Service服务 // 使用 AddAutofac 注册服务
builder.AddApplicationServices(); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(AddAutofacConfig.BuildContainer);
// 让控制器实例由容器创建
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
// 添加定时任务 // 添加定时任务
builder.AddApplicationBackendServices(); builder.AddApplicationBackendServices();
// 设置过滤器 // 设置过滤器

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
namespace Bunny.WebApi.Config; namespace Bunny.WebApi.Configuration;
public static class Knife4Net public static class Knife4Net
{ {

View File

@ -1,30 +1,14 @@
using Bunny.Common.Connect; using Bunny.Common.Filter;
using Bunny.Common.Filter;
using Bunny.Service.Filter; using Bunny.Service.Filter;
using Bunny.Service.IService;
using Bunny.Service.IService.Service;
using Bunny.Service.Job.JobService; using Bunny.Service.Job.JobService;
using Lazy.Captcha.Core; using Lazy.Captcha.Core;
using Lazy.Captcha.Core.Generator; using Lazy.Captcha.Core.Generator;
using SkiaSharp; using SkiaSharp;
namespace Bunny.WebApi.Config; namespace Bunny.WebApi.Configuration;
public static class ServiceRegistration public static class ServiceRegistration
{ {
public static void AddApplicationServices(this WebApplicationBuilder builder)
{
// 注入EfCore上下文对象
builder.Services.AddScoped<EfCoreContext>();
// 注入Service服务
builder.Services.AddScoped<IBaseService, BaseService>();
builder.Services.AddScoped<IBlogService, BlogService>();
builder.Services.AddScoped<IRedisOptionService, RedisOptionService>();
builder.Services.AddScoped<IJobService, JobService>();
builder.Services.AddScoped<IMinioService, MinioService>();
}
/// <summary> /// <summary>
/// 注入后台服务相关 /// 注入后台服务相关
/// 用于添加所以Job服务之后在BaseConfig中进行调用 /// 用于添加所以Job服务之后在BaseConfig中进行调用

View File

@ -1,6 +1,7 @@
using Bunny.Dao.Entity.System; using Bunny.Dao.Entity.System;
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Bunny.Service.IService; using Bunny.Service.IService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
@ -8,15 +9,11 @@ namespace Bunny.WebApi.Controllers;
/// <summary> /// <summary>
/// BLog相关接口 /// BLog相关接口
/// </summary> /// </summary>
[Route("/api/[controller]/[action]")] [Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
public class BlogController : ControllerBase public class BlogController : ControllerBase
{ {
private readonly IBlogService _blogService; [Inject] public required IBlogService BlogService { get; set; }
public BlogController(IBlogService blogService)
{
_blogService = blogService;
}
/// <summary> /// <summary>
/// 添加Blog /// 添加Blog
@ -26,7 +23,7 @@ public class BlogController : ControllerBase
[HttpPost] [HttpPost]
public Result<object> AddBlog(Blog dto) public Result<object> AddBlog(Blog dto)
{ {
_blogService.AddBlog(dto); BlogService.AddBlog(dto);
return Result<object>.Success(); return Result<object>.Success();
} }
@ -37,7 +34,7 @@ public class BlogController : ControllerBase
[HttpGet] [HttpGet]
public Result<List<Blog>> QueryBlog() public Result<List<Blog>> QueryBlog()
{ {
var vo = _blogService.QueryBlog(); var vo = BlogService.QueryBlog();
return Result<List<Blog>>.Success(vo); return Result<List<Blog>>.Success(vo);
} }
@ -49,7 +46,7 @@ public class BlogController : ControllerBase
[HttpPost] [HttpPost]
public Result<object> UpdateBlog(Blog dto) public Result<object> UpdateBlog(Blog dto)
{ {
_blogService.UpdateBlog(dto); BlogService.UpdateBlog(dto);
return Result<object>.Success(); return Result<object>.Success();
} }
@ -60,7 +57,7 @@ public class BlogController : ControllerBase
[HttpDelete] [HttpDelete]
public Result<string> DeleteBlog(string id) public Result<string> DeleteBlog(string id)
{ {
_blogService.DeleteBlog(id); BlogService.DeleteBlog(id);
return Result<string>.Success(); return Result<string>.Success();
} }
@ -71,7 +68,7 @@ public class BlogController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> AddBatchBlogs(string url) public Result<string> AddBatchBlogs(string url)
{ {
_blogService.AddBatchBlogs(url); BlogService.AddBatchBlogs(url);
return Result<string>.Success(); return Result<string>.Success();
} }
@ -82,7 +79,7 @@ public class BlogController : ControllerBase
[HttpGet] [HttpGet]
public Result<string> DeleteBatchBlogs() public Result<string> DeleteBatchBlogs()
{ {
_blogService.DeleteBatchBlogs(); BlogService.DeleteBatchBlogs();
return Result<string>.Success(); return Result<string>.Success();
} }
@ -93,7 +90,7 @@ public class BlogController : ControllerBase
[HttpGet] [HttpGet]
public Result<string> UseTransaction() public Result<string> UseTransaction()
{ {
_blogService.UseTransaction(); BlogService.UseTransaction();
return Result<string>.Success(); return Result<string>.Success();
} }
@ -104,7 +101,7 @@ public class BlogController : ControllerBase
[HttpPost] [HttpPost]
public Result<PageResult<Blog>> QueryPage(int page = 1, int limit = 10) public Result<PageResult<Blog>> QueryPage(int page = 1, int limit = 10)
{ {
var vo = _blogService.QueryPage(page, limit); var vo = BlogService.QueryPage(page, limit);
return Result<PageResult<Blog>>.Success(vo); return Result<PageResult<Blog>>.Success(vo);
} }

View File

@ -1,6 +1,7 @@
using Bunny.Dao.Model.Constant.Result; using Bunny.Dao.Model.Constant.Result;
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Lazy.Captcha.Core; using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
@ -8,9 +9,11 @@ namespace Bunny.WebApi.Controllers;
/// <summary> /// <summary>
/// 验证码测试 /// 验证码测试
/// </summary> /// </summary>
[Route("/api/[controller]/[action]")] [Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
public class CaptchaTestController(ICaptcha _captcha) : ControllerBase public class CaptchaTestController : ControllerBase
{ {
[Inject] public required ICaptcha Captcha { get; set; }
/// <summary> /// <summary>
/// 测试测试验证码生成 /// 测试测试验证码生成
/// </summary> /// </summary>
@ -18,7 +21,7 @@ public class CaptchaTestController(ICaptcha _captcha) : ControllerBase
[HttpGet] [HttpGet]
public IActionResult GetCaptcha(string id) public IActionResult GetCaptcha(string id)
{ {
var captchaData = _captcha.Generate(id); var captchaData = Captcha.Generate(id);
// 验证码的ID // 验证码的ID
var captchaDataId = captchaData.Id; var captchaDataId = captchaData.Id;
// 验证码的代码 // 验证码的代码
@ -39,7 +42,9 @@ public class CaptchaTestController(ICaptcha _captcha) : ControllerBase
public Result<string> CheckCode(string id, string code) public Result<string> CheckCode(string id, string code)
{ {
// 校验用户输入的验证码是否=正确 // 校验用户输入的验证码是否=正确
var validate = _captcha.Validate(id, code); var validate = Captcha.Validate(id, code);
return validate ? Result<string>.Success() : Result<string>.Error(ErrorConstant.ValidateCodeError); return validate
? Result<string>.Success()
: Result<string>.Error(null!, ErrorConstant.ValidateCodeError);
} }
} }

View File

@ -1,5 +1,6 @@
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Bunny.Service.IService; using Bunny.Service.IService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
@ -7,9 +8,11 @@ namespace Bunny.WebApi.Controllers;
/// <summary> /// <summary>
/// Quartz 示例相关 /// Quartz 示例相关
/// </summary> /// </summary>
[Route("/api/[controller]/[action]")] [Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
public class JobInitController(IJobService jobService) : ControllerBase public class JobInitController : ControllerBase
{ {
[Inject] public required IJobService JobService { get; set; }
/// <summary> /// <summary>
/// 1. 开启一个简单的工作 /// 1. 开启一个简单的工作
/// </summary> /// </summary>
@ -17,7 +20,7 @@ public class JobInitController(IJobService jobService) : ControllerBase
[HttpPost] [HttpPost]
public Result<string> StartSimpleJob() public Result<string> StartSimpleJob()
{ {
jobService.StartSimpleJob(); JobService.StartSimpleJob();
return Result<string>.Success("将名称生成放在jobDetail中可以再运行时获取到"); return Result<string>.Success("将名称生成放在jobDetail中可以再运行时获取到");
} }
@ -28,7 +31,7 @@ public class JobInitController(IJobService jobService) : ControllerBase
[HttpPost] [HttpPost]
public Result<string> PutJobDetail4Trigger() public Result<string> PutJobDetail4Trigger()
{ {
jobService.PutJobDetail4Trigger(); JobService.PutJobDetail4Trigger();
return Result<string>.Success("将jobDetail中的一些信息放在触发器中简化写法"); return Result<string>.Success("将jobDetail中的一些信息放在触发器中简化写法");
} }
@ -39,7 +42,7 @@ public class JobInitController(IJobService jobService) : ControllerBase
[HttpHead] [HttpHead]
public Result<string> SetJobWithDaily() public Result<string> SetJobWithDaily()
{ {
jobService.SetJobWithDaily(); JobService.SetJobWithDaily();
return Result<string>.Success(); return Result<string>.Success();
} }
} }

View File

@ -1,15 +1,18 @@
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Bunny.Service.IService; using Bunny.Service.IService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Minio.DataModel; using Minio.DataModel;
using Minio.DataModel.Result; using Minio.DataModel.Result;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
[Route("/api/[controller]/[action]")] [Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
[ApiController] [ApiController]
public class MinioController(IMinioService minioService) : ControllerBase public class MinioController : ControllerBase
{ {
[Inject] public required IMinioService MinioService { get; set; }
/// <summary> /// <summary>
/// 查询所有的桶 /// 查询所有的桶
/// </summary> /// </summary>
@ -17,7 +20,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public Result<ListAllMyBucketsResult> GetAllMyBuckets() public Result<ListAllMyBucketsResult> GetAllMyBuckets()
{ {
var listAllMyBucketsResult = minioService.GetAllMyBuckets(); var listAllMyBucketsResult = MinioService.GetAllMyBuckets();
return Result<ListAllMyBucketsResult>.Success(listAllMyBucketsResult); return Result<ListAllMyBucketsResult>.Success(listAllMyBucketsResult);
} }
@ -29,7 +32,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpPost] [HttpPost]
public Result<string> SaveMinioFile(IFormFile? file, string filepath = "test") public Result<string> SaveMinioFile(IFormFile? file, string filepath = "test")
{ {
minioService.SaveMinioFile(file, filepath); MinioService.SaveMinioFile(file, filepath);
return Result<string>.Success("上传成功"); return Result<string>.Success("上传成功");
} }
@ -42,7 +45,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public Result<ObjectStat> GetObjectStat(string filename, string bucketName = "csharp-test") public Result<ObjectStat> GetObjectStat(string filename, string bucketName = "csharp-test")
{ {
var vo = minioService.GetObjectStat(filename, bucketName); var vo = MinioService.GetObjectStat(filename, bucketName);
return Result<ObjectStat>.Success(vo); return Result<ObjectStat>.Success(vo);
} }
@ -55,7 +58,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public Result<string> GetObjectPath(string filename, string bucketName = "csharp-test") public Result<string> GetObjectPath(string filename, string bucketName = "csharp-test")
{ {
var vo = minioService.GetObjectPath(filename, bucketName); var vo = MinioService.GetObjectPath(filename, bucketName);
return Result<string>.Success(vo); return Result<string>.Success(vo);
} }
@ -68,7 +71,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public IActionResult DownloadObject(string filename, string bucketName = "csharp-test") public IActionResult DownloadObject(string filename, string bucketName = "csharp-test")
{ {
var buffer = minioService.DownloadObject(filename, bucketName).Result; var buffer = MinioService.DownloadObject(filename, bucketName).Result;
return File(buffer, "application/octet-stream", filename); return File(buffer, "application/octet-stream", filename);
} }
@ -81,7 +84,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public IActionResult ViewObject(string filename, string bucketName = "csharp-test") public IActionResult ViewObject(string filename, string bucketName = "csharp-test")
{ {
var buffer = minioService.DownloadObject(filename, bucketName).Result; var buffer = MinioService.DownloadObject(filename, bucketName).Result;
return File(buffer, "image/jpeg"); return File(buffer, "image/jpeg");
} }
@ -94,7 +97,7 @@ public class MinioController(IMinioService minioService) : ControllerBase
[HttpGet] [HttpGet]
public Result<IAsyncEnumerable<Item>> ListObject(string? filepath, string bucketName = "csharp-test") public Result<IAsyncEnumerable<Item>> ListObject(string? filepath, string bucketName = "csharp-test")
{ {
var vo = minioService.ListObject(filepath, bucketName); var vo = MinioService.ListObject(filepath, bucketName);
return Result<IAsyncEnumerable<Item>>.Success(vo); return Result<IAsyncEnumerable<Item>>.Success(vo);
} }
} }

View File

@ -1,5 +1,6 @@
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Bunny.Service.IService; using Bunny.Service.IService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
@ -7,15 +8,10 @@ namespace Bunny.WebApi.Controllers;
/// <summary> /// <summary>
/// 操作Redis相关内容 /// 操作Redis相关内容
/// </summary> /// </summary>
[Route("/api/[controller]/[action]")] [Microsoft.AspNetCore.Mvc.Route("/api/[controller]/[action]")]
public class RedisOptionController : ControllerBase public class RedisOptionController : ControllerBase
{ {
private readonly IRedisOptionService _redisOptionService; [Inject] public required IRedisOptionService RedisOptionService { get; set; }
public RedisOptionController(IRedisOptionService redisOptionService)
{
_redisOptionService = redisOptionService;
}
/// <summary> /// <summary>
/// 添加Redis中一个值 /// 添加Redis中一个值
@ -26,7 +22,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> AddStringValue(string key, string value) public Result<string> AddStringValue(string key, string value)
{ {
_redisOptionService.AddStringValue(key, value); RedisOptionService.AddStringValue(key, value);
return Result<string>.Success(); return Result<string>.Success();
} }
@ -37,7 +33,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> QueryStringKey(string key) public Result<string> QueryStringKey(string key)
{ {
var queryStringKey = _redisOptionService.QueryStringKey(key); var queryStringKey = RedisOptionService.QueryStringKey(key);
return Result<string>.Success(queryStringKey); return Result<string>.Success(queryStringKey);
} }
@ -50,7 +46,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> AddTimeRedisKey(string key, string value) public Result<string> AddTimeRedisKey(string key, string value)
{ {
_redisOptionService.AddTimeRedisKey(key, value); RedisOptionService.AddTimeRedisKey(key, value);
return Result<string>.Success(value); return Result<string>.Success(value);
} }
@ -63,7 +59,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> AddTimeRedisKeyTtl(string key, string value) public Result<string> AddTimeRedisKeyTtl(string key, string value)
{ {
_redisOptionService.AddTimeRedisKeyTtl(key, value); RedisOptionService.AddTimeRedisKeyTtl(key, value);
return Result<string>.Success(value); return Result<string>.Success(value);
} }
@ -74,7 +70,7 @@ public class RedisOptionController : ControllerBase
[HttpGet] [HttpGet]
public Result<string> AddJson() public Result<string> AddJson()
{ {
var json = _redisOptionService.AddJson(); var json = RedisOptionService.AddJson();
return Result<string>.Success(json); return Result<string>.Success(json);
} }
@ -86,7 +82,7 @@ public class RedisOptionController : ControllerBase
[HttpDelete] [HttpDelete]
public Result<string> DeleteKey(string key) public Result<string> DeleteKey(string key)
{ {
_redisOptionService.DeleteKey(key); RedisOptionService.DeleteKey(key);
return Result<string>.Success(); return Result<string>.Success();
} }
@ -97,7 +93,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> SetRedisCreateTransaction(string key, string value) public Result<string> SetRedisCreateTransaction(string key, string value)
{ {
var redisCreateTransaction = _redisOptionService.SetRedisCreateTransaction(key, value); var redisCreateTransaction = RedisOptionService.SetRedisCreateTransaction(key, value);
return Result<string>.Success(redisCreateTransaction); return Result<string>.Success(redisCreateTransaction);
} }
@ -108,7 +104,7 @@ public class RedisOptionController : ControllerBase
[HttpPost] [HttpPost]
public Result<string> AddHashWithRedis(string key, double keyExpire = 6.0) public Result<string> AddHashWithRedis(string key, double keyExpire = 6.0)
{ {
_redisOptionService.AddHashWithRedis(key, keyExpire); RedisOptionService.AddHashWithRedis(key, keyExpire);
return Result<string>.Success(); return Result<string>.Success();
} }
} }

View File

@ -1,5 +1,6 @@
using Bunny.Dao.Model.Result; using Bunny.Dao.Model.Result;
using Bunny.Service.IService; using Bunny.Service.IService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Controllers; namespace Bunny.WebApi.Controllers;
@ -8,15 +9,10 @@ namespace Bunny.WebApi.Controllers;
/// 测试请求模板 /// 测试请求模板
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]")] [Microsoft.AspNetCore.Mvc.Route("api/[controller]")]
public class TemplateController : ControllerBase public class TemplateController : ControllerBase
{ {
private readonly IBaseService _baseService; [Inject] public required IBaseService BaseService { get; set; }
public TemplateController(IBaseService baseService)
{
_baseService = baseService;
}
/// <summary> /// <summary>
/// 测试走缓存 /// 测试走缓存
@ -36,7 +32,7 @@ public class TemplateController : ControllerBase
[HttpGet("TestInject")] [HttpGet("TestInject")]
public Result<string> TestInject() public Result<string> TestInject()
{ {
var testIndex = _baseService.TestIndex(); var testIndex = BaseService.TestIndex();
return Result<string>.Success(testIndex); return Result<string>.Success(testIndex);
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
using Bunny.WebApi.Config; using Bunny.WebApi.Configuration;
using IGeekFan.AspNetCore.Knife4jUI; using IGeekFan.AspNetCore.Knife4jUI;
namespace Bunny.WebApi; namespace Bunny.WebApi;

View File

@ -62,3 +62,77 @@ service.AddCaptcha(options =>
}); });
} }
``` ```
## AutoFac配置
### 自动注入按照名称注入
**AutoFac配置详情**
```csharp
using Autofac;
using Bunny.Common.Attribute;
using Microsoft.AspNetCore.Mvc;
namespace Bunny.WebApi.Config;
public static class AddAutofacConfig
{
/// <summary>
/// AutoFac自动注入约定名称
/// 接口以Service结尾注入到IOC中
/// </summary>
/// <param name="builder"></param>
public static void BuildContainer(ContainerBuilder builder)
{
// 扫描所以前缀Bunny的命名空间
var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(t => t.FullName!.StartsWith("Bunny"));
// 遍历注入服务
foreach (var assembly in assemblies)
{
var types = assembly.GetTypes();
// 注入Service
var serviceTypes = types.Where(t => t.GetCustomAttributes(typeof(ServiceAttribute), false).Length != 0);
foreach (var serviceType in serviceTypes)
{
var interfaces = serviceType.GetInterfaces();
builder.RegisterType(serviceType).As(interfaces).InstancePerDependency();
}
// 注入数据库相关
var mapperTypes = types.Where(t => t.GetCustomAttributes(typeof(MapperAttribute), false).Length != 0);
foreach (var mapperType in mapperTypes)
{
var interfaces = mapperType.GetInterfaces();
builder.RegisterType(mapperType).As(interfaces).InstancePerDependency();
}
// 注入后台服务
var componentTypes =
types.Where(t => t.GetCustomAttributes(typeof(ComponentAttribute), false).Length != 0);
foreach (var componentType in componentTypes)
builder.RegisterType(componentType).AsSelf().As<IHostedService>().SingleInstance();
}
// 如果不在在 Controller 层写构造函数可以打开这个,自动完成注入
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired(); //支持属性注入
}
}
```
**主程序入口配置**
```csharp
// 让控制器实例由容器创建
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
// 如果将Service放在 WebApi同级目录下可以完成Controller自动注入不需要写构造函数
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
builder.Services.AddControllers().AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter()));
```