The Plugin Interface
To allow a Plugin to become involved in all stages of processing an incoming HTTP request, I had come up with an IWebModule interface and an IWebFilter interface. A Plugin can contain zero, one, or many Modules that implement the IWebModule interface. A Plugin can also contain zero, one, or many Filters that implement the IWebFilter interface. I had also determined that a PluginManager would be responsible for loading and controlling access to Plugins.
The problem remained as to how the PluginManager would actually find and then grab a Plugin.
But first, why is this even a problem that needs solving? Why can Charlie not do something like the following:
public class PluginManager { internal void LoadAllPlugins() { SecurityAssembly.SecurityPlugin security = new SecurityAssembly.SecurityPlugin(); ArticlesAssembly.ArticlesPlugin articles = new ArticlesAssembly.ArticlesPlugin(); } }
The first problem with the above technique is that Charlie’s PluginManager knows specifically which security plugin to use and which articles plugin to use, since it has called them both by name. This defeats the purpose of a plugin, which is that we can replace one plugin with another, without Charlie having to know about the switch.
The second problem with the above is that it forces the plugin assemblies (SecurityAssembly.dll and ArticlesAssembly.dll) to be created before the main Charlie assembly. Once again this defeats the purpose of a plugin, since the Charlie assembly should be created on its own, without having to be compiled against any specific plugin assemblies.
You will see then that there are actually two problems to be solved. The first is that Charlie’s PluginManager needs to be able to work with plugins without knowing precisely which plugins it is going to use. The second is that Charlie’s PluginManager must be able to find and get hold of plugins located in assemblies that were created after the Charlie assembly.
The second problem is addressed in the next weblog entry, where the Plugin Factory is introduced.
The first problem is easy to solve. For Charlie’s PluginManager to work with plugins without knowing precisely which plugins will be used, we need to come up with the definition of a plugin. That is the purpose of an interface, so let’s create the outline of the interface for a plugin:
public interface IPlugin { }
We know that a plugin may have Modules and Filters which allow the plugin to become involved in the processing of the current request. So let’s give the plugins a way of “giving” its Modules and Filters to Charlie’s PluginManager:
public interface IPlugin { IWebModule[] GetModules(); IWebFilter[] GetFilters(); }
With this simple interface, the PluginManager can accept any number of plugins, without ever knowing their specific names. The IPlugin interface defines that a plugin must have a GetModules method that the PluginManager can call to get the Modules from the plugin. The IPlugin interface also defines that a plugin must have a GetFilters method that the PluginManager can call to get the Filters from the plugin.
So we have solved the first of the two problems, as Charlie and its PluginManager can now work with plugins without having to know the specific plugins in use. The problem still remains however that even though Charlie now works with a general definition of a plugin, at some point we do have to load up and give the PluginManager the specific plugins it is to use. That is the task of the PluginFactory, discussed next.
by Alister Jones | Next up: The Plugin Factory →
----
Post a Comment