private static PluginDescriptor[] ExtractPlugins(Assembly assembly) { var pluginTypes = (from type in assembly.GetExportedTypes() where type.IsClass && !type.IsGenericType && type.IsPublic && type.IsVisible && !type.IsAbstract where CustomAttributeData.GetCustomAttributes(type).Any(x => x.Constructor.DeclaringType.FullName == typeof(PluginAttribute).FullName) select type).ToArray(); PluginDescriptor[] pluginDescriptions = new PluginDescriptor[pluginTypes.Length]; for (int i = 0; i < pluginTypes.Length; i++) { Type type = pluginTypes[i]; IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(type); PluginDescriptor plugin = pluginDescriptions[i] = new PluginDescriptor(); plugin.QualifiedName = type; plugin.Name = type.Namespace + "." + type.Name; plugin.Version = GetPluginVersion(attributes); SetPluginAncestors(plugin, type); SetPluginInterfaces(plugin, type); SetPluginInfoValuesFromAttributes(plugin, attributes); SetPluginSettings(plugin, type); var keyValues = GetPluginAttributeNamedValues(attributes); object value; if (keyValues.TryGetValue("Name", out value)) plugin.Name = value as string; } return pluginDescriptions; }
/// <summary> /// Fills the plugindescriptor with the plugins settings. /// </summary> /// <param name="plugin">The plugindescriptor.</param> /// <param name="type">The plugintype.</param> private static void SetPluginSettings(PluginDescriptor plugin, Type type) { // Fetch plugin settings foreach (var property in type.GetProperties()) { CustomAttributeData attribute = CustomAttributeData.GetCustomAttributes(property).FirstOrDefault(x => x.Constructor.DeclaringType.FullName == typeof(PluginSettingAttribute).FullName); if (attribute == null) continue; PluginSettingDescriptor setting = new PluginSettingDescriptor(); setting.Name = property.Name; setting.SettingType = property.PropertyType; foreach (var namedArg in attribute.NamedArguments) { if (namedArg.MemberInfo.Name == "Name") setting.Name = (string)namedArg.TypedValue.Value; else if (namedArg.MemberInfo.Name == "Required") setting.Required = (bool)namedArg.TypedValue.Value; } plugin.Settings.Add(setting); } }
private void AddPlugins(string assemblyId, PluginDescriptor[] plugins) { this.log.Info(Resources.FoundCountPluginsIn, plugins.Length, assemblyId); this.assemblyPlugins.Add(assemblyId, plugins); if (this.PluginAdded != null) foreach (var plugin in plugins) this.PluginAdded(this, new PluginEventArgs(plugin)); }
/// <summary> /// Fills the plugindescriptor with the plugin implemented interfaces. /// </summary> /// <param name="plugin">The plugindescriptor.</param> /// <param name="type">The plugintype.</param> private static void SetPluginInterfaces(PluginDescriptor plugin, Type type) { foreach (var interfaceType in type.GetInterfaces()) plugin.Interfaces.Add(interfaceType); }
/// <summary> /// Sets the plugin metainfo values from <see cref="PluginInfoAttribute"/>s found in class attributes. /// </summary> /// <param name="plugin">The plugindescriptor.</param> /// <param name="attributes">The class attributes.</param> private static void SetPluginInfoValuesFromAttributes(PluginDescriptor plugin, IList<CustomAttributeData> attributes) { foreach (var attribute in attributes.Where(x => x.Constructor.DeclaringType.FullName == typeof(PluginInfoAttribute).FullName)) plugin.InfoValues[attribute.ConstructorArguments[0].Value as string] = attribute.ConstructorArguments[1].Value as string; }
/// <summary> /// Fills the plugindescriptor with the plugin inherited ancestors. /// </summary> /// <param name="plugin">The plugindescriptor.</param> /// <param name="type">The plugintype.</param> private static void SetPluginAncestors(PluginDescriptor plugin, Type type) { Type loop = type; while (loop.BaseType != null) { plugin.Derives.Add(loop.BaseType); loop = loop.BaseType; } }
public object Create(PluginDescriptor descriptor, IAssemblyRepository assemblies, IDictionary<string, object> settings) { if (descriptor == null) throw new ArgumentNullException("descriptor"); if (assemblies == null) throw new ArgumentNullException("assemblies"); try { ResolveEventHandler resolveHandler = new ResolveEventHandler((s, e) => { // Fetch assembly from repository and load it into the appdomain byte[] assemblyBytes = assemblies.Fetch(e.Name); if (assemblyBytes != null) return Assembly.Load(assemblyBytes); // Unable to resolve this assembly return null; }); AppDomain.CurrentDomain.AssemblyResolve += resolveHandler; object plugin = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(descriptor.QualifiedName.AssemblyFullName, descriptor.QualifiedName.TypeFullName); AppDomain.CurrentDomain.AssemblyResolve -= resolveHandler; ApplySettings(plugin, settings); this.log.Info(Resources.CreatedPlugin, plugin.GetType().FullName); return plugin; } catch (PluginException ex) { this.log.Error(ex.Message); throw; } catch (Exception ex) { this.log.Error(ex.Message); throw new PluginException(ex.Message, ex); } }
/// <summary> /// Initializes a new instance of the <see cref="PluginEventArgs"/> class. /// </summary> /// <param name="plugin">The plugin.</param> public PluginEventArgs(PluginDescriptor plugin) { this.Plugin = plugin; }