diff --git a/src/Token.Module/Attributes/RunOrderAttribute.cs b/src/Token.Module/Attributes/RunOrderAttribute.cs new file mode 100644 index 0000000000000000000000000000000000000000..a2ab38ddc46d3e5a74c84e8b6c6948cd8c3b32ec --- /dev/null +++ b/src/Token.Module/Attributes/RunOrderAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Token.Module.Attributes; + + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class RunOrderAttribute :Attribute +{ + public int Order; + + public RunOrderAttribute(int order) + { + Order = order; + } +} \ No newline at end of file diff --git a/src/Token.Module/Extensions/DependencyExtensions.cs b/src/Token.Module/Extensions/DependencyExtensions.cs index eb6a862406ab927daeb67d16939310c98b85105c..95ad787bac9951ddcc2a3038bb614f79ab6c2d4a 100644 --- a/src/Token.Module/Extensions/DependencyExtensions.cs +++ b/src/Token.Module/Extensions/DependencyExtensions.cs @@ -7,7 +7,7 @@ namespace Token.Module.Extensions; public static class DependencyExtensions { - public static void AddAutoInject(this IServiceCollection services, List tokenModules) + public static void AddAutoInject(this IServiceCollection services, IEnumerable tokenModules) { var assemblies = tokenModules.Select(x => x.GetType().Assembly).Distinct() .SelectMany(x => x.GetTypes()); diff --git a/src/Token.Module/Extensions/ServiceCollectionApplicationExtensions.cs b/src/Token.Module/Extensions/ServiceCollectionApplicationExtensions.cs index be7b5107b0d3dca0f32077b8b79885a997b6ab57..0b1e5c9963c583930021051ce70f8506c098ca81 100644 --- a/src/Token.Module/Extensions/ServiceCollectionApplicationExtensions.cs +++ b/src/Token.Module/Extensions/ServiceCollectionApplicationExtensions.cs @@ -11,69 +11,99 @@ namespace Token.Module.Extensions; public static class ServiceCollectionApplicationExtensions { + /// + /// 默认运行顺序 + /// + private static int _defaultOrder = 1; + + public static void SetDefaultOrder(int order) + { + _defaultOrder = order; + } + /// /// 初始化Service /// /// /// 是否自动依赖注入 /// - public static async Task AddTagApplication(this IServiceCollection services,bool isAutoInject=true) where TModule : ITokenModule + public static async Task AddModuleApplication(this IServiceCollection services, bool isAutoInject = true) + where TModule : ITokenModule { - var types = new List(); + var types = new List>(); var type = typeof(TModule); await GetModuleTypeAsync(type, types); - foreach (var t in types.Distinct()) + var modules = types.OrderBy(x => x.Item2).Select(x => x.Item1).Distinct(); + + var tokenModules = modules as ITokenModule[] ?? modules.ToArray(); + if (isAutoInject) + { + services.AddAutoInject(tokenModules); + } + + + foreach (var t in tokenModules) { await t.ConfigureServicesAsync(services); } - + services.AddSingleton(types); - if (isAutoInject) + } + + /// + /// 初始化Application + /// + /// + public static void InitializeApplication(this IApplicationBuilder app) + { + var types = app.ApplicationServices.GetService>>(); + + var modules = types?.OrderBy(x => x.Item2).Select(x => x.Item1); + + if (modules == null) + return; + + async void Action(ITokenModule x) => await x.OnApplicationShutdownAsync(app); + + foreach (var module in modules) { - services.AddAutoInject(types); + Action(module); } } - private static async Task GetModuleTypeAsync(Type type,List types) + private static async Task GetModuleTypeAsync(Type type, ICollection> types) { var iTokenModule = typeof(ITokenModule); if (!iTokenModule.IsAssignableFrom(type)) { return; } + // 通过放射创建一个对象并且回调方法 ITokenModule typeInstance = type.Assembly.CreateInstance(type.FullName, true) as ITokenModule; - if (typeInstance != null) types.Add(typeInstance); + if (typeInstance != null) types.Add(new Tuple(typeInstance, GetRunOrder(type))); // 获取DependOn特性注入的模块 var attributes = type.GetCustomAttributes().OfType() - .SelectMany(x => x.Type).Where(x=>iTokenModule.IsAssignableFrom(x)); - + .SelectMany(x => x.Type).Where(x => iTokenModule.IsAssignableFrom(x)); foreach (var t in attributes) { - ITokenModule module = t.Assembly.CreateInstance(t?.FullName, true) as ITokenModule; - if(module==null) + ITokenModule? module = t.Assembly.CreateInstance(t?.FullName, true) as ITokenModule; + if (module == null) continue; - types.Add(module); // 可能存在循环依赖的问题 await GetModuleTypeAsync(t, types); } } - - /// - /// 初始化Application - /// - /// - public static void InitializeApplication(this IApplicationBuilder app) - { - var tag = app.ApplicationServices.GetService>(); - async void Action(ITokenModule x) => await x.OnApplicationShutdownAsync(app); + private static int GetRunOrder(Type type) + { + var runOrder = type.GetCustomAttribute(); - tag.ForEach(Action); + return runOrder?.Order ?? _defaultOrder++; } } \ No newline at end of file diff --git a/src/Token.Module/ITokenModule.cs b/src/Token.Module/ITokenModule.cs index d817be1eefc4c5a53902f4e064ca7d63b21a61a1..f244362b35c843ca68286bf6b1f09ba645d61540 100644 --- a/src/Token.Module/ITokenModule.cs +++ b/src/Token.Module/ITokenModule.cs @@ -9,7 +9,7 @@ public interface ITokenModule Task ConfigureServicesAsync(IServiceCollection services); void ConfigureServices(IServiceCollection services); - + Task OnApplicationShutdownAsync(IApplicationBuilder app); void OnApplicationShutdown(IApplicationBuilder app); diff --git a/src/Token.Module/Token.Module.csproj b/src/Token.Module/Token.Module.csproj index 34870dece84ad0dbc7e89860246c1a15912febe1..626cd1a62bb3b110f8c989b95acdfb429aff0525 100644 --- a/src/Token.Module/Token.Module.csproj +++ b/src/Token.Module/Token.Module.csproj @@ -10,9 +10,9 @@ true https://github.com/239573049/token-module https://github.com/239573049/token-module - 修复子模块未依赖问题 + 新增模块执行顺序实现 logo.png - 1.1.8 + 1.2.0 diff --git a/src/Token.Module/TokenModule.cs b/src/Token.Module/TokenModule.cs index 1e1df13f363a09275850913fab07ee591d6852b9..7248950bbd314ca82af646f5cc75c6cd4f7116c9 100644 --- a/src/Token.Module/TokenModule.cs +++ b/src/Token.Module/TokenModule.cs @@ -8,7 +8,7 @@ namespace Token.Module; public abstract class TokenModule : ITokenModule { private IServiceCollection _serviceCollection; - + public virtual Task ConfigureServicesAsync(IServiceCollection services) { _serviceCollection = services; diff --git a/test/NetCore.Domain/NetCoreDomainModule.cs b/test/NetCore.Domain/NetCoreDomainModule.cs index fc35f821f55602933209ee50f120ef710d3afef4..5a6d46ba46335429877e7147ded6a34aa6f5f592 100644 --- a/test/NetCore.Domain/NetCoreDomainModule.cs +++ b/test/NetCore.Domain/NetCoreDomainModule.cs @@ -3,6 +3,8 @@ using Token.Module.Attributes; namespace NetCore.Domain; +[RunOrder(1)] +[DependOn] public class NetCoreDomainModule : TokenModule { } \ No newline at end of file diff --git a/test/NetCoreTest/Program.cs b/test/NetCoreTest/Program.cs index d68e3f1ed3ebf5459e1347db0dc910473bd8a355..372c72645ed5d4ab7921aa42fe8f3211bfa778d4 100644 --- a/test/NetCoreTest/Program.cs +++ b/test/NetCoreTest/Program.cs @@ -4,7 +4,7 @@ using NetCoreTest; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); -builder.Services.AddTagApplication(); +builder.Services.AddModuleApplication(); var app = builder.Build(); app.InitializeApplication();