Tuesday, 7 April 2015

Dynamically Importing multiple functionality using MEF (Managed Extensibility Framework)

Using Managed Extensibility Framework (MEF) we can create lightweight, extensible applications without much of a fuzz.  It is a pretty good tools for IoC and can be easily use as a good DI component as well.

Following is a very simple example of using MEF create simple message service which include many variations.

First of all you need to import the assembly System.ComponentModel. This is the assembly that contains all the beauty of MEF.

We would be creating a very simple console application just to demonstrate the  principle.

The Program class is looks as follows.

    class Program
    {
        static void Main(string[] args)
        {
           DynamicLoad();
        }

        private static void DynamicLoad()
        {
            var testDynamicMessaging = new DynamicMessaging();
            testDynamicMessaging.Run();

            Console.ReadLine();
        }
      
    }

This class is very simple. Just invoking the method Run in the DynamicMessaging class.
DynamicMessaging looks as follows.
 internal class DynamicMessaging
    {
        [ImportMany]
        public IEnumerable Messages { get; set; }
        public void Run()
        {
          Compose();
          foreach (var messenger in Messages)
          {
              messenger.Send("Hi");
          }

        }
        
        private void Compose()
        {
          var assemblyCatalog = new AssemblyCatalog(GetType().Assembly);
          var container = new CompositionContainer(assemblyCatalog);

          container.ComposeParts(this);

        }
    }
There are few important points in this class as follows. 1. ImportMany attribute enables importing many interfaces to the enumerable property Messages. 2. We are creating an assembly catalog and using that when creating the CompositionContainer. 3. When composing parts, we are just passing the current object only. (this) . But if we are not going to load multiple interfaces , the code would looks as follows. ie: only the object type we need.
 var container = new CompositionContainer();
 container.ComposeParts(this, new SpecificMessenger());
Finally the implemented messenger classes are looks like follows.
[Export(typeof(IMessenger))]
    class EMailMessenger : IMessenger
    {
        public void Send(string message)
        {
            Console.WriteLine("This is from the email Messenger " + message  );
        }
    }

 [Export(typeof(IMessenger))]
    class TextMessenger : IMessenger
    {
        public void Send(string message )
        {
            Console.WriteLine("This is from the text messenger " +  message);
        }
    }

No comments:

Post a Comment