24 private static bool initialized;
25 private static readonly
object _lock =
new object();
27 private static readonly Dictionary<string, PlugInInstance> plugInClasses =
new Dictionary<string, PlugInInstance>();
28 private static readonly Dictionary<string, List<PlugInInstance>> queuePlugInClasses =
new Dictionary<string, List<PlugInInstance>>();
43 LoadReferencedAssemblies();
52 [ExcludeFromCodeCoverage]
53 private static void LoadReferencedAssemblies()
55 var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
56 var loadedPaths = loadedAssemblies
57 .Where(a => !a.IsDynamic && !
string.IsNullOrEmpty(a.Location))
58 .Select(a => a.Location)
60 var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory,
"*.dll")
61 .Where(path => !loadedPaths.Contains(path, StringComparer.InvariantCultureIgnoreCase));
63 foreach (var path
in referencedPaths)
67 Assembly assembly = Assembly.Load(path);
68 RegisterPlugIns(assembly);
82 internal static void InjectPlugins(List<Type> pluginTypes)
87 IEnumerable<Type> replacingPluginTypes = pluginTypes
88 .Where(t => t.GetCustomAttribute<NanoXlsxPlugInAttribute>() !=
null);
91 IEnumerable<Type> queuePluginTypes = pluginTypes
92 .Where(t => t.GetCustomAttributes<NanoXlsxQueuePlugInAttribute>().Any());
95 HandleReplacingPlugIns(replacingPluginTypes);
96 HandleQueuePlugIns(queuePluginTypes);
105 internal static void DisposePlugins()
109 plugInClasses.Clear();
110 queuePlugInClasses.Clear();
119 [ExcludeFromCodeCoverage]
120 private static void RegisterPlugIns(Assembly assembly)
122 IEnumerable<Type> replacingPlugInTypes = GetAssemblyPlugInsByType(assembly, typeof(NanoXlsxPlugInAttribute));
123 IEnumerable<Type> queuePlugInTypes = GetAssemblyPlugInsByType(assembly, typeof(NanoXlsxQueuePlugInAttribute));
124 HandleReplacingPlugIns(replacingPlugInTypes);
125 HandleQueuePlugIns(queuePlugInTypes);
135 [ExcludeFromCodeCoverage]
136 private static List<Type> GetAssemblyPlugInsByType(Assembly assembly, Type attributeType)
138 List<Type> plugInTypes =
new List<Type>();
139 Type plugInInterface = typeof(IPlugIn);
140 Type[] allTypes = assembly.GetTypes();
142 for (
int i = 0; i < allTypes.Length; i++)
144 Type type = allTypes[i];
145 if (type.IsClass && !type.IsAbstract &&
146 plugInInterface.IsAssignableFrom(type) &&
147 type.GetCustomAttribute(attributeType) !=
null)
149 plugInTypes.Add(type);
159 [ExcludeFromCodeCoverage]
160 private static void HandleReplacingPlugIns(IEnumerable<Type> plugInTypes)
162 foreach (Type plugInType
in plugInTypes)
164 IEnumerable<NanoXlsxPlugInAttribute> attributes = plugInType.GetCustomAttributes<NanoXlsxPlugInAttribute>();
165 foreach (NanoXlsxPlugInAttribute attribute
in attributes)
167 if (plugInClasses.ContainsKey(attribute.
PlugInUUID))
175 else if (!plugInClasses.ContainsKey(attribute.
PlugInUUID))
187 private static void HandleQueuePlugIns(IEnumerable<Type> queuePlugInTypes)
189 foreach (Type plugInType
in queuePlugInTypes)
191 IEnumerable<NanoXlsxQueuePlugInAttribute> attributes = plugInType.GetCustomAttributes<NanoXlsxQueuePlugInAttribute>();
192 foreach (var attribute
in attributes)
194 if (!queuePlugInClasses.TryGetValue(attribute.QueueUUID, out var value))
196 value =
new List<PlugInInstance>();
197 queuePlugInClasses.Add(attribute.QueueUUID, value);
200 value.Add(
new PlugInInstance(attribute.PlugInUUID, attribute.PlugInOrder, plugInType));
204 foreach (KeyValuePair<
string, List<PlugInInstance>> entry
in queuePlugInClasses)
206 entry.Value.Sort((a, b) => a.Order.CompareTo(b.Order));
219 internal static T GetPlugIn<T>(
string plugInUUID, T fallBackInstance)
221 if (plugInClasses.TryGetValue(plugInUUID, out var plugIn))
223 return (T)Activator.CreateInstance(plugIn.Type);
227 return fallBackInstance;
241 internal static T GetNextQueuePlugIn<T>(
string queueUUID,
string lastPlugInUUID, out
string currentPlugInUUID)
243 if (queuePlugInClasses.TryGetValue(queueUUID, out var plugInList) && plugInList.Count > 0)
245 PlugInInstance plugIn =
null;
246 if (lastPlugInUUID ==
null)
248 plugIn = plugInList[0];
253 int index = plugInList.FindIndex(p => p.UUID == lastPlugInUUID);
254 if (index >= 0 && index + 1 < plugInList.Count)
256 plugIn = plugInList[index + 1];
261 currentPlugInUUID =
null;
264 currentPlugInUUID = plugIn.UUID;
265 return (T)Activator.CreateInstance(plugIn.Type);
269 currentPlugInUUID =
null;
277 private sealed class PlugInInstance
282 public string UUID {
get;
private set; }
286 public int Order {
get;
private set; }
291 public Type Type {
get;
private set; }
299 internal PlugInInstance(
string uuid,
int order, Type type)