Tag Archives: Export

Introduction to MEF Programming – Importing Multiple Objects

Importing Multiple Objects

In the previous blog, we discussed the basic MEF attributes. Let us get into advance topics in MEF step by step.

In the previous example, we wrote the code for the main exe, contract library and MEF Part1. Imagine we have another class derived from IGreeting and implements the SayHelloWorld() function. The class diagram and sequence diagram is shown below.

image

Fig: Class diagram of the participating classes.

image

Fig: Sequence Diagram for the above classes

In the previous blog, i posted the code of all the participating classes. Let us add the new UserGreetingClass to the solution.

Coding the MEFPart2 Library:

  1. Add a New Project –> Visual C# –> Class Library.Enter Name as  MEFPart2. Click OK. Add the following code.
  2. Add a reference to the System.ComponentModel.Composition assembly.
  3. Add a reference to the ContractsLibrary.DLL assembly.
  4. Add the following using statement:
    • using System.ComponentModel.Composition; This allows us to specify the attributes for using MEF.
    • using ContractsLibrary;
  5. Add the following code.
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using ContractsLibrary;
  5.  
  6. namespace MefLabPart2
  7. {
  8.     [Export(typeof(IGreeting))]
  9.     public class UserGreeting : IGreeting
  10.     {
  11.         public string SayHelloWorld()
  12.         {
  13.             return "Hello " + Environment.UserDomainName;
  14.         }
  15.     }
  16. }

 

Compile the solution and copy the  MEFPart2.DLL to the MainExe\bin\Debug folder, where the MainExe.exe is located. Try running the application. The following error mesage comes up in the console.

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) More than one export was found that matches the constraint ‘((exportDefinition.ContractName == "ContractsLibrary.IGreeting") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "ContractsLibrary.IGreeting".Equals
(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))’.

Resulting in: Cannot set import ‘meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting")’ on part ‘meflab1.Program’. Element: meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting") –>  meflab1.Program

Press any key to continue . . .

The issue here is that the catalog contains two exports and the import is importing only one export. So when the container tries to match the imports and exports, it fails with the above error.

image

Fig: Debug information of the catalog.

The Import attribute will only be successfully composed when it matches one and only one export. Other cases will produce a composition error. An ordinary ImportAttribute attribute is filled by one and only one ExportAttribute. If more than one is available, the composition engine produces an error. To import more than one export that matches the same contract, use the ImportMany attribute. Imports marked with this attribute are always optional. For example, composition will not fail if no matching exports are present. The following class imports any number of exports of type IGreeting.

  1. class Program
  2. {
  3.     [ImportMany]
  4.     public IEnumerable<IGreeting> Greetings { get; set; }

 

Following is the code of the MainExe project.

using System; 
using System.IO; 
using System.Reflection; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 
//using System.ComponentModel.Composition.Primitives; 
using ContractsLibrary; 
using System.Collections.Generic; 
  
  
  
namespace meflab1 
{ 
    class Program 
    { 
      [ImportMany] 
      public IEnumerable<IGreeting> Greetings { get; set; } 
  
        static void Main(string[] args) 
        { 
            Program program = new Program(); 
            program.Run(); 
        } 
  
        public Program() 
        { 
            try 
            { 
                AggregateCatalog aggregatecatalogue = new AggregateCatalog(); 
                aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)); 
                CompositionContainer container = new CompositionContainer(aggregatecatalogue); 
                CompositionBatch batch = new CompositionBatch(); 
                batch.AddPart(this); 
                container.Compose(batch); 
            } 
            catch (FileNotFoundException fnfex) 
            { 
                Console.WriteLine(fnfex.Message); 
            } 
            catch (CompositionException cex) 
            { 
                Console.WriteLine(cex.Message); 
            } 
        } 
  
        void Run() 
        { 
            foreach (var mgreeting in Greetings) 
            { 
                if (mgreeting != null) 
                { 
                    Console.WriteLine(mgreeting.SayHelloWorld()); 
                    Console.ReadKey(); 
                } 
            } 
        } 
    } 
} 

 

Source Code is available at :

Microsoft: http://cid-38ecce05b21b8b44.office.live.com/self.aspx/MY%20Projects/mef%202.zip

(OR) Google: MEF Lab 2 (http://code.google.com/p/mef-dotnet/downloads/detail?name=mef%202.zip)

Have Fun !!!

 “If your actions inspire others to dream more, learn more, do more and become more, you are a leader.”

Introduction to MEF Programming

In the previous blog post, we discussed the MEF Architecture in detail. Let us start writing some code using MEF in C#.net. First things first, you need the current version of .NET Framework 4.0 and visual Studio 2010 to write code.

Note: For the UML diagrams, i am using the diagrams provided in the Architecture menu of Visual Studio 2010 Ultimate Edition. VS 2010 is not as powerful as Rational Rose or Enterprise Architect but you can design the basic UML diagrams.

Composition Basics:

Compose means To put things together to form a whole. Composition is used for objects that have a has-a relationship to each other. For ex, A car has-an engine, and has-a transmission, etc. A personal computer has-a CPU, has-a motherboard, etc.. we have designed classes that are composed of member variables which are built-in data types (eg. int, double, string, etc). Well, this is also an example of composition.

For ex, in C++, imagine we have the following two classes.

  1. class Class1
  2. {
  3.     ……….
  4.     ……….
  5. }

 

  1. class Class2
  2. {
  3.     public:
  4.             Class1 mobjclass1;        
  5.     ……….
  6.     ……….
  7. }

 

image   Fig: Composition relationship between class1 and class2. Class2 has a object of Class1.

The black diamond represents composition. It is placed on the Class2 class because it is the Class2 that is composed of a Class1. The arrowhead on the other end of the relationship denotes that the relationship is navigable in only one direction. That is, Class1 does not know about Class2. Composition is great but the disadvantage is that we introduce tight coupling (line 4 in Class2) resulting in higher code maintenance cost and difficult to extend the class for additional functionality.

prologue to MEF:

Ok, Let’s start with the most simple example: Hello World!!!

image Fig: Relationship diagram between the two classes

Let us assume a class SimpleGreetingClass, which has a member function public string SayHelloWorld(), which returns "Hello World !!!" string. Let us assume another class Program, which has an attribute SimpleGreetingClass mobjsimplegreetingclass.  Ones we create the object mobjsimplegreetingclass, we can call the member function SayHelloWorld() using this object. Following is the code for the same.

namespace MEFLab1
{
    public class SimpleGreetingClass
    {
        public string SayHelloWorld()
        {
            return "Hello World !!!";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Program program = new Program();
            program.Run();
        }

        void Run()
        {
            SimpleGreetingClass mobjsimplegreetingclass = new SimpleGreetingClass();
            Console.WriteLine(mobjsimplegreetingclass.SayHelloWorld());
            Console.ReadKey();
   
        }
    }
}

 

As we can see, there is a tight coupling between the SimpleGreetingClass and Program class. Also, the Program class must be aware of SimpleGreetingClass during the compilation time. Well, there are many disadvantages in this kind of design.

One of the USP (Unique Selling Point) of MEF is to solve this kind of tight coupling problem. Let us dive deep into MEF Programming and see how MEF solves this issue and other problems in the software world.

Enter the world of MEF:

The ABC’s of MEF are

  • Export it.
  • Import it.
  • Compose it.

Well, I am going to use some design pattern techniques  along with MEF as I always promote the best practices of software design in my architecture. Please observe the changes in the class diagram from the previous example. I used the IGreeting interface as it is a good practice to expose your contracts through interface (Facade Design Pattern). Our SimpleGreetingClass inherits IGreeting interface. This is the technique for Decoupling Implementation using an Interface. With out this, a tightly coupled relationship will be  formed between participating classes. This limits extensibility options as well as testability of the class itself. MEF allows imports to be decoupled from the exporter’s implementation by using an interface as the contract.

image  Fig: UML Class Diagram of the participating classes.

The source code can be downloaded from Google or Microsoft at  http://code.google.com/p/mef-dotnet/downloads/detail?name=MEFLab1.zip or from the link http://cid-38ecce05b21b8b44.office.live.com/self.aspx/MY%20Projects/MEFLab1.zip. Below is the detailed explanation of each of the projects present in solution1 in the attached zip file.

Coding the Interface Library :

  1. Create New Solution using VS 2010.
  2. Add a New Project –> Visual C# –> Class Library.Enter Name as  ContractsLibrary. Click OK. Add the following code.
  3. Here we are just creating an interface IGreeting so that the host application that can accept components through the IGreeting interface.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ContractsLibrary
{
    public interface IGreeting
    {
        string SayHelloWorld();
    }
}

 

Coding the MEFPart1 Library:

  1. Add a New Project –> Visual C# –> Class Library.Enter Name as  MEFPart1. Click OK. Add the following code.
  2. Add a reference to the System.ComponentModel.Composition assembly.
  3. Add a reference to the ContractsLibrary.DLL assembly.
  4. Add the following using statement:
    • using System.ComponentModel.Composition; This allows us to specify the attributes for using MEF.
    • using ContractsLibrary;
  5. Add the following code.
using System.ComponentModel.Composition;
using ContractsLibrary;

namespace MEFPart1
{
    [Export(typeof(IGreeting))]
    public class SimpleGreetingClass : IGreeting
    {
        public string SayHelloWorld()
        {
            return "Hello World !!!";
        }
    }
}

Here, MEF makes this piece of code available to other components as it is specified(decorated) with attribute [Export]. We know that the contract consists of a string, called the contract name, and the type of the exported or imported object, called the contract type. Only if both the contract name and contract type match is an export considered to fulfill a particular import. Let us examine the line [Export(typeof(IGreeting))] ; the contract type is IGreeting because it is specified as a parameter of the Export attribute. The exported type must be either the same as the contract type, derive from the contract type, or implement the contract type if it is an interface. In this export, the actual type SimpleGreetingClass implements the interface IGreeting.

So in this case, the contract type will be IGreeting, and the contract name will be a unique string created from the contract type. In other words, the contract name will match only exports whose names are also inferred from the type IGreeting.

Coding the MainExe:

  1. Add a New Project –> Visual C# –> Console Application.Enter Name as  MainExe. Click OK. Add the following code.
  2. Add a reference to the System.ComponentModel.Composition assembly.
  3. Add a reference to the ContractsLibrary.DLL assembly.
  4. Add the following using statement:
    • using System.ComponentModel.Composition; This allows us to specify the attributes for using MEF.
    • using System.ComponentModel.Composition.Hosting;
    • using ContractsLibrary;
  5. Add the following code.
using System;
using System.IO;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
//using System.ComponentModel.Composition.Primitives;
using ContractsLibrary;
using System.Collections.Generic;


namespace meflab1
{
    class Program
    {
        [Import(typeof(IGreeting))]
        public IGreeting Greetings { get; set; }

        static void Main(string[] args)
        {
            Program program = new Program();
            program.Run();
        }

        public Program()
        {
            try
            {
                AggregateCatalog aggregatecatalogue = new AggregateCatalog();
                //aggregatecatalogue.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
                aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));

                CompositionContainer container = new CompositionContainer(aggregatecatalogue);
                container.ComposeParts(this);
    
            }
            catch (FileNotFoundException fnfex)
            {
                Console.WriteLine(fnfex.Message);
            }
            catch (CompositionException cex)
            {
                Console.WriteLine(cex.Message);
            }
        }

        void Run()
        {
            if (Greetings != null)
            {
                Console.WriteLine(Greetings.SayHelloWorld());
                Console.ReadKey();
            }
        }
    }
}

Observe the code

[Import]

public IGreeting Greetings { get; set; }

The [Import] attribute declares something to be an import; that is, it will be filled by the composition engine when the object is composed. Every import has a contract, which determines what exports it will be matched with. The contract can be an explicitly specified string, or it can be automatically generated by MEF from a given type, in this case the interface IGreeting. Any export declared with a matching contract will fulfill this import. In this import, the Import attribute has neither a contract type nor a contract name parameter attached. Therefore, both will be inferred from the decorated property. In this case, the contract type will be IGreeting, and the contract name will be a unique string created from the contract type. MEF will automatically assume the contract to be based on the type of the import unless you specify it explicitly. We can also code it as [Import(typeof(IGreeting))].

MEF Composition explained:

With MEFPart1 and ContractsLibrary in place, you can now start composition. MEF parts don’t automatically get discovered or created. Instead, you need to write some bootstrapping code that will enact composition. A common place to do this is in our application’s entry point, which in this case is the Program class.

To bootstrap MEF involves a few steps:

  • Add imports of the contracts you need the container to create, which i explained in the above section.
  • Create a catalog that MEF uses to discover parts.
  • Create a container that composes instances of parts.
  • Compose by calling the Composeparts method on the container and passing in the instance that has the imports.

As you can see here, I added a IGreeting import on the Program class. Then I created a DirectoryCatalog pointing to the base folder containing the MainExe. Then created a container that uses the catalog. Finally, I called Composeparts, which caused an App instance to be composed and the IGreeting import to be satisfied.

During composition, the container will create the IGreeting and satisfy its SimpleGreetingClass import. This will result in SimpleGreetingClass being created. Finally, the Application class will have its IGreeting import satisfied. In this way, MEF has assembled the entire object graph based on declarative information, rather than manually requiring imperative code to do the assembly. As i said before, container acts as a match maker.

Epilogue:

Build the solution and run the Mainexe. The console window pops up and displays the following error information.

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint ‘((exportDefinition.ContractName == "ContractsLibrary.IGreeting") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "ContractsLibrary.IGreeting".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))’, invalid exports may have been rejected.

Resulting in: Cannot set import ‘meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting")’ on part ‘meflab1.Program’. Element: meflab1.Program.Greetings (ContractName="ContractsLibrary.IGreeting") –

->  meflab1.Program

Press any key to continue . . .

The reason is that the [Import] in the MainExe could not be satisfied as there the catalog provided to the container does not have any parts.

Copy the MEFPart1.DLL to the folder containing the MainExe executable. Then run the MainExe and you can see Hello World!!! on the console window. This is because we used directory catalog and it detects all the parts present in the directory and provides it to the container to satisfy the exports and import definitions.

I will be explaining other concepts of MEF in my upcoming blog. Below is the Class Diagram and Sequence Diagram for the code that i am writing.

image

image 

“A leader takes people where they want to go. A great leader takes people where they don’t necessarily want to go, but ought to be.”

Download Source Code from: http://cid-38ecce05b21b8b44.office.live.com/self.aspx/MY%20Projects/MEFLab1.zip

Concepts in the Managed Extensibility Framework

MEF PPT 2010

A few essential concepts:

Part —A part provides services to other parts and consumes services provided by other parts. Parts in MEF can come from anywhere, from within the application or externally; from an MEF perspective, it makes no difference.

Export—An export is a service that a part provides. When a part provides an export, it is said that the part exports it. For example, a part may export a logger, or in the case of Visual Studio, an editor extension. Parts can provide multiple exports, though most parts provide a single export. Every Export has a contract, which determines what Imports it will be matched with. An export is a value (capabilities) that a part provides to other parts in the container

Import—An import is a service that a part consumes. Composable Parts declare imports through the attribute [Import]. The [Import] attribute declares something to be an import; that is, it will be filled by the composition engine when the object is composed. Every import has a contract, which determines what exports it will be matched with. An Import is a requirement (Dependencies) that a part expresses to the container, to be filled from the available exports.

Contracts—A contract is an identifier for an export or an import. The contract consists of a string, called the contract name, and the type of the exported or imported object, called the contract type. Only if both the contract name and contract type match is an export considered to fulfill a particular import. An exporter specifies a string contract that it provides, and an importer specifies the contract that it needs. MEF derives contract names from the types that are being exported and imported, so in most cases you don’t have to think about it.

Catalog – A catalog is an object that makes available parts discovered from some source. MEF provides catalogs to discover parts from a provided type, an assembly, or a directory. So basically Catalog provides the parts to the application.

Composition—Parts are composed by MEF, which instantiates them and then matches up exporters to importers. The core of the MEF composition model is the composition container, which contains all the parts available and performs composition. (That is, the matching up of imports to exports.) The most common type of composition container is CompositionContainer. In order to discover the parts available to it, the composition containers makes use of a catalog.