Changeset 3247
- Timestamp:
- 04/01/10 12:36:29 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.PluginInfrastructure
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.PluginInfrastructure/ApplicationManager.cs
r3092 r3247 35 35 /// <summary> 36 36 /// The ApplicationManager has a reference to the application manager singleton. 37 /// The application manager provides38 37 /// </summary> 39 public sealed class ApplicationManager : MarshalByRefObject, IApplicationManager { 40 private static IApplicationManager appManager; 38 public static class ApplicationManager { 39 // the singleton instance is initialized to LightweightApplicationManager as long as no other application manager is registered 40 private static IApplicationManager appManager = new LightweightApplicationManager(); 41 41 /// <summary> 42 42 /// Gets the application manager singleton. … … 47 47 48 48 /// <summary> 49 /// Fired when a plugin is loaded.50 /// </summary>51 internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;52 /// <summary>53 /// Fired when a plugin is unloaded (when the application terminates).54 /// </summary>55 internal event EventHandler<PluginInfrastructureEventArgs> PluginUnloaded;56 57 // cache for the AssemblyResolveEvent58 // which must be handled when assemblies are loaded dynamically after the application start59 private Dictionary<string, Assembly> loadedAssemblies;60 61 private List<IPlugin> loadedPlugins;62 63 private List<PluginDescription> plugins;64 /// <summary>65 /// Gets all plugins.66 /// </summary>67 public IEnumerable<IPluginDescription> Plugins {68 get { return plugins.Cast<IPluginDescription>(); }69 }70 71 private List<ApplicationDescription> applications;72 /// <summary>73 /// Gets all installed applications.74 /// </summary>75 public IEnumerable<IApplicationDescription> Applications {76 get { return applications.Cast<IApplicationDescription>(); }77 }78 79 internal ApplicationManager()80 : base() {81 loadedAssemblies = new Dictionary<string, Assembly>();82 loadedPlugins = new List<IPlugin>();83 AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {84 if (loadedAssemblies.ContainsKey(args.Name)) {85 return loadedAssemblies[args.Name];86 }87 return null;88 };89 }90 91 /// <summary>92 /// Prepares the application domain for the execution of an HL application.93 /// Pre-loads all <paramref name="plugins"/>.94 /// </summary>95 /// <param name="apps">Enumerable of available HL applications.</param>96 /// <param name="plugins">Enumerable of plugins that should be pre-loaded.</param>97 internal void PrepareApplicationDomain(IEnumerable<ApplicationDescription> apps, IEnumerable<PluginDescription> plugins) {98 this.plugins = new List<PluginDescription>(plugins);99 this.applications = new List<ApplicationDescription>(apps);100 RegisterApplicationManager((IApplicationManager)this);101 LoadPlugins(plugins);102 }103 104 /// <summary>105 49 /// Registers a new application manager. 106 50 /// </summary> 107 51 /// <param name="manager"></param> 108 52 internal static void RegisterApplicationManager(IApplicationManager manager) { 109 if (appManager != null) throw new InvalidOperationException("The application manager has already been set."); 110 appManager = manager; 111 } 112 113 /// <summary> 114 /// Loads the <paramref name="plugins"/> into this application domain. 115 /// </summary> 116 /// <param name="plugins">Enumerable of plugins that should be loaded.</param> 117 private void LoadPlugins(IEnumerable<PluginDescription> plugins) { 118 // load all loadable plugins (all dependencies available) into the execution context 119 foreach (var desc in PluginDescriptionIterator.IterateDependenciesBottomUp(plugins.Where(x => x.PluginState != PluginState.Disabled))) { 120 foreach (string fileName in desc.AssemblyLocations) { 121 var asm = Assembly.LoadFrom(fileName); 122 RegisterLoadedAssembly(asm); 123 // instantiate and load all plugins in this assembly 124 foreach (var plugin in GetInstances<IPlugin>(asm)) { 125 plugin.OnLoad(); 126 loadedPlugins.Add(plugin); 127 } 128 } 129 OnPluginLoaded(new PluginInfrastructureEventArgs(desc)); 130 desc.Load(); 53 if (!(appManager is LightweightApplicationManager)) throw new InvalidOperationException("The application manager has already been set."); 54 else { 55 appManager = manager; 131 56 } 132 57 } 133 134 /// <summary>135 /// Runs the application declared in <paramref name="appInfo"/>.136 /// This is a synchronous call. When the application is terminated all plugins are unloaded.137 /// </summary>138 /// <param name="appInfo">Description of the application to run</param>139 internal void Run(ApplicationDescription appInfo) {140 IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();141 try {142 runnablePlugin.Run();143 }144 finally {145 // unload plugins in reverse order146 foreach (var plugin in loadedPlugins.Reverse<IPlugin>()) {147 plugin.OnUnload();148 }149 foreach (var desc in PluginDescriptionIterator.IterateDependenciesBottomUp(plugins.Where(x => x.PluginState != PluginState.Disabled))) {150 desc.Unload();151 OnPluginUnloaded(new PluginInfrastructureEventArgs(desc));152 }153 }154 }155 156 /// <summary>157 /// Loads raw assemblies dynamically from a byte array158 /// </summary>159 /// <param name="assemblies">bytearray of all raw assemblies that should be loaded</param>160 internal void LoadAssemblies(IEnumerable<byte[]> assemblies) {161 foreach (byte[] asm in assemblies) {162 Assembly loadedAsm = Assembly.Load(asm);163 RegisterLoadedAssembly(loadedAsm);164 }165 }166 167 // register assembly in the assembly cache for the AssemblyResolveEvent168 private void RegisterLoadedAssembly(Assembly asm) {169 loadedAssemblies.Add(asm.FullName, asm);170 loadedAssemblies.Add(asm.GetName().Name, asm); // add short name171 }172 173 /// <summary>174 /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>175 /// </summary>176 /// <typeparam name="T">Most general type.</typeparam>177 /// <returns>Enumerable of the created instances.</returns>178 internal static IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class {179 return from t in GetTypes(typeof(T), plugin, true)180 select (T)Activator.CreateInstance(t);181 }182 /// <summary>183 /// Creates an instance of all types declared in assembly <paramref name="asm"/> that are subtypes or the same type of the specified <typeparamref name="type"/>.184 /// </summary>185 /// <typeparam name="T">Most general type.</typeparam>186 /// <param name="asm">Declaring assembly.</param>187 /// <returns>Enumerable of the created instances.</returns>188 private static IEnumerable<T> GetInstances<T>(Assembly asm) where T : class {189 return from t in GetTypes(typeof(T), asm, true)190 select (T)Activator.CreateInstance(t);191 }192 /// <summary>193 /// Creates an instance of all types that are subtypes or the same type of the specified type194 /// </summary>195 /// <typeparam name="T">Most general type.</typeparam>196 /// <returns>Enumerable of the created instances.</returns>197 internal static IEnumerable<T> GetInstances<T>() where T : class {198 return from i in GetInstances(typeof(T))199 select (T)i;200 }201 202 /// <summary>203 /// Creates an instance of all types that are subtypes or the same type of the specified type204 /// </summary>205 /// <param name="type">Most general type.</param>206 /// <returns>Enumerable of the created instances.</returns>207 internal static IEnumerable<object> GetInstances(Type type) {208 return (from t in GetTypes(type, true)209 select Activator.CreateInstance(t)).ToList();210 }211 212 /// <summary>213 /// Finds all types that are subtypes or equal to the specified type.214 /// </summary>215 /// <param name="type">Most general type for which to find matching types.</param>216 /// <param name="onlyInstantiable">Return only types that are instantiable217 /// (interfaces, abstract classes... are not returned)</param>218 /// <returns>Enumerable of the discovered types.</returns>219 internal static IEnumerable<Type> GetTypes(Type type, bool onlyInstantiable) {220 return from asm in AppDomain.CurrentDomain.GetAssemblies()221 from t in GetTypes(type, asm, onlyInstantiable)222 select t;223 }224 225 /// <summary>226 /// Finds all types that are subtypes or equal to the specified type if they are part of the given227 /// <paramref name="pluginDescription"/>.228 /// </summary>229 /// <param name="type">Most general type for which to find matching types.</param>230 /// <param name="pluginDescription">The plugin the subtypes must be part of.</param>231 /// <param name="onlyInstantiable">Return only types that are instantiable232 /// (interfaces, abstract classes... are not returned)</param>233 /// <returns>Enumerable of the discovered types.</returns>234 internal static IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription, bool onlyInstantiable) {235 PluginDescription pluginDesc = (PluginDescription)pluginDescription;236 return from asm in AppDomain.CurrentDomain.GetAssemblies()237 where !IsDynamicAssembly(asm)238 where pluginDesc.AssemblyLocations.Any(location => location.Equals(Path.GetFullPath(asm.Location), StringComparison.CurrentCultureIgnoreCase))239 from t in GetTypes(type, asm, onlyInstantiable)240 select t;241 }242 243 private static bool IsDynamicAssembly(Assembly asm) {244 return (asm is System.Reflection.Emit.AssemblyBuilder) || string.IsNullOrEmpty(asm.Location);245 }246 247 /// <summary>248 /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.249 /// </summary>250 /// <param name="type">Most general type we want to find.</param>251 /// <param name="assembly">Assembly that should be searched for types.</param>252 /// <param name="onlyInstantiable">Return only types that are instantiable253 /// (interfaces, abstract classes... are not returned)</param>254 /// <returns>Enumerable of the discovered types.</returns>255 private static IEnumerable<Type> GetTypes(Type type, Assembly assembly, bool onlyInstantiable) {256 return from t in assembly.GetTypes()257 where type.IsAssignableFrom(t)258 where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)259 select t;260 }261 262 private void OnPluginLoaded(PluginInfrastructureEventArgs e) {263 if (PluginLoaded != null) PluginLoaded(this, e);264 }265 266 private void OnPluginUnloaded(PluginInfrastructureEventArgs e) {267 if (PluginUnloaded != null) PluginUnloaded(this, e);268 }269 270 // infinite lease time271 /// <summary>272 /// Initializes the life time service with infinite lease time.273 /// </summary>274 /// <returns><c>null</c>.</returns>275 public override object InitializeLifetimeService() {276 return null;277 }278 279 #region IApplicationManager Members280 281 IEnumerable<T> IApplicationManager.GetInstances<T>() {282 return GetInstances<T>();283 }284 285 IEnumerable<object> IApplicationManager.GetInstances(Type type) {286 return GetInstances(type);287 }288 289 IEnumerable<Type> IApplicationManager.GetTypes(Type type) {290 return GetTypes(type, true);291 }292 293 IEnumerable<Type> IApplicationManager.GetTypes(Type type, bool onlyInstantiable) {294 return GetTypes(type, onlyInstantiable);295 }296 297 IEnumerable<Type> IApplicationManager.GetTypes(Type type, IPluginDescription plugin) {298 return GetTypes(type, plugin, true);299 }300 301 IEnumerable<Type> IApplicationManager.GetTypes(Type type, IPluginDescription plugin, bool onlyInstantiable) {302 return GetTypes(type, plugin, onlyInstantiable);303 }304 305 306 /// <summary>307 /// Finds the plugin that declares the <paramref name="type">type</paramref>.308 /// </summary>309 /// <param name="type">The type of interest.</param>310 /// <returns>The description of the plugin that declares the given type or null if the type has not been declared by a known plugin.</returns>311 public IPluginDescription GetDeclaringPlugin(Type type) {312 foreach (PluginDescription info in Plugins) {313 if (info.AssemblyLocations.Contains(Path.GetFullPath(type.Assembly.Location))) return info;314 }315 return null;316 }317 #endregion318 58 } 319 59 } -
trunk/sources/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj
r3069 r3247 172 172 <Compile Include="BaseClasses\ApplicationBase.cs" /> 173 173 <Compile Include="BaseClasses\PluginBase.cs" /> 174 <Compile Include="DefaultApplicationManager.cs" /> 175 <Compile Include="LightweightApplicationManager.cs" /> 174 176 <Compile Include="Interfaces\IPluginFile.cs" /> 175 177 <Compile Include="Interfaces\IApplicationManager.cs" /> -
trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginManager.cs
r2922 r3247 125 125 setup.PrivateBinPath = pluginDir; 126 126 applicationDomain = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName, null, setup); 127 Type applicationManagerType = typeof( ApplicationManager);128 ApplicationManager applicationManager =129 ( ApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null);127 Type applicationManagerType = typeof(DefaultApplicationManager); 128 DefaultApplicationManager applicationManager = 129 (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null); 130 130 applicationManager.PluginLoaded += applicationManager_PluginLoaded; 131 131 applicationManager.PluginUnloaded += applicationManager_PluginUnloaded; -
trunk/sources/HeuristicLab.PluginInfrastructure/Sandboxing/SandboxManager.cs
r2846 r3247 81 81 // unrestricted appdomain 82 82 pset = new PermissionSet(PermissionState.Unrestricted); 83 #endregion 83 #endregion 84 84 85 85 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; … … 87 87 setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 88 88 AppDomain applicationDomain = AppDomain.CreateDomain(name, AppDomain.CurrentDomain.Evidence, setup, pset, CreateStrongName(Assembly.GetExecutingAssembly())); 89 Type applicationManagerType = typeof( ApplicationManager);90 ApplicationManager applicationManager =91 ( ApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null);89 Type applicationManagerType = typeof(DefaultApplicationManager); 90 DefaultApplicationManager applicationManager = 91 (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null); 92 92 ApplicationDescription[] apps = ApplicationManager.Manager.Applications.Cast<ApplicationDescription>().ToArray(); 93 93 PluginDescription[] plugins = ApplicationManager.Manager.Plugins.Cast<PluginDescription>().ToArray(); 94 94 applicationManager.PrepareApplicationDomain(apps, plugins); 95 95 //if (files != null && files.Count() > 0) 96 96 //applicationManager.LoadAssemblies(files); 97 97 return applicationDomain; 98 98 }
Note: See TracChangeset
for help on using the changeset viewer.