diff --git a/src/dotnetCampus.ApplicationStartupManager/IStartupContext.cs b/src/dotnetCampus.ApplicationStartupManager/IStartupContext.cs
index 60978b3..71e79e6 100644
--- a/src/dotnetCampus.ApplicationStartupManager/IStartupContext.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/IStartupContext.cs
@@ -1,12 +1,18 @@
using System.Threading.Tasks;
-//using dotnetCampus.Configurations;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 表示启动任务的上下文接口
+ ///
public interface IStartupContext
{
- //IAppConfigurator Configs { get; }
- //Task ReadCacheAsync(string key, string @default = "");
+ ///
+ /// 等待某个启动任务完成
+ ///
+ ///
+ ///
+ /// 这是框架层需要支持的能力,因此也就放在此
Task WaitStartupTaskAsync(string startupKey);
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/IStartupLogger.cs b/src/dotnetCampus.ApplicationStartupManager/IStartupLogger.cs
index cb1ef2d..e06d317 100644
--- a/src/dotnetCampus.ApplicationStartupManager/IStartupLogger.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/IStartupLogger.cs
@@ -4,10 +4,27 @@ using System.Threading.Tasks;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动模块的日志
+ ///
public interface IStartupLogger
{
+ ///
+ /// 打点某个里程碑,将会自动与上个里程碑记录时间差
+ ///
+ ///
void RecordTime(string milestoneName);
+ ///
+ /// 记录某个任务的耗时情况
+ ///
+ ///
+ ///
+ ///
Task RecordDuration(string taskName, Func> task);
+ ///
+ /// 上报启动结果
+ ///
+ ///
void ReportResult(IReadOnlyList wrappers);
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/IStartupManager.cs b/src/dotnetCampus.ApplicationStartupManager/IStartupManager.cs
index d6e4c09..8f92364 100644
--- a/src/dotnetCampus.ApplicationStartupManager/IStartupManager.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/IStartupManager.cs
@@ -2,10 +2,24 @@
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动流程管理器
+ ///
public interface IStartupManager
{
+ ///
+ /// 等待某个启动项的完成
+ ///
+ ///
+ ///
Task WaitStartupTaskAsync(string startupTaskKey);
+ ///
+ /// 获取指定类型的启动项
+ ///
+ ///
+ ///
+ /// 理论上相同的类型的启动项不会被重复加入,基本都是一个启动项一个类型
StartupTaskBase GetStartupTask() where T : StartupTaskBase;
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/IStartupTaskWrapper.cs b/src/dotnetCampus.ApplicationStartupManager/IStartupTaskWrapper.cs
index 36d68a4..56f9e10 100644
--- a/src/dotnetCampus.ApplicationStartupManager/IStartupTaskWrapper.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/IStartupTaskWrapper.cs
@@ -2,11 +2,26 @@
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动项在启动框架的信息
+ ///
public interface IStartupTaskWrapper
{
+ ///
+ /// 跟随等待着当前启动项的其他启动项
+ ///
HashSet FollowTasks { get; }
+ ///
+ /// 当前启动项所依赖的其他启动项
+ ///
HashSet Dependencies { get; }
+ ///
+ /// 当前启动项的标识
+ ///
string StartupTaskKey { get; }
+ ///
+ /// 表示当前启动项是否只能在 UI 线程启动
+ ///
bool UIOnly { get; }
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/IStartupValueProvider.cs b/src/dotnetCampus.ApplicationStartupManager/IStartupValueProvider.cs
index 920c2f4..a59c7f2 100644
--- a/src/dotnetCampus.ApplicationStartupManager/IStartupValueProvider.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/IStartupValueProvider.cs
@@ -1,7 +1,15 @@
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 用于启动项里的值提供器,用于多个启动项之间传递参数
+ ///
+ ///
public interface IStartupValueProvider
{
+ ///
+ /// 获取启动项提供的值
+ ///
+ ///
T ProvideValue();
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/NullObjectStartup.cs b/src/dotnetCampus.ApplicationStartupManager/NullObjectStartup.cs
index f9d4409..70ec3c2 100644
--- a/src/dotnetCampus.ApplicationStartupManager/NullObjectStartup.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/NullObjectStartup.cs
@@ -1,5 +1,8 @@
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 一个表示空白的启动项
+ ///
internal sealed class NullObjectStartup : StartupTaskBase
{
diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupContext.cs b/src/dotnetCampus.ApplicationStartupManager/StartupContext.cs
index 50da798..1faea1f 100644
--- a/src/dotnetCampus.ApplicationStartupManager/StartupContext.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/StartupContext.cs
@@ -1,36 +1,26 @@
using System;
using System.Threading.Tasks;
-//using dotnetCampus.Configurations;
-//using dotnetCampus.Configurations.Core;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动项的上下文信息,业务方可以自己再定义而不需要使用此类型
+ ///
internal class StartupContext : IStartupContext
{
public IStartupLogger Logger { get; }
- //public FileConfigurationRepo Configuration { get; }
-
- //public IAppConfigurator Configs { get; }
-
public Func FastFail { get; }
private readonly Func _waitStartupTaskAsync;
- //public Task ReadCacheAsync(string key, string @default = "")
- //{
- // return Configuration.TryReadAsync(key, @default);
- //}
-
Task IStartupContext.WaitStartupTaskAsync(string startupKey) => _waitStartupTaskAsync(startupKey);
public StartupContext(IStartupLogger logger, /*FileConfigurationRepo configuration,*/
Func fastFailAction, Func waitStartupAsync)
{
Logger = logger;
- //Configuration = configuration;
_waitStartupTaskAsync = waitStartupAsync;
- //Configs = configuration.CreateAppConfigurator();
FastFail = fastFailAction ?? (exception => StartupTaskBase.CompletedTask);
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupLogger.cs b/src/dotnetCampus.ApplicationStartupManager/StartupLogger.cs
index 5ca1d36..8c69d2c 100644
--- a/src/dotnetCampus.ApplicationStartupManager/StartupLogger.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/StartupLogger.cs
@@ -9,20 +9,36 @@ using System.Threading.Tasks;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 表示启动任务的基础日志,推荐业务方提供更贴合业务的日志,和日志记录的方法
+ ///
public class StartupLoggerBase : IStartupLogger
{
private readonly Stopwatch _mainWatch;
+ ///
+ /// 各个启动的里程碑的信息,包括里程碑的所运行的线程名,启动时间和执行时间
+ ///
+ /// Key: 启动的里程碑名
+ ///
+ ///
+ /// Value: 启动的信息,包括里程碑的所运行的线程名,启动时间和执行时间。时间都是从 获取
+ ///
+ ///
protected ConcurrentDictionary
MilestoneDictionary
{ get; } = new ConcurrentDictionary();
+ ///
+ /// 创建启动任务的基础日志,此日志的核心功能就是监控启动项的启动时间
+ ///
public StartupLoggerBase()
{
_mainWatch = new Stopwatch();
_mainWatch.Start();
}
+ ///
public void RecordTime(string milestoneName)
{
var start = MilestoneDictionary.Count > 0
@@ -34,6 +50,7 @@ namespace dotnetCampus.ApplicationStartupManager
start, end - start);
}
+ ///
public async Task RecordDuration(string taskName, Func> task)
{
var threadName = "null";
@@ -51,8 +68,10 @@ namespace dotnetCampus.ApplicationStartupManager
}
}
+ ///
public virtual void ReportResult(IReadOnlyList wrappers)
{
+ // 没有实际的可以记录的地方,需要业务方自己实现记录到哪
}
}
}
diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupManagerBase.cs b/src/dotnetCampus.ApplicationStartupManager/StartupManagerBase.cs
index 1b40517..70c4043 100644
--- a/src/dotnetCampus.ApplicationStartupManager/StartupManagerBase.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/StartupManagerBase.cs
@@ -9,15 +9,16 @@ using System.Threading.Tasks;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动任务管理器,这是此框架的入口
+ ///
+ /// 期望业务方自己再基于此类型继续实现自己的业务逻辑,例如注入业务方需要的日志模块,以及构建启动任务上下文
+ ///
+ ///
public class StartupManagerBase : IStartupManager
{
private readonly IMainThreadDispatcher _dispatcher;
- /////
- ///// Builder 模式所需状态:包含当前剩余需要管理的启动任务程序集。
- /////
- //private readonly List _assembliesToBeManaged = new List();
-
///
/// Builder 模式所需状态:包含当前所有的关键启动任务。
///
@@ -42,10 +43,25 @@ namespace dotnetCampus.ApplicationStartupManager
private List? Graph { get; set; }
private StartupContext Context { get; }
+
+ ///
+ /// 获取启动任务上下文信息
+ ///
protected IStartupContext StartupContext => Context;
+ ///
+ /// 获取启动任务日志
+ ///
protected IStartupLogger Logger => Context.Logger;
+ ///
+ /// 创建启动任务管理器
+ ///
+ /// 启动项的日志记录器
+ /// 启动过程存在失败时需要执行的逻辑,也就是说此委托被框架执行时,将应该记录失败然后退出应用
+ /// 传入线程调度器,需要业务方自己实现
+ /// 是否需要在进入启动框架时,让框架设置线程池的线程数
+ ///
public StartupManagerBase(IStartupLogger logger, /*FileConfigurationRepo configurationRepo,*/
Func fastFailAction, IMainThreadDispatcher dispatcher, bool shouldSetThreadPool = true)
{
@@ -213,12 +229,20 @@ namespace dotnetCampus.ApplicationStartupManager
// return this;
//}
+ ///
+ /// 加入构建预设启动项
+ ///
+ ///
+ ///
public StartupManagerBase ForStartupTasksOfCategory(Action taskBuilder)
{
_additionalBuilders.Add(taskBuilder);
return this;
}
+ ///
+ /// 启动框架,开始执行应用程序的启动流程
+ ///
public async void Run()
{
if (Graph == null)
@@ -352,6 +376,10 @@ namespace dotnetCampus.ApplicationStartupManager
}
}
+ ///
+ /// 导出所有的启动任务项,可以给子类继承,用于让子类定制获取启动任务项的方法
+ ///
+ ///
protected virtual IEnumerable ExportStartupTasks()
{
foreach (var func in _startupTaskMetadataCollectorList)
@@ -444,6 +472,7 @@ namespace dotnetCampus.ApplicationStartupManager
throw new InvalidOperationException($"{startupTaskKey}既无法添加至字典,也无法从字典获取对应值");
}
+ ///
public Task WaitStartupTaskAsync(string startupTaskKey)
=> GetStartupTaskWrapper(startupTaskKey).TaskBase.TaskResult;
@@ -453,6 +482,13 @@ namespace dotnetCampus.ApplicationStartupManager
private static string StartupTypeToKey(Type type)
=> type.Name.Remove(type.Name.Length - "startup".Length);
+ ///
+ /// 实际执行某个具体的启动任务项的函数,可以给子类继承,用来控制具体的启动任务项执行逻辑
+ ///
+ ///
+ ///
+ ///
+ ///
protected internal virtual Task ExecuteStartupTaskAsync(StartupTaskBase startupTask, IStartupContext context, bool uiOnly)
{
return startupTask.JoinAsync(context, uiOnly);
diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupTaskAttribute.cs b/src/dotnetCampus.ApplicationStartupManager/StartupTaskAttribute.cs
index cd17dac..3c61633 100644
--- a/src/dotnetCampus.ApplicationStartupManager/StartupTaskAttribute.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/StartupTaskAttribute.cs
@@ -1,8 +1,10 @@
using System;
-using System.Diagnostics.CodeAnalysis;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动任务的特性,可以让业务方用来对接,如对接预编译框架,从而收集启动任务项
+ ///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class StartupTaskAttribute : Attribute
{
diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupTaskBase.cs b/src/dotnetCampus.ApplicationStartupManager/StartupTaskBase.cs
index bb642e7..923a9d4 100644
--- a/src/dotnetCampus.ApplicationStartupManager/StartupTaskBase.cs
+++ b/src/dotnetCampus.ApplicationStartupManager/StartupTaskBase.cs
@@ -4,10 +4,22 @@ using System.Threading.Tasks;
namespace dotnetCampus.ApplicationStartupManager
{
+ ///
+ /// 启动任务项的基类型
+ ///
public abstract class StartupTaskBase
{
- // 由于我们都在编译期间收集 Attribute 了,当然也能收集使用方到底重写了哪个 Run。
- // 这里传入的 isUIOnly 就是编译期间收集的那个属性。
+ ///
+ /// 将当前启动任务项加入执行
+ ///
+ ///
+ /// 此函数由启动框架调用
+ ///
+ ///
+ ///
+ ///
+ /// 由于我们都在编译期间收集 Attribute 了,当然也能收集使用方到底重写了哪个 Run。
+ /// 这里传入的 isUIOnly 就是编译期间收集的那个属性。
public async Task JoinAsync(IStartupContext context, bool isUIOnly)
{
// 决定执行 Run 还是 RunAsync。
@@ -44,11 +56,19 @@ namespace dotnetCampus.ApplicationStartupManager
}
}
+ ///
+ /// 启动任务项的实际执行逻辑,由子类继承,实现启动任务项业务逻辑
+ ///
+ ///
+ ///
protected virtual Task RunAsync(IStartupContext context)
{
return CompletedTask;
}
+ ///
+ /// 一个表示执行完成的任务,可以在 作为返回值
+ ///
protected internal static Task CompletedTask =>
#if NETFRAMEWORK
CompletedCommonTask;
@@ -59,6 +79,9 @@ namespace dotnetCampus.ApplicationStartupManager
Task.CompletedTask;
#endif
+ ///
+ /// 获取当前启动任务项可等待任务
+ ///
public Task TaskResult => CompletedSource.Task;
private TaskCompletionSource