Changeset 1228
- Timestamp:
- 02/26/09 13:40:08 (16 years ago)
- Location:
- branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs ¶
r8 r1228 30 30 /// Default implementation of the IPlugin interface. 31 31 /// </summary> 32 public class PluginBase : IPlugin {32 public abstract class PluginBase : IPlugin { 33 33 private string name; 34 34 private Version version; … … 44 44 45 45 // exactly one attribute of the type ClassInfoAttribute must be given 46 if (pluginAttributes.Length != 1) {46 if (pluginAttributes.Length != 1) { 47 47 throw new InvalidPluginException(); 48 48 } … … 52 52 53 53 // if the plugin name is not explicitly set in the attribute then the default plugin name is the FullName of the type 54 if (pluginAttribute != null && pluginAttribute.Name != null) {54 if (pluginAttribute != null && pluginAttribute.Name != null) { 55 55 this.name = pluginAttribute.Name; 56 56 } else { … … 59 59 60 60 // if the version is not explicitly set in the attribute then the version of the assembly is used as default 61 if (pluginAttribute != null && pluginAttribute.Version != null) {61 if (pluginAttribute != null && pluginAttribute.Version != null) { 62 62 this.version = new Version(pluginAttribute.Version); 63 63 } else { … … 66 66 67 67 // if the description is not explicitly set in the attribute then the name of name of the plugin is used as default 68 if (pluginAttribute != null && pluginAttribute.Description != null) {68 if (pluginAttribute != null && pluginAttribute.Description != null) { 69 69 this.description = pluginAttribute.Description; 70 70 } else { … … 78 78 this.files = new string[fileAttributes.Length]; 79 79 int i = 0; 80 foreach (PluginFileAttribute fileAttr in fileAttributes) {80 foreach (PluginFileAttribute fileAttr in fileAttributes) { 81 81 files[i++] = fileAttr.Filename; 82 82 } … … 102 102 } 103 103 104 public 104 public string[] Files { 105 105 get { 106 106 return files; … … 108 108 } 109 109 110 public virtual void OnInstall() { 111 } 112 113 public virtual void OnDelete() { 114 } 115 116 public virtual void OnPreUpdate() { 117 } 118 119 public virtual void OnPostUpdate() { 120 } 110 public virtual void OnLoad() { } 111 public virtual void OnInstall() { } 112 public virtual void OnDelete() { } 113 public virtual void OnPreUpdate() { } 114 public virtual void OnPostUpdate() { } 121 115 122 116 #endregion -
TabularUnified branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs ¶
r2 r1228 30 30 /// assemblies of the plugin. Plugin developers can use the properties of this interface to store 31 31 /// plugin data (name, version, files, update location ...). 32 /// The methods On Install(), OnDelete(), OnPreUpdate(), OnPostUpdate() are called by the framework32 /// The methods OnLoad(), OnInstall(), OnDelete(), OnPreUpdate(), OnPostUpdate() are called by the framework 33 33 /// when the corresponding actions are executed. This mechanism allows that the plugin reacts to such 34 34 /// events. For instance to store plugin specific settings. … … 42 42 string[] Files { get; } 43 43 44 45 /// <summary> 46 /// Called by the framework whenever the plugin is loaded. 47 /// Plugins are loaded once at startup and then each time a new application is started from the starter. 48 /// </summary> 49 void OnLoad(); 44 50 /// <summary> 45 51 /// called by the framework after the plugin was successfully installed -
TabularUnified branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Loader.cs ¶
r535 r1228 46 46 get { 47 47 List<PluginInfo> list = new List<PluginInfo>(); 48 foreach (PluginInfo info in allPlugins.Keys) {49 if (!disabledPlugins.Exists(delegate(PluginInfo disabledInfo) { return info.Name == disabledInfo.Name; })) {48 foreach (PluginInfo info in allPlugins.Keys) { 49 if (!disabledPlugins.Exists(delegate(PluginInfo disabledInfo) { return info.Name == disabledInfo.Name; })) { 50 50 list.Add(info); 51 51 } … … 75 75 76 76 private IPlugin FindPlugin(PluginInfo plugin) { 77 if (allPlugins.ContainsKey(plugin)) {77 if (allPlugins.ContainsKey(plugin)) { 78 78 return allPlugins[plugin]; 79 79 } else return null; … … 95 95 try { 96 96 return Assembly.ReflectionOnlyLoad(args.Name); 97 } catch(FileLoadException ex) { 97 } 98 catch (FileLoadException ex) { 98 99 return null; 99 100 } 100 101 }; 101 102 allPlugins.Clear(); 102 103 disabledPlugins.Clear(); … … 115 116 applications = new List<ApplicationInfo>(); 116 117 117 foreach (IApplication application in apps) {118 foreach (IApplication application in apps) { 118 119 ApplicationInfo info = new ApplicationInfo(); 119 120 info.Name = application.Name; … … 131 132 List<Assembly> assemblies = new List<Assembly>(); 132 133 // load all installed plugins into the reflection only context 133 foreach (String filename in Directory.GetFiles(pluginDir, "*.dll")) {134 foreach (String filename in Directory.GetFiles(pluginDir, "*.dll")) { 134 135 try { 135 136 assemblies.Add(ReflectionOnlyLoadDll(filename)); 136 } catch(BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll 137 } 138 catch (BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll 137 139 } 138 140 return assemblies; … … 144 146 145 147 private void CheckAssemblyDependencies(List<Assembly> assemblies) { 146 foreach (Assembly assembly in assemblies) {148 foreach (Assembly assembly in assemblies) { 147 149 // GetExportedTypes throws FileNotFoundException when a referenced assembly 148 150 // of the current assembly is missing. … … 150 152 Type[] exported = assembly.GetExportedTypes(); 151 153 152 foreach (Type t in exported) {154 foreach (Type t in exported) { 153 155 // if there is a type that implements IPlugin 154 if (Array.Exists<Type>(t.GetInterfaces(), delegate(Type iface) {156 if (Array.Exists<Type>(t.GetInterfaces(), delegate(Type iface) { 155 157 // use AssemblyQualifiedName to compare the types because we can't directly 156 158 // compare ReflectionOnly types and Execution types … … 161 163 } 162 164 } 163 } catch(FileNotFoundException ex) { 165 } 166 catch (FileNotFoundException ex) { 164 167 PluginInfo info = new PluginInfo(); 165 168 AssemblyName name = assembly.GetName(); … … 170 173 info.Message = "File not found: " + ex.FileName; 171 174 disabledPlugins.Add(info); 172 } catch(FileLoadException ex) { 175 } 176 catch (FileLoadException ex) { 173 177 PluginInfo info = new PluginInfo(); 174 178 AssemblyName name = assembly.GetName(); … … 197 201 string pluginName = ""; 198 202 // iterate through all custom attributes and search for named arguments that we are interested in 199 foreach (CustomAttributeData attributeData in attributes) {203 foreach (CustomAttributeData attributeData in attributes) { 200 204 List<CustomAttributeNamedArgument> namedArguments = new List<CustomAttributeNamedArgument>(attributeData.NamedArguments); 201 205 // if the current attribute contains a named argument with the name "Name" then extract the plugin name … … 203 207 return arg.MemberInfo.Name == "Name"; 204 208 }); 205 if (pluginNameArgument.MemberInfo != null) {209 if (pluginNameArgument.MemberInfo != null) { 206 210 pluginName = (string)pluginNameArgument.TypedValue.Value; 207 211 } … … 211 215 return arg.MemberInfo.Name == "Dependency"; 212 216 }); 213 if (dependencyNameArgument.MemberInfo != null) {217 if (dependencyNameArgument.MemberInfo != null) { 214 218 pluginDependencies.Add((string)dependencyNameArgument.TypedValue.Value); 215 219 } … … 222 226 return arg.MemberInfo.Name == "Filetype"; 223 227 }); 224 if (filenameArg.MemberInfo != null && filetypeArg.MemberInfo != null) {228 if (filenameArg.MemberInfo != null && filetypeArg.MemberInfo != null) { 225 229 pluginFiles.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value); 226 if ((PluginFileType)filetypeArg.TypedValue.Value == PluginFileType.Assembly) {230 if ((PluginFileType)filetypeArg.TypedValue.Value == PluginFileType.Assembly) { 227 231 pluginAssemblies.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value); 228 232 } … … 231 235 232 236 // minimal sanity check of the attribute values 233 if (pluginName != "" && pluginAssemblies.Count > 0) {237 if (pluginName != "" && pluginAssemblies.Count > 0) { 234 238 // create a temporary PluginInfo that contains the attribute values 235 239 PluginInfo info = new PluginInfo(); … … 247 251 248 252 private void CheckPluginDependencies() { 249 foreach (PluginInfo pluginInfo in preloadedPluginInfos) {253 foreach (PluginInfo pluginInfo in preloadedPluginInfos) { 250 254 // don't need to check plugins that are already disabled 251 if (disabledPlugins.Contains(pluginInfo)) {255 if (disabledPlugins.Contains(pluginInfo)) { 252 256 continue; 253 257 } 254 258 visitedDependencies.Clear(); 255 if (!CheckPluginDependencies(pluginInfo.Name)) {259 if (!CheckPluginDependencies(pluginInfo.Name)) { 256 260 PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginInfo.Name; }); 257 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen258 foreach (string dependency in pluginDependencies[matchingInfo]) {261 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen 262 foreach (string dependency in pluginDependencies[matchingInfo]) { 259 263 PluginInfo dependencyInfo = new PluginInfo(); 260 264 dependencyInfo.Name = dependency; … … 270 274 private List<string> visitedDependencies = new List<string>(); 271 275 private bool CheckPluginDependencies(string pluginName) { 272 if (!preloadedPluginInfos.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) ||276 if (!preloadedPluginInfos.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) || 273 277 disabledPlugins.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) || 274 278 visitedDependencies.Contains(pluginName)) { … … 280 284 281 285 PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginName; }); 282 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen283 foreach (string dependency in pluginDependencies[matchingInfo]) {286 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen 287 foreach (string dependency in pluginDependencies[matchingInfo]) { 284 288 visitedDependencies.Add(pluginName); 285 if (CheckPluginDependencies(dependency) == false) {289 if (CheckPluginDependencies(dependency) == false) { 286 290 // if only one dependency is not available that means that the current plugin also is unloadable 287 291 return false; … … 298 302 private void LoadPlugins() { 299 303 // load all loadable plugins (all dependencies available) into the execution context 300 foreach (PluginInfo pluginInfo in preloadedPluginInfos) {301 if (!disabledPlugins.Contains(pluginInfo)) {302 foreach (string assembly in pluginInfo.Assemblies) {304 foreach (PluginInfo pluginInfo in preloadedPluginInfos) { 305 if (!disabledPlugins.Contains(pluginInfo)) { 306 foreach (string assembly in pluginInfo.Assemblies) { 303 307 Assembly.LoadFrom(assembly); 304 308 } … … 308 312 DiscoveryService service = new DiscoveryService(); 309 313 // now search and instantiate an IPlugin type in each loaded assembly 310 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {314 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { 311 315 // don't search for plugins in the PluginInfrastructure 312 if (assembly == this.GetType().Assembly)316 if (assembly == this.GetType().Assembly) 313 317 continue; 314 318 Type[] availablePluginTypes = service.GetTypes(typeof(IPlugin), assembly); 315 foreach (Type pluginType in availablePluginTypes) {316 if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {319 foreach (Type pluginType in availablePluginTypes) { 320 if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) { 317 321 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); 318 322 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.InitializingPlugin)); 323 plugin.OnLoad(); 319 324 pluginsByName.Add(plugin.Name, plugin); 320 325 } … … 322 327 } 323 328 324 foreach (IPlugin plugin in pluginsByName.Values) {329 foreach (IPlugin plugin in pluginsByName.Values) { 325 330 PluginInfo pluginInfo = GetPluginInfo(plugin); 326 331 allPlugins.Add(pluginInfo, plugin); … … 329 334 } 330 335 private PluginInfo GetPluginInfo(IPlugin plugin) { 331 if (pluginInfos.ContainsKey(plugin)) {336 if (pluginInfos.ContainsKey(plugin)) { 332 337 return pluginInfos[plugin]; 333 338 } … … 338 343 339 344 object[] customAttributes = plugin.GetType().Assembly.GetCustomAttributes(typeof(AssemblyBuildDateAttribute), false); 340 if (customAttributes.Length > 0) {345 if (customAttributes.Length > 0) { 341 346 pluginInfo.BuildDate = ((AssemblyBuildDateAttribute)customAttributes[0]).BuildDate; 342 347 } … … 351 356 352 357 PluginInfo preloadedInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == plugin.Name; }); 353 foreach (string assembly in preloadedInfo.Assemblies) {358 foreach (string assembly in preloadedInfo.Assemblies) { 354 359 // always use \ as directory separator (this is necessary for discovery of types in 355 360 // plugins see DiscoveryService.GetTypes() 356 361 pluginInfo.Assemblies.Add(assembly.Replace('/', '\\')); 357 362 } 358 foreach (string dependency in pluginDependencies[preloadedInfo]) {363 foreach (string dependency in pluginDependencies[preloadedInfo]) { 359 364 // accumulate the dependencies of each assembly into the dependencies of the whole plugin 360 365 PluginInfo dependencyInfo = GetPluginInfo(pluginsByName[dependency]); … … 366 371 367 372 private void CheckPluginFiles() { 368 foreach (PluginInfo plugin in preloadedPluginInfos) {369 if (!CheckPluginFiles(plugin)) {373 foreach (PluginInfo plugin in preloadedPluginInfos) { 374 if (!CheckPluginFiles(plugin)) { 370 375 plugin.Message = "Disabled: missing plugin file."; 371 376 disabledPlugins.Add(plugin); … … 375 380 376 381 private bool CheckPluginFiles(PluginInfo pluginInfo) { 377 foreach (string filename in pluginInfo.Files) {378 if (!File.Exists(filename)) {379 if (MissingPluginFile != null) {382 foreach (string filename in pluginInfo.Files) { 383 if (!File.Exists(filename)) { 384 if (MissingPluginFile != null) { 380 385 MissingPluginFile(pluginInfo.Name, filename); 381 386 } … … 393 398 internal void OnDelete(PluginInfo pluginInfo) { 394 399 IPlugin plugin = FindPlugin(pluginInfo); 395 if (plugin!=null) plugin.OnDelete();400 if (plugin != null) plugin.OnDelete(); 396 401 } 397 402 398 403 internal void OnInstall(PluginInfo pluginInfo) { 399 404 IPlugin plugin = FindPlugin(pluginInfo); 400 if (plugin != null) plugin.OnInstall();405 if (plugin != null) plugin.OnInstall(); 401 406 } 402 407 403 408 internal void OnPreUpdate(PluginInfo pluginInfo) { 404 409 IPlugin plugin = FindPlugin(pluginInfo); 405 if (plugin != null) plugin.OnPreUpdate();410 if (plugin != null) plugin.OnPreUpdate(); 406 411 } 407 412 408 413 internal void OnPostUpdate(PluginInfo pluginInfo) { 409 414 IPlugin plugin = FindPlugin(pluginInfo); 410 if (plugin != null) plugin.OnPostUpdate();415 if (plugin != null) plugin.OnPostUpdate(); 411 416 } 412 417 } -
TabularUnified branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Runner.cs ¶
r886 r1228 39 39 } 40 40 //CodeAccessPermission.RevertAssert(); 41 FireOnLoad(); 41 42 PluginManager.Manager.LoadedPlugins = plugins; 42 43 } … … 47 48 } 48 49 50 private void FireOnLoad() { 51 DiscoveryService service = new DiscoveryService(); 52 Array.ForEach(service.GetInstances<IPlugin>(), p => p.OnLoad()); 53 } 54 49 55 // infinite lease time 50 56 public override object InitializeLifetimeService() {
Note: See TracChangeset
for help on using the changeset viewer.