Managed Add-In Framework

June 16th, 2008

In this post I will describe the basics of MAF to quickly introduce this framework.

The Managed Add-In Framework is an Add-In architecture built on top of the .Net Framework aimed to address the following problems:

  • Loading/Unloading
  • Sandboxing (Add-ins can be sandboxed to a particular security permission set)
  • Isolation (isolation boundary between the Host and the Add-ins)
  • Lifetime Management
  • Discovery
  • Activation
  • Backwards compatibility
  • Forwards compatibility
  • Isolation changes (moving from AppDomain to Process isolation boundaries)
  • Sharing (taking an add-in built for one application and running it in another)

A MAF solution usually have seven types of projects:

  • Host: The main application that supports extensibility and manages the add-ins.
  • Host View: Defines the functionalities that the host expects from the add-ins. The host will work against this view directly.
  • Host Side Adapter: This is the glue between the Host View and the Contract. It has adapter classes that are used to convert to and from the host views and the contracts.
  • Contract: The interfaces used to communicate between Host and Add-Ins.
  • Add-In Side Adapter: This is the glue between the Add-In View and the Contract. It has adapter classes that are used to convert to and from the Add-In views and the contracts.
  • Add-In View: Represents the Add-In view of the methods and object types used to communicate with the host.
  • Add-In: An assembly loaded by the host to extend functionalities.

For more details about contracts and adapters go to this post: PDC05 - Managed AddIn Framework (MAF)

As you can deduce from the next picture the Host only references to the Host View and the Add-In only references to the Add-In view, so, each part hast its own view of the contract. In this way, if there is a new contract, it’s just necessary create new adapters to allow forward and backward compatibility.


If you are thinking that it is too much effort to create so many projects I have good news for you, there is an Add-In for Visual Studio that generates the Add-In View, Add-In Adapter, Host View and the Host Adapter from the Contract project. You can find the add-in here: Pipeline Builder.

Creating a contract

The first step to create a extensible host is to define a Contract. To do this you have to create a project with an Interface to define the functionalities that the host will expect from the add-ins. This interface have to derive from IContract and have to be marked with the AddInContract attribute. This is an example of an Contract:
using System;
using System.AddIn.Pipeline;
using System.AddIn.Contract;

namespace Contracts
{
  [AddInContract]
  public interface IHelloMAFContract : IContract
  {
    string SayHelloMAF();
  }
}

Then you can generate the basic Adapters and Views for the Host and Add-Ins using the Pipeline Builder.

The projects in a MAF solution should follow a defined file structure, for the Contract project, a possible output directory can be: “..\output\Contracts\”. You can find more details about the directory requirements in this topic: Pipeline Development Requirements.

Creating an Add-In

To create an Add-In, you just have to create a project with a class implementing the contract from the AddInView project and marked with the AddIn attribute. The following is an example AddIn implementation:
using System;
using System.AddIn;
using Contracts.AddInViews;

namespace AddInV1
{
  [AddIn("AddInV1", Version="1.0.0.0")]
  public class AddInV1 : IHelloMAF
  {
    public string SayHelloMAF()
    {
      return “Hello MAF!!”;
    }
  }
}

This project may be generated in the directory “..\Output\AddIns\AddInName\”.

Discovering and activating the Add-Ins

To discover the available Add-Ins the host can obtain a list of tokens that represents all the available Add-Ins of a specific type in a specific location. These tokens contains the Add-Ins information such as name and version, with that information then the host can decide which Add-Ins activate.

This is a sample code snippet for discovering and activating add ins:
static void Main()
{
  // In this sample we expect the AddIns and components to
  // be installed in the current directory
  String addInRoot = Environment.CurrentDirectory;

  // Check to see if new AddIns have been installed
  AddInStore.Rebuild(addInRoot);

  // Look for Calculator AddIns in our root directory and
  // store the results
  Collection tokens =
  AddInStore.FindAddIns(typeof(Calculator), addInRoot);

  // Ask the user which AddIn they would like to use
  AddInToken calcToken = ChooseCalculator(tokens);

  // Activate the selected AddInToken in a new AppDomain set sandboxed
  // in the internet zone
  Calculator calculator = calcToken.Activate(AddInSecurityLevel.Internet);

  // Run the read-eval-print loop
  RunCalculator(calculator);
}

Further readings

Leave a Reply