-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathXStartup.cs
More file actions
137 lines (117 loc) · 4.06 KB
/
XStartup.cs
File metadata and controls
137 lines (117 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Inkslab
{
/// <summary>
/// 启动。
/// </summary>
public class XStartup : IDisposable
{
private readonly List<Type> _types;
private static readonly HashSet<Type> _startupCachings = new HashSet<Type>();
private static readonly Type _startupType = typeof(IStartup);
/// <summary>
/// 启动(获取所有DLL的类型启动)<see cref="AssemblyFinder.FindAll()"/>。
/// </summary>
public XStartup() : this(AssemblyFinder.FindAll())
{
}
/// <summary>
/// 启动(满足指定条件的程序集)<see cref="AssemblyFinder.Find(string)"/>。
/// </summary>
/// <param name="pattern">DLL过滤规则。</param>
public XStartup(string pattern) : this(AssemblyFinder.Find(pattern))
{
}
/// <summary>
/// 启动(满足指定条件的程序集)<see cref="AssemblyFinder.Find(string[])"/>。
/// </summary>
/// <param name="patterns">DLL过滤规则。<see cref="Directory.GetFiles(string, string)"/></param>
public XStartup(params string[] patterns) : this(AssemblyFinder.Find(patterns))
{
}
/// <summary>
/// 启动(获取指定程序集的所有类型启动)。
/// </summary>
/// <param name="assemblies">程序集集合。</param>
public XStartup(IEnumerable<Assembly> assemblies) : this(assemblies.SelectMany(x => x.GetTypes()))
{
}
/// <summary>
/// 启动(指定类型启动)。
/// </summary>
/// <param name="types">类型集合。</param>
public XStartup(IEnumerable<Type> types)
{
if (types is null)
{
throw new ArgumentNullException(nameof(types));
}
_types = types.Where(x => x.IsClass && !x.IsAbstract && _startupType.IsAssignableFrom(x)).ToList();
}
/// <summary>
/// 执行启动项。
/// </summary>
public void DoStartup()
{
// 启动配置类不考虑并发场景;在反射实例化之前过滤掉已启动的类型,避免无效的 Activator.CreateInstance 开销。
var startups = new List<IStartup>(_types.Count);
foreach (var type in _types)
{
if (_startupCachings.Contains(type))
{
continue;
}
startups.Add((IStartup)Activator.CreateInstance(type, true));
}
if (startups.Count == 0)
{
return;
}
foreach (var group in startups.GroupBy(x => x.Code).OrderBy(x => x.Key))
{
foreach (IStartup startup in group.OrderByDescending(y => y.Weight))
{
if (ToStartup(startup))
{
if (_startupCachings.Add(startup.GetType()))
{
startup.Startup();
}
break;
}
}
}
}
/// <summary>
/// 支持启动。
/// </summary>
/// <param name="startup">启动类型。</param>
/// <returns></returns>
protected virtual bool ToStartup(IStartup startup) => true;
#region IDisposable Support
private bool disposedValue; // 要检测冗余调用
/// <summary>
/// 是否资源。
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing && !disposedValue)
{
_types.Clear();
disposedValue = true;
}
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}