1 #region License Information
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/>.
23 using System
.Collections
.Generic
;
25 using System
.Reflection
;
27 namespace HeuristicLab
.PluginInfrastructure
{
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.
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
) {
44 #region IApplicationManager Members
46 /// Gets an empty list of plugins. (LightweightApplicationManager doesn't support plugin discovery)
48 public IEnumerable
<IPluginDescription
> Plugins
{
49 get { return new IPluginDescription[0]; }
53 /// Gets an empty list of applications. (LightweightApplicationManager doesn't support application discovery)
55 public IEnumerable
<IApplicationDescription
> Applications
{
56 get { return new IApplicationDescription[0]; }
60 /// Creates an instance of all types that are subtypes or the same type of the specified type
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
>();
69 /// Creates an instance of all types that are subtypes or the same type of the specified type
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); }
79 if (instance
!= null) instances
.Add(instance
);
85 /// Finds all instantiable types that are subtypes or equal to the specified types.
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
);
103 /// Finds all types that are subtypes or equal to the specified type.
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
)
117 /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.
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) {
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
)
133 where t
.IsSubTypeOf(type
)
134 where
!t
.IsNonDiscoverableType()
135 where onlyInstantiable
== false || (!t
.IsAbstract
&& !t
.IsInterface
&& !t
.HasElementType
)
136 where includeGenericTypeDefinitions
|| !t
.IsGenericTypeDefinition
139 return matchingTypes
;
141 catch (TypeLoadException
) {
142 return Enumerable
.Empty
<Type
>();
144 catch (ReflectionTypeLoadException
) {
145 return Enumerable
.Empty
<Type
>();
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"/>.
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
);
168 /// Not supported by the LightweightApplicationManager
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.");
179 /// Not supported by the LightweightApplicationManager
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.");
192 /// Not supported by the LightweightApplicationManager
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.");
205 /// Not supported by the LightweightApplicationManager
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.");