#3136
[heuristiclab.git] / HeuristicLab.PluginInfrastructure / 3.3 / LightweightApplicationManager.cs
blob14770c74ba46fe1252078bcaaf4bd375c9f52f03
1 #region License Information
2 /* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 * This file is part of HeuristicLab.
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 #endregion
22 using System;
23 using System.Collections.Generic;
24 using System.Linq;
25 using System.Reflection;
27 namespace HeuristicLab.PluginInfrastructure {
29 /// <summary>
30 /// Lightweight application manager is set as the application manager as long as the plugin infrastructure is uninitialized.
31 /// The list of plugins and applications is empty. The default application manager is necessary to provide the type discovery
32 /// functionality in unit tests.
33 /// </summary>
34 internal sealed class LightweightApplicationManager : IApplicationManager {
35 internal LightweightApplicationManager() {
36 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
39 Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
40 return null;
44 #region IApplicationManager Members
45 /// <summary>
46 /// Gets an empty list of plugins. (LightweightApplicationManager doesn't support plugin discovery)
47 /// </summary>
48 public IEnumerable<IPluginDescription> Plugins {
49 get { return new IPluginDescription[0]; }
52 /// <summary>
53 /// Gets an empty list of applications. (LightweightApplicationManager doesn't support application discovery)
54 /// </summary>
55 public IEnumerable<IApplicationDescription> Applications {
56 get { return new IApplicationDescription[0]; }
59 /// <summary>
60 /// Creates an instance of all types that are subtypes or the same type of the specified type
61 /// </summary>
62 /// <typeparam name="T">Most general type.</typeparam>
63 /// <returns>Enumerable of the created instances.</returns>
64 public IEnumerable<T> GetInstances<T>() where T : class {
65 return GetInstances(typeof(T)).Cast<T>();
68 /// <summary>
69 /// Creates an instance of all types that are subtypes or the same type of the specified type
70 /// </summary>
71 /// <param name="type">Most general type.</param>
72 /// <returns>Enumerable of the created instances.</returns>
73 public IEnumerable<object> GetInstances(Type type) {
74 List<object> instances = new List<object>();
75 foreach (Type t in GetTypes(type)) {
76 object instance = null;
77 try { instance = Activator.CreateInstance(t); }
78 catch { }
79 if (instance != null) instances.Add(instance);
81 return instances;
84 /// <summary>
85 /// Finds all instantiable types that are subtypes or equal to the specified types.
86 /// </summary>
87 /// <param name="types">Most general types for which to find matching types.</param>
88 /// <remarks>Return only types that are instantiable
89 /// (interfaces, abstract classes... are not returned)</remarks>
90 /// <param name="includeGenericTypeDefinitions">Specifies if generic type definitions shall be included</param>
91 /// <returns>Enumerable of the discovered types.</returns>
92 public IEnumerable<Type> GetTypes(IEnumerable<Type> types, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) {
93 IEnumerable<Type> result = GetTypes(types.First(), onlyInstantiable, includeGenericTypeDefinitions);
94 foreach (Type type in types.Skip(1)) {
95 IEnumerable<Type> discoveredTypes = GetTypes(type, onlyInstantiable, includeGenericTypeDefinitions);
96 if (assignableToAllTypes) result = result.Intersect(discoveredTypes);
97 else result = result.Union(discoveredTypes);
99 return result;
102 /// <summary>
103 /// Finds all types that are subtypes or equal to the specified type.
104 /// </summary>
105 /// <param name="type">Most general type for which to find matching types.</param>
106 /// <param name="onlyInstantiable">Return only types that are instantiable
107 /// (interfaces, abstract classes... are not returned)</param>
108 /// <param name="includeGenericTypeDefinitions">Specifies if generic type definitions shall be included</param>
109 /// <returns>Enumerable of the discovered types.</returns>
110 public IEnumerable<Type> GetTypes(Type type, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) {
111 return from asm in AppDomain.CurrentDomain.GetAssemblies()
112 from t in GetTypes(type, asm, onlyInstantiable, includeGenericTypeDefinitions)
113 select t;
116 /// <summary>
117 /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.
118 /// </summary>
119 /// <param name="type">Most general type we want to find.</param>
120 /// <param name="assembly">Assembly that should be searched for types.</param>
121 /// <param name="onlyInstantiable">Return only types that are instantiable
122 /// (interfaces, abstract classes... are not returned)</param>
123 /// <returns>Enumerable of the discovered types.</returns>
124 public IEnumerable<Type> GetTypes(Type type, Assembly assembly, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) {
125 try {
126 // necessary to make sure the exception is immediately thrown
127 // instead of later when the enumerable is iterated?
128 var assemblyTypes = assembly.GetTypes();
130 var matchingTypes = from assemblyType in assembly.GetTypes()
131 let t = assemblyType.BuildType(type)
132 where t != null
133 where t.IsSubTypeOf(type)
134 where !t.IsNonDiscoverableType()
135 where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
136 where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition
137 select t;
139 return matchingTypes;
141 catch (TypeLoadException) {
142 return Enumerable.Empty<Type>();
144 catch (ReflectionTypeLoadException) {
145 return Enumerable.Empty<Type>();
149 /// <summary>
150 /// Discovers all types implementing or inheriting all or any type in <paramref name="types"/> (directly and indirectly) that are declared in the assembly <paramref name="assembly"/>.
151 /// </summary>
152 /// <param name="types">The types to discover.</param>
153 /// <param name="assembly">The declaring assembly.</param>
154 /// <param name="onlyInstantiable">Return only types that are instantiable (instance, abstract... are not returned)</param>
155 /// /// <param name="assignableToAllTypes">Specifies if discovered types must implement or inherit all given <paramref name="types"/>.</param>
156 /// <returns>An enumerable of discovered types.</returns>
157 public IEnumerable<Type> GetTypes(IEnumerable<Type> types, Assembly assembly, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) {
158 IEnumerable<Type> result = GetTypes(types.First(), assembly, onlyInstantiable, includeGenericTypeDefinitions);
159 foreach (Type type in types.Skip(1)) {
160 IEnumerable<Type> discoveredTypes = GetTypes(type, assembly, onlyInstantiable, includeGenericTypeDefinitions);
161 if (assignableToAllTypes) result = result.Intersect(discoveredTypes);
162 else result = result.Union(discoveredTypes);
164 return result;
167 /// <summary>
168 /// Not supported by the LightweightApplicationManager
169 /// </summary>
170 /// <param name="type"></param>
171 /// <param name="plugin"></param>
172 /// <returns></returns>
173 /// <throws>NotSupportedException</throws>
174 public IEnumerable<Type> GetTypes(Type type, IPluginDescription plugin) {
175 throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins.");
178 /// <summary>
179 /// Not supported by the LightweightApplicationManager
180 /// </summary>
181 /// <param name="type"></param>
182 /// <param name="plugin"></param>
183 /// <param name="onlyInstantiable"></param>
184 /// <param name="includeGenericTypeDefinitions"></param>
185 /// <returns></returns>
186 /// <throws>NotSupportedException</throws>
187 public IEnumerable<Type> GetTypes(Type type, IPluginDescription plugin, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) {
188 throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins.");
191 /// <summary>
192 /// Not supported by the LightweightApplicationManager
193 /// </summary>
194 /// <param name="type"></param>
195 /// <param name="plugin"></param>
196 /// <param name="onlyInstantiable"></param>
197 /// <param name="includeGenericTypeDefinitions"></param>
198 /// <returns></returns>
199 /// <throws>NotSupportedException</throws>
200 public IEnumerable<Type> GetTypes(IEnumerable<Type> types, IPluginDescription plugin, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) {
201 throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins.");
204 /// <summary>
205 /// Not supported by the LightweightApplicationManager
206 /// </summary>
207 /// <param name="type"></param>
208 /// <returns></returns>
209 /// <throws>NotSupportedException</throws>
210 public IPluginDescription GetDeclaringPlugin(Type type) {
211 throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins.");
214 #endregion