2008-01-07 18:04:02 +00:00
|
|
|
|
#region CPL License
|
|
|
|
|
/*
|
|
|
|
|
Nuclex Framework
|
2012-02-29 16:27:43 +00:00
|
|
|
|
Copyright (C) 2002-2012 Nuclex Development Labs
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the IBM Common Public License as
|
|
|
|
|
published by the IBM Corporation; either version 1.0 of the
|
|
|
|
|
License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
|
IBM Common Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the IBM Common Public
|
|
|
|
|
License along with this library
|
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
using System;
|
2008-12-09 19:41:43 +00:00
|
|
|
|
using System.Diagnostics;
|
2008-01-07 18:04:02 +00:00
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
namespace Nuclex.Support.Plugins {
|
|
|
|
|
|
|
|
|
|
/// <summary>Integration host for plugins</summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This class is created by the party that is interested in loading plugins,
|
|
|
|
|
/// herein referred to as the "plugin user". The plugin host will monitor a
|
|
|
|
|
/// repository and react to any assembly being loaded into that repository by
|
|
|
|
|
/// iterating over all types (as in classes and structures) found in the
|
|
|
|
|
/// assembly and using the employer to do whatever the plugin user intends
|
|
|
|
|
/// to do with the types found in that assembly
|
|
|
|
|
/// </remarks>
|
|
|
|
|
public class PluginHost {
|
|
|
|
|
|
|
|
|
|
/// <summary>Initializes a plugin host using a new repository</summary>
|
|
|
|
|
/// <param name="employer">Employer used assess and employ the plugin types</param>
|
2009-05-20 20:14:21 +00:00
|
|
|
|
public PluginHost(Employer employer) :
|
|
|
|
|
this(employer, new PluginRepository()) { }
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>Initializes the plugin using an existing repository</summary>
|
|
|
|
|
/// <param name="employer">Employer used assess and employ the plugin types</param>
|
|
|
|
|
/// <param name="repository">Repository in which plugins will be stored</param>
|
|
|
|
|
public PluginHost(Employer employer, PluginRepository repository) {
|
|
|
|
|
this.employer = employer;
|
|
|
|
|
this.repository = repository;
|
|
|
|
|
|
2009-05-20 20:14:21 +00:00
|
|
|
|
foreach(Assembly assembly in this.repository.LoadedAssemblies) {
|
2008-01-07 18:04:02 +00:00
|
|
|
|
employAssemblyTypes(assembly);
|
2009-05-20 20:14:21 +00:00
|
|
|
|
}
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
this.repository.AssemblyLoaded += new AssemblyLoadEventHandler(assemblyLoadHandler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>The repository containing all loaded plugins</summary>
|
|
|
|
|
public PluginRepository Repository {
|
|
|
|
|
get { return this.repository; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>The employer that is used by this plugin integration host</summary>
|
|
|
|
|
public Employer Employer {
|
|
|
|
|
get { return this.employer; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Responds to a new plugin being loaded into the repository</summary>
|
|
|
|
|
/// <param name="sender">Repository into which the assembly was loaded</param>
|
|
|
|
|
/// <param name="arguments">Event arguments; contains the loaded assembly</param>
|
|
|
|
|
private void assemblyLoadHandler(object sender, AssemblyLoadEventArgs arguments) {
|
|
|
|
|
employAssemblyTypes(arguments.LoadedAssembly);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Employs all employable types in an assembly</summary>
|
|
|
|
|
/// <param name="assembly">Assembly whose types to assess and to employ</param>
|
|
|
|
|
private void employAssemblyTypes(Assembly assembly) {
|
|
|
|
|
|
|
|
|
|
// Iterate all types contained in the assembly
|
2009-05-20 20:14:21 +00:00
|
|
|
|
Type[] types = assembly.GetTypes();
|
|
|
|
|
for(int index = 0; index < types.Length; ++index) {
|
|
|
|
|
Type type = types[index];
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
// We'll ignore abstract and non-public types
|
2008-08-07 19:57:20 +00:00
|
|
|
|
if(!type.IsPublic || type.IsAbstract) {
|
2008-01-07 18:04:02 +00:00
|
|
|
|
continue;
|
2008-08-07 19:57:20 +00:00
|
|
|
|
}
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
// Types that have been tagged with the [NoPlugin] attribute will be ignored
|
|
|
|
|
object[] attributes = type.GetCustomAttributes(true);
|
2008-12-09 19:41:43 +00:00
|
|
|
|
if(containsNoPluginAttribute(attributes)) {
|
|
|
|
|
continue;
|
2008-08-07 19:57:20 +00:00
|
|
|
|
}
|
2008-01-07 18:04:02 +00:00
|
|
|
|
|
|
|
|
|
// Type seems to be acceptable, assess and possibly employ it
|
|
|
|
|
try {
|
2008-08-07 19:57:20 +00:00
|
|
|
|
if(this.employer.CanEmploy(type)) {
|
2008-01-07 18:04:02 +00:00
|
|
|
|
this.employer.Employ(type);
|
2008-08-07 19:57:20 +00:00
|
|
|
|
}
|
2008-01-07 18:04:02 +00:00
|
|
|
|
}
|
|
|
|
|
catch(Exception exception) {
|
2010-09-17 01:43:00 +00:00
|
|
|
|
reportError("Could not employ " + type.ToString() + ": " + exception.Message);
|
2008-01-07 18:04:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-24 19:20:26 +00:00
|
|
|
|
|
2008-01-07 18:04:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-12-09 19:41:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Determines whether the specifies list of attributes contains a NoPluginAttribute
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="attributes">List of attributes to check</param>
|
|
|
|
|
/// <returns>True if the list contained a NoPluginAttribute, false otherwise</returns>
|
|
|
|
|
private static bool containsNoPluginAttribute(object[] attributes) {
|
|
|
|
|
for(int index = 0; index < attributes.Length; ++index) {
|
|
|
|
|
if(attributes[index] is NoPluginAttribute) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-17 01:43:00 +00:00
|
|
|
|
/// <summary>Reports an error to the debugging console</summary>
|
|
|
|
|
/// <param name="error">Error message that will be reported</param>
|
|
|
|
|
private static void reportError(string error) {
|
2010-12-24 01:02:56 +00:00
|
|
|
|
#if WINDOWS
|
2010-09-17 01:43:00 +00:00
|
|
|
|
Trace.WriteLine(error);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-07 18:04:02 +00:00
|
|
|
|
/// <summary>Employs and manages types in the loaded plugin assemblies</summary>
|
|
|
|
|
private Employer employer;
|
|
|
|
|
/// <summary>Repository containing all plugins loaded, shared with other hosts</summary>
|
|
|
|
|
private PluginRepository repository;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Nuclex.Support.Plugins
|