private static void Register(Type plugin, PluginAttribute pluginAttribute) { object implementor = null; // If the implementor is not provided, we need to be able to construct one ourself if (plugin.GetConstructor(Type.EmptyTypes) == null) { Debug.WriteLine($"Provided type {plugin.Name} does has no parameterless constructor. The type will not be used as a plugin!", "Error"); return; } // Check the plugin-type of the target var targetAttribute = GetOrRegisterPluginType(pluginAttribute.Target); if (targetAttribute != null) { // Get the plugins for this target type if (!pluginImplementors.TryGetValue(pluginAttribute.Target, out var targetPlugins)) { targetPlugins = new Dictionary<string, SortedSet<PluginImplementorData>>(); pluginImplementors[pluginAttribute.Target] = targetPlugins; } if (targetPlugins.TryGetValue(pluginAttribute.Kind, out var targetKindPlugins)) { // Check if multiple implementors of this plugin-type for every kind is allowed if (targetAttribute.AllowMultipleImplementations) { // If yes, just add another targetKindPlugins.Add(new PluginImplementorData { ImplementorType = plugin, Instance = implementor, PluginType = targetAttribute, Priority = pluginAttribute.Priority }); } else { // If not, show an error Debug.WriteLine($"Plugin-type {pluginAttribute.Target.Name} with kind '{pluginAttribute.Kind}' is already provided by {targetKindPlugins.First().ImplementorType.Name}. The type {plugin.Name} will not be used as a plugin!", "Error"); } } else { // Create a new list containing this plugin targetKindPlugins = new SortedSet<PluginImplementorData>(); targetKindPlugins.Add(new PluginImplementorData { ImplementorType = plugin, Instance = implementor, PluginType = targetAttribute, }); targetPlugins[pluginAttribute.Kind] = targetKindPlugins; } } }
private static void RegisterPlugin(Type plugin, PluginAttribute pluginAttribute) { // Check that it implements the proper interface if (!pluginAttribute.Target.IsAssignableFrom(plugin)) { Debug.WriteLine($"Provided type {plugin.Name} does not implement {pluginAttribute.Target.Name}. The type will not be used as a plugin!", "Error"); return; } // Register this type Register(plugin, pluginAttribute); }