Search

Advertising

Home Downloads Components

Components

Folder Path: \ Components \

File: Type-Safe Plugin Framework

file.png
Uploaded:
September.01.09
Modified:
September.01.09
File Size:
20 KB
Downloads:
634
Version
1.0

Plugin framework that allows you to build applications that can be dynamically extended. Using plugins is also an elegant way of enforcing decoupling of application modules and avoiding dependency creep. Doesn't require any modification to the plugin classes (no custom attributes and no special base classes).

Details

Here's a piece of code that has been sitting in my support library for some time already and is being successfully used for all kinds of plug-ins. Plug-ins are an elegant way not only to make applications extensible, but also to enforce separation: if an assembly does not have a reference to another assembly, no "dependency creep" will happen and separation is guaranteed.

Plugins are quite similar to Dependency Injection through an Inversion-of-Control container with auto-wiring, but without recursive lookups and requiring you to write the code that decides which types are suitable as implementations yourself. If you don't know what I'm talking about here, don't worry, you don't need to know a thing about IoC containers to use plugins, though I highly recommend reading up on the topic because it's an excellent way to keep on top of larger projects :)

My plugin library splits plugin management into three parts: First, there's the "Repository", which stores the loaded plugin assemblies. Then there are "Employers" which will pick the types from the plugin assemblies that fulfill the employer's requirements (an example criterion could be: all non-abstract classes deriving from IGraphicsDevice). Finally, there's the "PluginHost" which will run an employer on the types found in the assemblies in its repository.

Example

This is the example also included in the downloadable example project

// The employer screens all types encountered in an assembly and employs
// those matching his criteria. Employment here can mean registering a factory
// for the type, instantiating the type and adding it to a list or anything
// else you could possibly code.
//
// This is the default factory employer, it will employ public, non-abstract
// types with a parameterless constructor derived from the class or interface
// we specify in its generic parameter.
FactoryEmployer<ICollection> listEmployer = new FactoryEmployer<ICollection>();

// The plugin host stores the employer and connects it to a repository, which
// contains the assemblies from which types can be employed. Multiple plugin
// hosts can share a single repository.
//
// If no repository is specified, the plugin host creates a new, empty one.
PluginHost host = new PluginHost(listEmployer);

// Now load some assemblies into the host's repository. The first one will be
// our System.dll containing .NET's default classes. The second one loads
// Nuclex.Collections.dll. You could also specify wildcards instead of a
// file name, eg "Plugins/*.dll"
host.Repository.AddAssembly(typeof(ICollection).Assembly);
host.Repository.AddFiles("Nuclex.Collections.dll");

// Note that for this example, we added Nuclex.Collections as a reference to
// the Demo project - simply to make sure the assembly will be in the target
// directory after compiling. This makes the plugin a requirement, however.
//
// Normally, plugins should be optional. One way to achieve this is to create
// an additional project in your solution and let it reference your main
// executable project and any plugin projects. This will cause the main
// executable and all plugins to be copied into its output folder while
// keeping the main executable free of any references to the plugin projects.

// Print the types for which we now have factories:
Console.WriteLine("Factories exist for:");
foreach(IAbstractFactory<ICollection> factory in listEmployer.Factories) {
  string typeName = factory.CreateInstance().GetType().Name;
  Console.WriteLine("  " + typeName);
}

Features

  • Dynamic loading of assemblies as plugins
  • Plugins are fully type-safe
  • Freely definable employment criteria for plugin types
  • Freely controllable employment action (built-in employers include factory creation and instance list)
  • 100% unit test coverage for the whole code

The plugin code is part of the Nuclex.Support library from the Nuclex Framework. You can find the most recent release of the code on the framework's CodePlex site:
http://nuclexframework.codeplex.com/



Joomla Template by Joomlashack