#region License Information /* HeuristicLab * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace HeuristicLab.PluginInfrastructure { /// /// Lightweight application manager is set as the application manager as long as the plugin infrastructure is uninitialized. /// The list of plugins and applications is empty. The default application manager is necessary to provide the type discovery /// functionality in unit tests. /// internal sealed class LightweightApplicationManager : IApplicationManager { internal LightweightApplicationManager() { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { return null; } #region IApplicationManager Members /// /// Gets an empty list of plugins. (LightweightApplicationManager doesn't support plugin discovery) /// public IEnumerable Plugins { get { return new IPluginDescription[0]; } } /// /// Gets an empty list of applications. (LightweightApplicationManager doesn't support application discovery) /// public IEnumerable Applications { get { return new IApplicationDescription[0]; } } /// /// Creates an instance of all types that are subtypes or the same type of the specified type /// /// Most general type. /// Enumerable of the created instances. public IEnumerable GetInstances() where T : class { return GetInstances(typeof(T)).Cast(); } /// /// Creates an instance of all types that are subtypes or the same type of the specified type /// /// Most general type. /// Enumerable of the created instances. public IEnumerable GetInstances(Type type) { List instances = new List(); foreach (Type t in GetTypes(type)) { object instance = null; try { instance = Activator.CreateInstance(t); } catch { } if (instance != null) instances.Add(instance); } return instances; } /// /// Finds all instantiable types that are subtypes or equal to the specified types. /// /// Most general types for which to find matching types. /// Return only types that are instantiable /// (interfaces, abstract classes... are not returned) /// Specifies if generic type definitions shall be included /// Enumerable of the discovered types. public IEnumerable GetTypes(IEnumerable types, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) { IEnumerable result = GetTypes(types.First(), onlyInstantiable, includeGenericTypeDefinitions); foreach (Type type in types.Skip(1)) { IEnumerable discoveredTypes = GetTypes(type, onlyInstantiable, includeGenericTypeDefinitions); if (assignableToAllTypes) result = result.Intersect(discoveredTypes); else result = result.Union(discoveredTypes); } return result; } /// /// Finds all types that are subtypes or equal to the specified type. /// /// Most general type for which to find matching types. /// Return only types that are instantiable /// (interfaces, abstract classes... are not returned) /// Specifies if generic type definitions shall be included /// Enumerable of the discovered types. public IEnumerable GetTypes(Type type, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) { return from asm in AppDomain.CurrentDomain.GetAssemblies() from t in GetTypes(type, asm, onlyInstantiable, includeGenericTypeDefinitions) select t; } /// /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly. /// /// Most general type we want to find. /// Assembly that should be searched for types. /// Return only types that are instantiable /// (interfaces, abstract classes... are not returned) /// Enumerable of the discovered types. public IEnumerable GetTypes(Type type, Assembly assembly, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) { try { // necessary to make sure the exception is immediately thrown // instead of later when the enumerable is iterated? var assemblyTypes = assembly.GetTypes(); var matchingTypes = from assemblyType in assembly.GetTypes() let t = assemblyType.BuildType(type) where t != null where t.IsAssignableTo(type) where !t.IsNonDiscoverableType() where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType) where includeGenericTypeDefinitions || !t.IsGenericTypeDefinition select t; return matchingTypes; } catch (TypeLoadException) { return Enumerable.Empty(); } catch (ReflectionTypeLoadException) { return Enumerable.Empty(); } } /// /// Discovers all types implementing or inheriting all or any type in (directly and indirectly) that are declared in the assembly . /// /// The types to discover. /// The declaring assembly. /// Return only types that are instantiable (instance, abstract... are not returned) /// /// Specifies if discovered types must implement or inherit all given . /// An enumerable of discovered types. public IEnumerable GetTypes(IEnumerable types, Assembly assembly, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) { IEnumerable result = GetTypes(types.First(), assembly, onlyInstantiable, includeGenericTypeDefinitions); foreach (Type type in types.Skip(1)) { IEnumerable discoveredTypes = GetTypes(type, assembly, onlyInstantiable, includeGenericTypeDefinitions); if (assignableToAllTypes) result = result.Intersect(discoveredTypes); else result = result.Union(discoveredTypes); } return result; } /// /// Not supported by the LightweightApplicationManager /// /// /// /// /// NotSupportedException public IEnumerable GetTypes(Type type, IPluginDescription plugin) { throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins."); } /// /// Not supported by the LightweightApplicationManager /// /// /// /// /// /// /// NotSupportedException public IEnumerable GetTypes(Type type, IPluginDescription plugin, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false) { throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins."); } /// /// Not supported by the LightweightApplicationManager /// /// /// /// /// /// /// NotSupportedException public IEnumerable GetTypes(IEnumerable types, IPluginDescription plugin, bool onlyInstantiable = true, bool includeGenericTypeDefinitions = false, bool assignableToAllTypes = true) { throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins."); } /// /// Not supported by the LightweightApplicationManager /// /// /// /// NotSupportedException public IPluginDescription GetDeclaringPlugin(Type type) { throw new NotSupportedException("LightweightApplicationManager doesn't support type discovery for plugins."); } #endregion } }