Compare commits

..

10 Commits

Author SHA1 Message Date
lihanbo 1a362319d0 Default dev db for sqlite 2024-10-16 11:28:39 +08:00
lihanbo 448cb878ba Config DefaultConnection 2024-10-16 11:28:17 +08:00
lihanbo 215540ca1c Add Default CURD impl 2024-10-16 11:27:57 +08:00
lihanbo 0d5dc03030 Use IModule register modules 2024-10-16 11:27:14 +08:00
lihanbo cf7ebb3cbc Add CodeFirst helper 2024-10-16 11:25:57 +08:00
lihanbo 5f9f86663e Update allow use GetAll 2024-10-16 11:25:32 +08:00
lihanbo 963649b2b7 FIx error `The logger is already frozen` 2024-10-16 11:24:49 +08:00
lihanbo 7a6c1d8481 Fix typo 2024-10-16 11:24:29 +08:00
lihanbo 19a612160e FIx error `The logger is already frozen` 2024-10-16 11:24:10 +08:00
lihanbo 59e8845568 Add Module interface. use ConfigureModule method to build Module 2024-10-16 11:17:16 +08:00
16 changed files with 333 additions and 125 deletions

View File

@ -6,7 +6,7 @@ using Serilog;
using Serilog.Core; using Serilog.Core;
namespace LFlow.Home.Controllers; namespace LFlow.Home.Controllers;
public class HomeController(IHomeService<HomeDto, string> service, ILogger logger) : BaseController public class HomeController(IHomeService<HomeDto, string> service, ILogger logger)
{ {
[HttpGet] [HttpGet]
public string Home(string id) public string Home(string id)

30
LFlow.Home/HomeModule.cs Normal file
View File

@ -0,0 +1,30 @@
using System;
using System.Reflection;
using LFlow.Base.BusinessInterface;
using LFlow.Base.Interfaces;
using LFlow.Base.Utils;
using LFlow.Home.Models.DataModels;
using LFlow.Home.Models.DtoModel;
using LFlow.Home.Services;
using Microsoft.Extensions.DependencyInjection;
namespace LFlow.Home;
public class HomeModule : IModule
{
public void ConfigureModule(IServiceCollection services)
{
// 将HomeModel注册到CodeFirst将会在程序启动后自动创建表
CodeFirst.AddType(typeof(HomeModel));
var assembly = Assembly.GetAssembly(typeof(HomeService))!;
var types = assembly.GetTypes().ToList();
RegisterModule.RegisterAllService(types, services);
RegisterModule.RegisterAllRepo(types, services);
RegisterModule.RegisterAllModule(types, services);
services.AddControllers().AddApplicationPart(assembly);
Console.WriteLine("HomeModule ConfigureModule");
}
}

View File

@ -5,11 +5,26 @@ namespace LFlow.Home.Models.DtoModel;
public class HomeDto : IModel public class HomeDto : IModel
{ {
public string? Id { get; set; } public string? Id
{
get; set;
}
public string? ModuleName
{
get; set;
}
public string? ModuleUrl
{
get; set;
}
public string? ModuleVer
{
get; set;
}
public override string ToString() public override string ToString()
{ {
return $"HomeDto {Id}"; return $"HomeDto {Id} _ {ModuleName} _ {ModuleUrl} _ {ModuleVer}";
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using LFlow.Base.Default;
using LFlow.Base.Interfaces; using LFlow.Base.Interfaces;
// using LFlow.Interfaces; // using LFlow.Interfaces;
@ -7,33 +8,21 @@ using SqlSugar;
namespace LFlow.Home.Repositorys; namespace LFlow.Home.Repositorys;
public class HomeRepo(ISqlSugarClient db) : IRepo<HomeModel, string> public class HomeRepo(ISqlSugarClient db) : DefaultCurdRepo<HomeModel, string>(db)
{ {
public HomeModel Delete(string id)
{
throw new NotImplementedException();
}
public HomeModel Get(string id) /// <summary>
{ /// 查询
return new HomeModel /// </summary>
{ /// <param name="whereObj"></param>
Id = id /// <returns></returns>
}; /// <exception cref="NotImplementedException"></exception>
} public override List<HomeModel> Search(HomeModel whereObj) => throw new NotImplementedException();
/// <summary>
public HomeModel SaveOrUpdate(HomeModel entity, bool isUpdate) /// 根据条件查询ID
{ /// </summary>
throw new NotImplementedException(); /// <param name="whereObj"></param>
} /// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public List<HomeModel> Search(HomeModel whereObj) public override List<string> WhereSearchId(HomeModel whereObj) => throw new NotImplementedException();
{
throw new NotImplementedException();
}
public List<string> WhereSearchId(HomeModel whereObj)
{
throw new NotImplementedException();
}
} }

View File

@ -7,31 +7,33 @@ using LFlow.Home.Models.DataModels;
using LFlow.Home.Models.DtoModel; using LFlow.Home.Models.DtoModel;
using LFlow.Base.BusinessInterface; using LFlow.Base.BusinessInterface;
using Serilog; using Serilog;
using Microsoft.AspNetCore.Mvc;
namespace LFlow.Home.Services; namespace LFlow.Home.Services;
public class HomeService(IRepo<HomeModel, string> repo, ILogger logger) : IHomeService<HomeDto, string> public class HomeService(IRepo<HomeModel, string> repo, ILogger logger) : BaseController, IHomeService<HomeDto?, string>
{ {
public HomeDto DeleteById(string id) [HttpGet]
public HomeDto? DeleteById(string id)
{ {
var result = repo.Delete(id); var result = repo.Delete(id);
return Mapper.Map<HomeDto>(result); return Mapper.Map<HomeDto>(result);
} }
[HttpGet]
public HomeDto GetById(string id) public HomeDto? GetById(string id)
{ {
logger.Information($"GetById id -> {id}"); logger.Information($"GetById id -> {id}");
var result = repo.Get(id); var result = repo.Get(id);
return Mapper.Map<HomeDto>(result); return Mapper.Map<HomeDto>(result);
} }
[HttpPost]
public HomeDto Save(HomeDto entity) public HomeDto? Save(HomeDto entity)
{ {
var result = repo.SaveOrUpdate(Mapper.Map<HomeModel>(entity), false); var result = repo.SaveOrUpdate(Mapper.Map<HomeModel>(entity), false);
return Mapper.Map<HomeDto>(result); return Mapper.Map<HomeDto>(result);
} }
[HttpGet]
public List<HomeDto> Search(HomeDto whereObj) public List<HomeDto>? Search(HomeDto whereObj)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -1,41 +1,25 @@
using System; using System;
using LFlow.Base.Default;
using LFlow.Base.Interfaces; using LFlow.Base.Interfaces;
using LFlow.User.Model.DataModel; using LFlow.User.Model.DataModel;
using SqlSugar; using SqlSugar;
namespace LFlow.User.Repositorys; namespace LFlow.User.Repositorys;
public class UserRepo(ISqlSugarClient db) : IRepo<UserModel, string> public class UserRepo(ISqlSugarClient db) : DefaultCurdRepo<UserModel, string>(db)
{ {
public UserModel Delete(string id) /// <summary>
{ /// 查询
throw new NotImplementedException(); /// </summary>
} /// <param name="whereObj"></param>
/// <returns></returns>
public UserModel Get(string id) /// <exception cref="NotImplementedException"></exception>
{ public override List<UserModel> Search(UserModel whereObj) => throw new NotImplementedException();
return new UserModel /// <summary>
{ /// 根据条件查询ID
UserID = id, /// </summary>
UserName = "Test User", /// <param name="whereObj"></param>
UserNickName = "Tester", /// <returns></returns>
EmailAddress = "Test@Ling.chat", /// <exception cref="NotImplementedException"></exception>
public override List<string> WhereSearchId(UserModel whereObj) => throw new NotImplementedException();
};
}
public UserModel SaveOrUpdate(UserModel entity, bool isUpdate)
{
throw new NotImplementedException();
}
public List<UserModel> Search(UserModel whereObj)
{
throw new NotImplementedException();
}
public List<string> WhereSearchId(UserModel whereObj)
{
throw new NotImplementedException();
}
} }

View File

@ -7,9 +7,9 @@ namespace LFlow.Base;
public class App public class App
{ {
public static IServiceCollection? services; public static IServiceCollection? services;
private static IServiceProvider? serviceProvider => services?.BuildServiceProvider(); private static IServiceProvider? ServiceProvider => services?.BuildServiceProvider();
public static T? GetService<T>() public static T? GetService<T>()
{ {
return serviceProvider.GetService<T>(); return ServiceProvider!.GetService<T>();
} }
} }

View File

@ -0,0 +1,40 @@
using System;
using System.Reflection;
using LFlow.Base.Interfaces;
namespace LFlow.Base.Default;
/// <summary>
/// 默认的CURD操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
public abstract class DefaultCurd<T, K> where T : IModel, IDataModel
{
private readonly IRepo<T, K> _repo;
public DefaultCurd(IRepo<T, K> repo)
{
_repo = repo;
}
public virtual T Add(T model)
{
return _repo.SaveOrUpdate(model, false);
}
public virtual int Delete(K id)
{
return _repo.Delete(id);
}
public virtual T Update(T model)
{
return _repo.SaveOrUpdate(model, true);
}
public virtual T Get(K id)
{
return _repo.Get(id);
}
public virtual List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal)
{
return _repo.GetAll(pageIndex, pageSize, ref pageTotal);
}
public abstract List<T> GetWhere(T WhereObject);
}

View File

@ -0,0 +1,50 @@
using System;
using LFlow.Base.Interfaces;
using SqlSugar;
namespace LFlow.Base.Default;
public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IDataModel, new()
{
private readonly ISqlSugarClient _client;
public DefaultCurdRepo(ISqlSugarClient client)
{
_client = client;
}
public virtual int Delete(K id)
{
if (Get(id) != null)
{
return _client.Deleteable<T>().In(id).ExecuteCommand();
}
else
{
throw new Exception("删除的对象不存在");
}
}
public virtual T Get(K id)
{
return _client.Queryable<T>().InSingle(id);
}
public List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal)
{
return _client.Queryable<T>().ToPageList(pageIndex, pageSize, ref pageTotal);
}
public virtual T SaveOrUpdate(T entity, bool isUpdate)
{
if (isUpdate)
{
_client.Updateable(entity).ExecuteCommand();
}
else
{
_client.Insertable(entity).ExecuteCommand();
}
return entity;
}
public abstract List<T> Search(T whereObj);
public abstract List<K> WhereSearchId(T whereObj);
}

View File

@ -0,0 +1,10 @@
using System;
namespace LFlow.Base.Interfaces;
/// <summary>
/// 模块接口
/// </summary>
public interface IModule
{
void ConfigureModule(IServiceCollection services);
}

View File

@ -20,13 +20,21 @@ public interface IRepo<T, K> where T : IDataModel
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
T Delete(K id); int Delete(K id);
/// <summary> /// <summary>
/// 保存与更新 /// 保存与更新
/// </summary> /// </summary>
/// <param name="entity"></param> /// <param name="entity"></param>
/// <returns></returns> /// <returns></returns>
T SaveOrUpdate(T entity, bool isUpdate); T SaveOrUpdate(T entity, bool isUpdate);
/// <summary>
/// 获取所有对象列表(默认分页)
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal);
/// <summary> /// <summary>
/// 根据条件搜索对象列表 /// 根据条件搜索对象列表
/// </summary> /// </summary>

BIN
LFlow/LFlow-dev.db Normal file

Binary file not shown.

View File

@ -1,4 +1,6 @@
using System.Reflection; using System.Reflection;
using LFlow.Base.Interfaces;
using LFlow.Base.Utils;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -56,7 +58,13 @@ public static class Program
}); });
}); });
builder.Host.UseSerilog(); builder.Host.UseSerilog((context, services, config) =>
{
config.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext();
// .WriteTo.Console();
}, true);
// init App.service // init App.service
App.services = builder.Services; App.services = builder.Services;
var app = builder.Build(); var app = builder.Build();
@ -74,6 +82,13 @@ public static class Program
u.DocumentTitle = "LFlow"; u.DocumentTitle = "LFlow";
}); });
} }
// 在启动后调用Sqlsugar进行CodeFirst
// 挂载启动后事件
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.Register(() =>
{
Log.Logger.Information("ApplicationStarted");
CodeFirst.InitTable();
});
app.Run(); app.Run();
} }
@ -99,6 +114,8 @@ public static class Program
Console.WriteLine($"{appServive?.HttpContext?.Request.Path}:{sql}\r\n{pars}"); Console.WriteLine($"{appServive?.HttpContext?.Request.Path}:{sql}\r\n{pars}");
}; };
}); });
sqlSugar.DbMaintenance.CreateDatabase();
return sqlSugar; return sqlSugar;
}); });
} }
@ -117,43 +134,27 @@ public static class Program
Log.Logger.Information($"Load file -> {file}..."); Log.Logger.Information($"Load file -> {file}...");
var assembly = Assembly.LoadFile(file); var assembly = Assembly.LoadFile(file);
var types = assembly.GetTypes(); var types = assembly.GetTypes();
bool isUseController = false; // bool isUseController = false;
foreach (var type in types) foreach (var type in types)
{ {
// Console.WriteLine(type); // Console.WriteLine(type);
if (type.IsClass && !type.IsAbstract) if (type.IsClass && !type.IsAbstract)
{ {
var interfaces = type.GetInterfaces(); var interfaces = type.GetInterfaces();
foreach (var inter in interfaces) if (interfaces.Contains(typeof(IModule)))
{ {
if (inter.Name.Contains("IRepo")) Log.Logger.Information($"\tFound IModule -> {type.FullName}");
{ var module = Activator.CreateInstance(type) as IModule;
//注册数据仓库 module.ConfigureModule(services);
services.AddScoped(inter, type);
}
if (inter.Name.Contains(type.Name))
{
//注册服务
services.AddScoped(inter, type);
}
if (inter.Name.Contains("IController"))
{
isUseController = true;
}
if (inter.Name.Equals("IDataModel"))
{
} }
} }
} }
} // if (isUseController)
if (isUseController) // {
{ // Log.Logger.Information($"\tAdd Controllers for {assembly.FullName}");
Log.Logger.Information($"\tAdd Controllers for {assembly.FullName}"); // // 添加Controller
// 添加Controller // services.AddControllers().AddApplicationPart(assembly);
services.AddControllers().AddApplicationPart(assembly); // }
}
Log.Logger.Information("done.\r\n"); Log.Logger.Information("done.\r\n");
} }
} }
@ -164,4 +165,6 @@ public static class Program
} }
} }
} }

View File

@ -1,25 +1,32 @@
using System; using System;
using System.Collections.Concurrent;
using System.Net; using System.Net;
using Serilog;
using SqlSugar;
namespace LFlow.Base.Utils; namespace LFlow.Base.Utils;
public static class CodeFirst public static class CodeFirst
{ {
private static List<Type> _tableTypes = new List<Type>(); // 线程安全的类型列表
private static readonly ConcurrentBag<Type> _types = new();
public static void AddType(Type type)
{
_types.Add(type);
}
internal static void InitTable()
{
var logger = App.GetService<Serilog.ILogger>()!;
var db = App.GetService<ISqlSugarClient>()!;
foreach (var type in _types)
{
db.CodeFirst.InitTables(type);
logger.Information($"Init table {type.Name} success");
}
}
internal static void RegisterTable(Type type) internal static void InitDBSeed()
{ {
if (_tableTypes.Contains(type)) //TODO: Seed data
{
return;
}
else
{
_tableTypes.Add(type);
}
}
internal static void DBSeed()
{
} }
} }

View File

@ -0,0 +1,67 @@
using System;
using LFlow.Base.Interfaces;
namespace LFlow.Base.Utils;
public static class RegisterModule
{
public static void RegisterAllModule(this List<Type> types, IServiceCollection services)
{
foreach (var type in types)
{
if (type.IsAbstract || !type.IsClass)
{
continue;
}
var interfaces = type.GetInterfaces();
foreach (var inter in interfaces)
{
if (inter.Name.Equals("IDataModel"))
{
services.AddScoped(inter, type);
}
}
}
}
public static void RegisterAllService(this List<Type> types, IServiceCollection services)
{
foreach (var type in types)
{
if (type.IsAbstract || !type.IsClass)
{
continue;
}
var interfaces = type.GetInterfaces();
foreach (var inter in interfaces)
{
if (inter.Name.Contains(type.Name) && inter.Name.StartsWith('I') && inter.Name.Contains("Service"))
{
//注册服务
services.AddScoped(inter, type);
}
}
}
}
public static void RegisterAllRepo(this List<Type> types, IServiceCollection services)
{
foreach (var type in types)
{
if (type.IsAbstract || !type.IsClass)
{
continue;
}
var interfaces = type.GetInterfaces();
foreach (var inter in interfaces)
{
if (inter.Name.Contains("IRepo"))
{
//注册数据仓库
services.AddScoped(inter, type);
}
}
}
}
}

View File

@ -14,5 +14,8 @@
} }
] ]
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Data Source=192.168.3.85;Initial Catalog=PluginAdmin-dev;User Id=sa;Password=Sa1234;Encrypt=True;TrustServerCertificate=True"
}
} }