Quantcast
Channel: C# – Software Rockstar
Viewing all articles
Browse latest Browse all 11

MEF: Easily Creating Plug-in Based Apps In .NET

$
0
0

MEF (Managed Extensibility Framework) is an awesome framework that allows easily loading types at runtime making your apps plugin-ready.   Using reflection magic, MEF makes it super easy for any app to accept plugins.

Following are 5 easy steps involved in making your app plugin-ready using MEF:

  1. Define an interface for plugins.  This is the interface that each plugin must implement.
  2. Define a metadata interface.  This interface tells your app out of so many plugins which one is the correct plugin for a given piece of functionality.
  3. Define one or more concrete plugin classes.
  4. Decorate each class with some attributes.
  5. In your app write a few lines of code to invoke MEF, and let the magic happen.

While it may not be very useful in the real world, let’s say that we have an extensible app that can write provided text to Console using different styles.  For example input string of “style=warning|This is a warning!” will reproduce text “This is a warning” with red background and white foreground colors.  Since our app is extensible we can create new style pluins at any time, place them in appropriate folder, and start using new styles without ever having to recompile our main app.

In order to achieve this, let’s first define an interface that all our plugins must implement:

public interface IStyledConsoleWriter
{
    void Write(string text);
}

Since our app is extensible, we can have many plugins that implement IStyledConsoleWriter.  How shall the code then know at runtime which plugin to use for which style?  That’s super easy with MEF!  All we have to do is define a metadata interface that will tell our code which plugin to load:

public interface IStyledConsoleWriterMetadata
{
    string StyleName { get; }
}

Once we have these two interfaces, we can create as many plugins as we need using these interfaces such as follows:

[Export(typeof(IStyledConsoleWriter))]
[ExportMetadata("StyleName ", "warning")]
public class StyleProcessor : IStyledConsoleWriter
{
    public string Write(string text)
    {
        Console.BackgroundColor = ConsoleColor.Red;
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine();
        Console.ResetColor();
    }
}

In our main app, we can define a variable such as this:

[ImportMany]
private IEnumerable< Lazy<IStyledConsoleWriter, IStyledConsoleWriterMetadata>> _plugins;

Once MEF does it’s magic, the _plugins variable will allow us to enumerate through all plugins and use the one suitable for our need.  In order for MEF to do it’s magic we need to initialize it like this:

AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetEntryAssembly()));
var container = new CompositionContainer(catalog);

container.ComposeParts(this);

Essentially what we are doing in above code is that we are initializing MEF with plugins that are dynamically loaded from the same folder as our main app.  Once the above code executes, our _plugins enumerable is initialized which we can query to find the plugin that we need to use using the metadata properties in IStyledConsoleWriterMetadata.

For example, we can have a method in our main code such as this:

private void ProcessWarningStyle(string payLoad)
{
    var q = (from x in _plugins
        where x.Metadata.StyleName == “warning”
        select x.Value).FirstOrDefault();

    q.Write(payLoad);
}

The above code queries our _plugins enumerable to find a plugin that implements the warning style.  Once we find such plugin, we call it’s Write method to write to Console with that style.  That’s it!

There is definitely much more you can do with MEF, but hopefully this will get you started quickly. If you would like to dig deep, you can refer to the official MEF documentation.


Viewing all articles
Browse latest Browse all 11

Trending Articles