#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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) { return from t in GetTypes(type, true) select Activator.CreateInstance(t); } /// /// Finds all instantiable 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) /// Enumerable of the discovered types. public IEnumerable GetTypes(Type type) { return GetTypes(type, true); } /// /// 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) /// Enumerable of the discovered types. public IEnumerable GetTypes(Type type, bool onlyInstantiable) { return from asm in AppDomain.CurrentDomain.GetAssemblies() from t in GetTypes(type, asm, onlyInstantiable) 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. private static IEnumerable GetTypes(Type type, Assembly assembly, bool onlyInstantiable) { try { var assemblyTypes = assembly.GetTypes(); return from t in assemblyTypes where CheckTypeCompatibility(type, t) where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType) select BuildType(t, type); } catch (TypeLoadException) { return Enumerable.Empty(); } catch (ReflectionTypeLoadException) { return Enumerable.Empty(); } } private static bool CheckTypeCompatibility(Type type, Type other) { if (type.IsAssignableFrom(other)) return true; if (type.IsGenericType && other.IsGenericType) { try { if (type.IsAssignableFrom(other.GetGenericTypeDefinition().MakeGenericType(type.GetGenericArguments()))) return true; } catch (Exception) { } } return false; } private static Type BuildType(Type type, Type protoType) { if (type.IsGenericType && protoType.IsGenericType) return type.GetGenericTypeDefinition().MakeGenericType(protoType.GetGenericArguments()); else return type; } /// /// 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) { 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 } }