Takeaway: Many dynamic applications allow third parties to create plugins that extend the functionality of the application. Zach Smith explains how developers can leverage the .NET Framework and C# to easily create a plugin architecture of their own. A sample solution is also provided that demonstrates the concepts described.
This article is also available as a TechRepublic download.
In the enterprise world you rarely come across any in-house application that will allow plugins to be written and imported without any changes to core application code. I believe one of the reasons for this is that in the past it was difficult to implement the type of architecture that will allow the use of plugins.
Developers were forced to either spend a large amount of time on the architecture design, or figure out a work around to accomplish their goals. As we all know, large amounts of time are not easy to come by in the enterprise world, and it seems most developers were forced to develop workarounds. Microsoft has solved this issue with C# and the .NET Framework. It is now trivial to develop an application that will allow components to be plugged-in dynamically, without any core code changes.
The solution included with this article (see the project files found in the download) demonstrates how to implement a simple plugin architecture. This demonstration solution dynamically executes tests (each test is a plugin) and reports the results. Each test is able to do something different, and tests should be able to be added or removed without any changes to the core test engine functionality. This allows us to add tests to the application without rebuilding the entire application. I have called this solution "SystemTests", and it contains four projects: SharedObjects, TestEngine, TestExamples, and TestApplication.
Many applications that allow plugins have just a few basic layers that enable the plugin functionality, and the SystemTests solution is no different.
The shared objects layer is responsible for providing a way for the main application to communicate with the plugins. Both the main application and the plugins reference the shared objects.
The Shared Objects layer is implemented by the SharedObject project. This project contains the following items:
The main application layer is where the core functionality for the application is implemented. This layer ties all of the plugins together, does any reporting that is needed, and interfaces with the user or database.
The main application layer is implemented by the TestEngine project, which contains one class – "Engine". It is the job of the Engine class to gather the tests that must be ran and run them, reporting the results back to the calling application through a TestEngineState object.
The two most important methods in the Engine class are LoadConfiguration and CreateTest. These two methods are explained in detail below:
The plugin layer contains the plugins that are setup for the application. Generally, each plugin contained in this layer will implement one or more interfaces from the shared objects layer. This allows the main application layer to communicate with the plugins.
The plugin layer is implemented by the TestExamples project. The functionality within each test can vary from one test to another, and there are no rules on what a test has to do. The only rule is that the test must implement the ITest interface, everything else is up to the test developer.
Listing C is an example of a very simple test, called "MathTest". This test passes if 1 does not equal 2 (1 != 2), and fails if 1 equals 2 (1 == 2):
While this test is extremely simple, as I mentioned above it could do anything as long as it implements the ITest interface.
The included solution contains two other sample tests:
There is one more project in the solution included with this article called "TestApplication". This project is a very simple Windows form application that displays results from the TestEngine.
Take a look at the solution included with this articleand think about how this type of plugin functionality could be applied to business problems at your company. Chances are there are at least a couple instances where this type of highly dynamic functionality could be very helpful. Feel free to use the code examples for your own use!