How to work with the Managed Extensibility Framework in C#

The Managed Extensibility Framework in .Net avoids fragile hard dependencies in your code and builds applications that are loosely coupled, lightweight, and extensible

MEF

The MEF (Managed Extensibility Framework) is a component that comes with .Net Framework 4 (or beyond) and helps you to build applications that are lightweight and extensible by adopting a loosely-coupled plugin-like architecture. You can take advantage of this framework to discover and leverage extensions sans the need of any configuration. In using MEF you can improve the flexibility, maintainability and testability of your applications with ease. When using MEF, you can reuse the extensions within the same application or, even across applications.

The MSDN states: "The Managed Extensibility Framework or MEF is a library for creating lightweight, extensible applications. It allows application developers to discover and use extensions with no configuration required. It also lets extension developers easily encapsulate code and avoid fragile hard dependencies. MEF not only allows extensions to be reused within applications, but across applications as well."

DI, IoC, and MEF

DI (Dependency Injection) is a realization of the IoC (Inversion of Control) principle. It states that when an object is dependent on other objects, such objects should be created using a separate framework or component. While IoC is the ability of varying the implementation of a contract, DI is the ability to provide the necessary implementation when asked for. Note that you should use IoC containers when your dependencies are static -- if they are dynamic, MEF is much more useful. Basically, the DI containers provide support for Object Composition, Lifetime Management, and Interception.

Contrary to a typical dependency injection container like Unity, NInject, Castle Windsor MEF provides support for object composition only. MEF provides you a way to extend plug-ins - a feature that the typical IOC containers don't provide support for.

MEF is a managed library included as part of the recent versions of .Net Framework (since .Net Framework 4 to be more precise) to discover extensions through composition without the need of any configuration. A component in MEF is known as a part. A part specifies its dependencies and capabilities declaratively. These dependencies are known as "Imports" and the capabilities are represented via "Exports". Note that a part should have an “Export” attribute mentioned.

Getting started

When working with MEF, you can use any one of the two approaches. These include: the attribute based and convention based approaches. When using the former, you would typically take advantage of attributes on your code. On the contrary, in the latter you would want to create a set of rules and then determine the rules that apply and those rules that don't apply. In this example we will explore the first approach.

MEF provides you extensibility through a plug-in framework. The System.Composition namespace provides support for MEF in .Net. To get started using MEF in your application, you should include the System.Composition assembly as a reference to your project.

Now, consider the following interface named ILogger given below.

public interface ILogger

   {

       string Message { get; set; }

   }

The following classes FileLogger and DbLogger implement the ILogger interface.

[Export]

   public class FileLogger : ILogger

   {      

       public string Message

       {

           get;set;

       }

   }

[Export]

   public class DbLogger : ILogger

   {

       public string Message

       {

           get; set;

       }

   }

At first glance you might assume that MEF is like a DI container. However, although MEF looks like a DI container, it mainly aims at extensibility. In essence, MEF takes advantage of an attribute based discovery mechanism to promote extensibility sans the need of configuring the components. You don't need any registration -- you just need to mark your types with the Export attribute and it does all for you. Unlike Unity, when using MEF, you can just mark your classes using attributes without the need of registering them individually. The exported values are all stored in a container. The following class shows how you can build a custom MEF container and store inside it all the exports from the directory where the current executing assembly resides.

public static class MEFContainer

   {

       private static CompositionContainer compositionContainer = null;

       public static CompositionContainer Container

       {

           get

           {

               if (compositionContainer == null)

               {

                   var directoryCatalog =

                        new DirectoryCatalog(

                       Path.GetDirectoryName(

                       Assembly.GetExecutingAssembly().Location));

                   compositionContainer = new CompositionContainer(directoryCatalog);

               }

               return compositionContainer;

           }

       }

   }

The following code snippet illustrates how you can retrieve an instance of type FileLogger via the container.

FileLogger fileLogger = MEFContainer.Container.GetExportedValue<FileLogger>();

Similarly, to retrieve an instance of type DbLogger, you can use the following code snippet.

DbLogger dbLogger = MEFContainer.Container.GetExportedValue<DbLogger>();

Copyright © 2016 IDG Communications, Inc.