This article is all about using the .NET 3.5 System.Addin namespace. This article owes much to the fabulous WPF book by Mathew McDonald (who is an uber genius in my opinion).

What this article is attempting to demonstrate is fairly simple actually.

There is an AddIn contract (INumberProcessorContract implementing IContract) that defines what all add-ins should do. There is also another Contract that specifies how the add-in should communicate back to the Host application. This Contract is called IHostObjectContract, which again implements IContract.

There is a pipeline to support the AddIn model, and finally, there is a host application that will host the add-ins. In essence, that is all this article is about.

Before I start diving into the details, it's probably worth mentioning what the add-in(s) provided by the demo application actually do. I have created several add-ins that all provide some functionality that matches the method signature defined within the AddIn INumberProcessorContract contract (implementing IContract). Basically, all the add-ins in the demo app will provide a single method that has the following signature:

List<int> ProcessNumbers(int fromNumber, int toNumber)

I have created three separate add-ns, which do various things to do with numbers:

Finobacci numbers add-in: Returns a list of Fibonacci numbers between fromNumber and toNumber.

Loop numbers add-in: Returns a list of numbers between fromNumber and toNumber

Prime numbers add-in: Returns a list of prime numbers between fromNumber and toNumber

And within the attached demo application, I wanted to show how the add-in could report progress back to the host application, so this is also part of the attached demo code.

We will now go on to discuss how the .NET 3.5 System.Addin namespace allows us to create add-ins (not easily, but it does allow it).

AddIns (sometimes called Plugins) are separately compiled components that an application can locate, load, and make use of at runtime (dynamically). An application that has been designed to use add-ins can be enhanced (by developing more add-ins) without the need for the original application to be modified or recompiled and tested (though the add-ins should be tested). For some time, .NET has allowed developers to create applications that use add-ins, but this more than likely used the System.Reflection namespace, and was probably a fair bit of work. With .NET 3.5 comes a new namespace, namely the System.Addin namespace. The .NET team has created a very flexible framework for building add-ins, this is known as the AddIn Pipeline (System.AddIn.Pipeline). By using the AddIn Pipeline, the necessary plumbing is already in place to allow the AddIn model to work. So that's a good thing. The down side to this is that you must implement at least 7 different components to implement the most basic AddIn model. The next section will discuss the AddIn pipeline concept (though it will not discuss the System.AddIn.Pipeline namespace), and shall discuss what happens in each of the 7 (minimum) components that are required in order to correctly setup an AddIn model enabled application.

Note: The AddIn model is equally at home in WinForms or WPF (and possibly ASP.NET, though I didn't try that). I shall be using WPF as I like it, though the topics discussed here after would be equally suited to working with WinForms.

The heart of the Addin model is the pipeline. The pipeline is a chain of components that allows the application to communicate with the add-in. At one end of the pipeline is the Host Application, and at the other end is the add-in, and in between are five other components that facilitate the add-in operation and interaction. Consider the following diagram:

At the center of this figure is the Contract (implements System.AddIn.Contract.IContract), which includes one or more interfaces that define how the host application and the add-ins can interact. The Contract can also include serializable types that are planned to be used between the host application and the add-in. Microsoft designed the AddIn model with extensibility in mind, and as such, both the host application and the actual add-in don't actually use the Contract directly; rather they use their own respective versions of the Contract, called Views. The host application uses the host view, while the add-in uses the AddIn view. The views normally contain an abstract class that reflects the interfaces in the Contract interface (though the View doesn't inherit from the Contract or implement the System.AddIn.Contract.IContract interface).

Although the Views and the Contract have similar method signatures, they are totally separate; it's up to the Adapters to join them together. There are two Adapters: one for the host application which inherits from the abstract host view class, whilst the AddIn adapter inherits from System.AddIn.Pipeline.ContractBase and the actual application specific interface that is defined in the Contract component. One thing to note here is that because the AddIn adapter inherits from System.AddIn.Pipeline.ContractBase, which in turn inherits from MarshalByRefObject (MarshalByRefObject enables access to objects across application domain boundaries in applications that support Remoting), the add-in is allowed to cross application domain boundaries.

The flow is something like this:

The host application calls one of the methods in the host view. But the host view is really an abstract class. What is actually happening is that the host application is really calling a method on the host adapter though the host view. This is possible as the host adapter inherits from the host view.

The host adapter then calls the correct method in the contract interface, which is implemented by the AddIn adapter.

The AddIn adapter calls a method in the AddIn View. This method is implemented by the add-in that actually does the work.

Consider the following figure for a single add-in within the pipeline:

This diagram shows what the pipeline would look like for a single add-in. If we wish to create more add-ins (as the demo application does), we simply need to create more concrete classes that inherit from the abstract AddIn View class.

The AddIn model relies on a strict directory structure. However, the required directory structure is actually separate from the application, so it's fine to have the projects elsewhere as long as they build to a common folder. For example,s the demo application uses an Output folder under the solution, which must have the following subfolders:

The AddinIns folder above must also have a separate folder for each available add-in, as shown below (using the three add-ins for the demo application):

This folder structure is not optional at all. It must be exactly as shown in the order for the AddIn model to work correctly. This example assumes that the host application is deployed in the Output folder.

As the AddIn model file structure is mandatory, if you leave out or misname a particular project, you will get a runtime Exception. Here is a step by step Visual Studio guide of how I managed to get the demo application to work.

Create a top level directory to hold all the seperate components. I called mine AddInTest.

Create either a WinForms or WPF based host application. It doesn't matter what it is called, but it must be placed in the top level folder from step 1.

Add a new Class Library project for each pipeline component. You will also need to create a project for at least one add-in component. This should give you something like the following within Visual Studio (note there are actually three add-ins in the solution shown here):

Next, you need to create a build directory in the top level directory (AddInTest\ for the demo app). This is where the AddIn pipeline components will be placed once they are compiled. This folder is called "Output" in the demo application.

As each of the pipeline components is constructed and built, you will need to modify the build path to point to the relevant subdirectory underneath the top level build folder. This is shown in the figure below (which we saw earlier):

The build path can be changed using Visual Studio by right clicking the project and getting up the project settings. See the figure below:

There is one last issue that you have to be aware of when building AddIn enabled applications. There will obviously be a need to reference one or more of the AddIn pipeline components within another pipeline component project. However, as the AddIn model relies on the strict mandatory file structure mentioned above, when adding a reference to another of the pipeline components, care needs to be taken that the referenced DLL is not copied, such that the AddIn model will only ever use the DLL that is found within the related AddIn model file system folder. To make sure this all works as expected, we need to make sure that any referenced pipeline DLL is set with the "Copy Local" property set to "False". This ensures that the correct file system placed DLL is used within the host application. Basically, the host application looks for the various components at certain file system locations. The "Copy Local" property may be changed by clicking on the referenced DLL and examining the value of the "Copy Local" property within the property grid. If it is set to "True", this needs to be changed to "False" for any referenced pipeline component. Let's see an example of that.

The following figure shows this for the Contract DLL when referenced within the HostSideAdapter project:

This simply contains two classes. The NumberProcessorViewToContractAdapter class allows the AddIn adapter to to interact with the View and the Contract. Whilst the HostObjectContractToViewAddInAdapter class allows the AddIn adapter to interact with the Host view. In this case, this allows the AddIn to report progress.

This simply contains two classes. The NumberProcessorContractToViewHostAdapter class allows the Host side adapter to interact with the host View. Whilst the HostObjectViewToContractHostAdapter class allows the Host adapter to interact with the Host view, which in this case allows the AddIn to report progress.

This simply contains two abstract classes. The NumberProcessorAddInView class is inherited by any AddIn concrete class. Whilst the HostObject is inherited by an object that needs to communicate between the host Contract and View adapter.

This simply contains two abstract classes. The NumberProcessorHostView class is inherited by any host side adapter concrete class. Whilst the HostObject is inherited by a class within the host application that can make use of the reported progress.

namespace HostView
{
///<summary>/// Abstract base class that should be inherited by the Host view
///</summary>publicabstractclass NumberProcessorHostView
{
publicabstract List<int> ProcessNumbers(int fromNumber, int toNumber);
publicabstractvoid Initialize(HostObject host);
}
///<summary>/// Abstract base class that should be inherited by a class within the host
/// application that can make use of the reported progress
///</summary>publicabstractclass HostObject
{
publicabstractvoid ReportProgress(int progressPercent);
}
}

This is the WinForms or WPF (WPF, in this case) application that is hosting the AddIns found. It is also responsible for calling the selected add-in's methods, and allows the add-in to report progress by using an internal class AutomationHost which inherits from the HostView.HostObject class.

As I stated, this is WPF (but could be WinForms); the UI is not important and is a throw away. However, it looks like this:

Where there is a list of add-ins found, and then the user is able to apply the add-ins. This probably needs a little bit of an explanation. There is a class called AddInStore which allows the .NET code to rebuild the add-in list. This results in a new file being created on the file system.

The AddInStore also allows the app code to find add-ins. So this is exactly what I do with the following lines, where the add-ins are refreshed and then added to a ListBox:

So that really only leaves the add-in concrete classes themselves; these are fairly trivial (you'll be pleased to hear... as the add-in model is fairly scary, and not for the faint hearted, and without Mathew McDonald's excellent book on WPF, I could not have written this article). So, let's see the add-in's code.

As you can see, this is a complicated arrangement, and it is quite a lot to get your head around, and quite a lot of work. The CLR AddIn team has listened to initial concerns that this model is too much work, and have dedicated a CodePlex page to a Visual Studio AddIn that aids in the development of creating AddIn enabled apps. They also supply a blank AddIn pipeline project for you to start with. The VS AddIn aids in the creation of both the host and AddIn side adapters. The CLR AddIn team's CodePlex page can be found at the following link: Managed Extensibility and Add-In Framework.

I think it's fair to say that the AddIn model is not that easy to understand, but this example shows you most of what you will need to know. I have not included all the code in this article, I have tried to only include what I consider to be the most important parts (Nish, if you are reading, see I've listened to you) of the code. As such, you will need to refer to the article's demo application in order to understand the full workings of the AddIn model. I hope you learnt something from this article, and if you liked it, please leave a vote for it.