Documentation

Create Managed Extensibility Framework (MEF) Plug-Ins

What Is MEF?

The Managed Extensibility Framework (MEF) is a library for creating lightweight, extensible applications.

Why Use MEF?

When working with .NET applications, it is typically necessary to specify which .NET components should be loaded.

Keeping the application updated with hard-coded names and locations of .NET components rapidly becomes a maintenance issue, especially if the updating is to be done by an end user who may not be familiar with the technical aspects of the application.

MEF allows you to create a plug-in framework for your application or use an existing framework with no required preconfiguration. It lets you avoid hard-coded dependencies and reuse extensions within and across applications. Using MEF lets you avoid recompiling applications, such as Microsoft® Silverlight™, for which source code is generally unavailable.

How Does MEF Work?

MEF provides a way for .NET components to be automatically discovered. It does this by using MEF components called parts. Parts declaratively specify dependencies (imports) and capabilities (exports) through metadata.

An MEF application consists of a host program that invokes functions defined in MEF parts. MEF Parts that implement the same interface export functions with identical names. These parts all participate in a common framework.

Each part implements an interface; often times, many parts implement the same interface. Parts that implement the same interface export functions with identical names that can be used over a variety of applications. MEF parts that implement the same interface must have descriptive, unique metadata.

The MEF host examines each part's metadata to determine which to load and invoke.

MEF parts are similar to MATLAB® MEX files—each MEX file dynamically extends MATLAB just as parts dynamically extend .NET components.

For More information About MEF

For up-to-date information regarding MEF, refer to the MSDN article “Managed Extensibility Framework.”

MEF Prerequisites

Before running this example, keep the following in mind:

  • You must be running at least Microsoft Visual Studio® 2010 to create MEF applications. If you can't use Microsoft Visual Studio 2010, you can't run this example code, or any other program that uses MEF. End Users do not need Microsoft Visual Studio 2010 to run applications using MEF.

  • You must be running at least Microsoft .NET Framework 4.0 to use the MEF feature.

  • If you want to use MEF, the easiest way to do so is through the type-safe API.

Addition and Multiplication Applications with MEF

This MEF example application consists of an MEF host and two parts. The parts implement a very simple interface (ICompute) which defines three overloads of a single function (compute).

Each part performs simple arithmetic. In one part, the compute function adds one (1) to its input. In the other part, compute multiplies its input by two (2). The MEF host loads both parts and calls their compute functions twice.

To run this example, you’ll create a new solution containing three projects:

  • MEF host

  • Contract interface assembly

  • Strongly-typed metadata attribute assembly

Implementing MEF requires the expertise of a .NET Developer because it requires performing a number of advanced programming tasks.

 Where To Find Example Code for MEF

To deploy an MEF-based component, follow this general workflow:

Create an MEFHost Assembly

  1. Start Microsoft Visual Studio 2010.

  2. Click File > New > Project.

  3. In the Installed Templates pane, click Visual C# to filter the list of available templates.

  4. Select the Console Application template from the list.

  5. In the Name field, enter MEFHost.

  6. Click OK. Your project is created.

  7. Replace the contents of the default Program.cs with the MEFHost.cs code. For information about locating example code, see “Where to Find Example Code,” above.

  8. In the Solution Explorer pane, select the project MEFHost and right-click. Select Add Reference.

  9. Click Assemblies > Framework and add a reference to System.ComponentModel.Composition.

  10. To prevent security errors, particularly if you have a non-local installation of MATLAB, add an application configuration file to the project. This XML file instructs the MEF host to trust assemblies loaded from the network. If your project does not include this configuration file, your application fails at run time.

    1. Select the MEFHost project in the Solution Explorer pane and right-click.

    2. Click Add > New Item.

    3. From the list of available items, select Application Configuration File.

    4. Name the configuration file App.config and click Add.

    5. Replace the automatically-generated contents of App.config with this configuration:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
          <runtime>
            <loadFromRemoteSources enabled="true" />
          </runtime>
        </configuration>
      

You have finished building the first project, which builds the MEF host.

Next, you add a C# class library project for the MEF contract interface assembly.

Create a Contract Interface Assembly

  1. in Visual Studio, click File > New > Project.

  2. In the Installed Templates pane, click Visual C# to filter the list of available templates.

  3. Select the Class Library template from the list.

  4. In the Name field, enter Contract.

    Note

    Ensure Add to solution is selected in the Solution drop-down box.

  5. Click OK. Your project is created.

  6. Replace the contents of the default Class1.cs with the following ICompute interface code:

    namespace Contract
    {
    		public interface ICompute
    		{
        	double compute(double y);
       		double[] compute(double[] y);
       		double[,] compute(double[,] y);
    		}
    	}

You have finished building the second project, which builds the Contract Interface Assembly.

Since strongly-typed metadata requires that you decorate MEF parts with a custom metadata attribute, in the next step you add a C# class library project. This project builds an attribute assembly to your MEFHost solution.

Create a Metadata Attribute Assembly

  1. in Visual Studio, click File > New > Project.

  2. In the Installed Templates pane, click Visual C# to filter the list of available templates.

  3. Select the Class Library template from the list.

  4. In the Name field, enter Attribute.

    Note

    Ensure Add to solution is selected in the Solution drop-down box.

  5. Click OK. Your project is created.

  6. In the generated assembly code, change the namespace from Attribute to MEFHost. Your namespace code should now look like the following:

  7. In the MEFHost namespace, replace the contents of the default class Class1.cs with the following code for the ComputationTypeAttribute class:

    using System.ComponentModel.Composition;
    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
    public class ComputationTypeAttribute: ExportAttribute
    {
        public ComputationTypeAttribute() : 
                base(typeof(Contract.ICompute)) { }
        public Operation FunctionType{ get; set; }
        public double Operand { get; set; }
    }
    
    public enum Operation
    {
        Plus,
        Times
    }
    

  8. Navigate to the .NET tab and add a reference to System.ComponentModel.Composition.dll.

Add Contract and Attributes References to MEFHost

Before compiling your code in Microsoft Visual Studio:

  1. In your MEFHost project, add references to the Contract and Attribute projects.

  2. In your Attribute project, add a reference to the Contract project.

Compile Your Code in Microsoft Visual Studio

Build all your code by selecting the solution name MEFHost in the Solution Explorer pane, right-clicking, and selecting Build Solution.

In doing so, you create the following binaries in MEFHost/bin/Debug:

  • Attribute.dll

  • Contract.dll

  • MEFHost.exe

Write MATLAB Functions for MEF Parts

Create two MATLAB functions. Each must be named compute and stored in separate folders, within your Microsoft Visual Studio project:

 MEFHost/Multiply/compute.m

 MEFHost/Add/compute.m

Create Metadata Files

Create a metadata file for each MATLAB function.

  1. For MEFHost/Add/compute.m:

    1. Name the metadata file MEFHost/Add/Add.metadata.

    2. In this file, enter the following metadata on one line:

      [MEFHost.ComputationType(FunctionType=MEFHost.Operation.Plus, Operand=1)] 
      
  2. For MEFHost/Multiply/compute.m:

    1. Name the metadata file MEFHost/Multiply/Multiply.metadata.

    2. In this file, enter the following metadata on one line:

      [MEFHost.ComputationType(FunctionType=MEFHost.Operation.Times, Operand=2)]
      

Build .NET Components from MATLAB Functions and Metadata

In this step, use the Library Compiler app to create .NET components from the MATLAB functions and associated metadata.

Use the information in these tables to create both Addition and Multiplication projects.

Note

Since you are deploying two functions, you need to run the Library Compiler app twice, once using the Addition.prj information and once using the following Multiplication.prj information.

Addition.prj

Project NameAddition
Class NameAdd
File to compileMEFHost/Add/compute.m

Multiplication.prj

Project NameMultiplication
Class NameMultiply
File to compileMEFHost/Multiply/compute.m
  1. Click the Library Compiler app in the apps gallery.

  2. Create your component, following the instructions in Generate a .NET Assembly and Build a .NET Application.

  3. Modify project settings ( > Settings) on the Type Safe API tab, for whatever project you are building (Addition or Multiplication).

    Project SettingAddition.prjMultiplication.prj
    Enable Type Safe API CheckedChecked
    Interface AssemblyMEFHost/bin/Debug/Contract.dll MEFHost/bin/Debug/Contract.dll
    MEF metadataMEFHost/Add/Add.metadata MEFHost/Multiply/Multiply.metadata
    Attribute AssemblyMEFHost/bin/Debug/Attribute.dll MEFHost/bin/Debug/Attribute.dll
    Wrapped ClassAddMultiply
  4. Click the Package button.

Install MEF Parts

The two components you have built are MEF parts. You now need to move the generated parts into the catalog directory so your application can find them:

  1. Create a parts folder named MEFHost/Parts.

  2. If necessary, modify the path argument that is passed to the DirectoryCatalog constructor in your MEF host program. It must match the full path to the Parts folder that you just created.

    Note

    If you change the path after building the MEF host a first time, you must rebuild the MEF host again to pick up the new Parts path.

  3. Copy the two componentNative.dlls (Addition and Multiplication) and AddICompute.dll and MultiplyICompute.dll assemblies from your into MEFHost/Parts.

    Note

    You do not need to reference any of your MEF part assemblies in the MEF host program. The host program uses a DirectoryCatalog, which means it automatically searches for (and loads) parts that it finds in the specified folder. You can add parts at any time, without having to recompile or relink the MEF host application. You do not need to copy Addition.dll or Multiplication.dll to the Parts directory.

Run the MEF Host Program

MATLAB-based MEF parts require the MATLAB Runtime, like all deployed MATLAB code.

Before you run your MEF host, ensure that the correct version of the MATLAB Runtime is available and that matlabroot/runtime/arch is on your path.

  1. From a command window, run the following. This example assumes you are running from c:\Work.

    c:\Work> MEFHost\bin\Debug\MEFHost.exe
    

  2. Verify you receive the following output:

    8 Plus 1 = 9
    9 Times 2 = 18
    16 Plus 1 = 17
    1.5707963267949 Times 2 = 3.14159265358979
    

Troubleshooting the MEF Host Program

 Do you receive an exception indicating that a type initializer failed?

 Do you receive an exception indicating that MWArray.dll cannot be loaded commonly?

 Do you receive an exception that a particular version of mclmcrrt cannot load?