Working with the Managed addin framework (System.Addin)
I’m writing this post mainly as a reference for myself to remember key points regarding the Managed Addin Framework (MAF). MAF is pretty complex and a developer needs some sort of a reference guide in order to use it effectively. Thats what I’ll try and achieve with this post.
Disclaimer: I’ll be extracting quite a lot of info from msdn for this post so you might read stuff you’ve already been through before. Again, this post is only for my reference and its going to be a long one.
Before I begin let me note a few good references to the Addin Framework:
- Daniel Moth’s MAF – Part 1
- Daniel Moth’s MAF – Version Resilience – Part 2
- Detailed MSDN Coverage
- MAF at CodePlex
- Pipeline Builder
Addin pipeline:
Add-in overview:
The contract is loaded into both the host and addin app domains.
To pass through the isolation boundary any type should be serializable or should be a contract. If not a contract or a serializable type then it should be converted to one by the adapter segment in the pipeline.
The views are usually abstract base classes or interfaces which are statically bound to the host or the addin.
Developing the pipeline:
The addin side adapter and host side adapter segment convert the flow of types between the respective views and the contract.
The contract derives from IContract interface.
The diagram below depicts the segments of the pipeline requiring attributes.
Description of the pipeline segments:
Pipeline segment | Description |
Host | The application assembly that creates an instance of an add-in. |
Host view of addin | Abstract base class or interface. Represents host’s view of types and methods used to communicate with the addin. |
Host side adapter | An assembly with one or more classes that adapts methods to and from the contract. [HostAdapter] attribute. |
Contract | Interface deriving from IContract. [AddInContract] attribute |
Addin side adapter | [AddInAdapter] attribute. Each assembly in the addin side adapter directory that has this attribute is loaded into the addin’s app domain. |
Addin view | Abstract base class or interface. [AddInBase] attribute. Each assembly in the addin views directory that has this attribute is loaded into the addin’s app domain. |
Add In | A type that performs service for the host. [AddIn] |
Pipeline Activation Path:
Moving from right to left in the diagram:
1. The addin inherits the addin view.
2. The addin view is passed into the constructor of the addin side adapter.
3. The addin side adapter inherits the contract.
4. The contract is passed into the constructor of the host side adapter.
5. The host side adapter inherits the host view.
Steps involved in activation:
The host application activates the add-in with the Activate method.
The add-in, add-in view, add-in-side adapter, and the contract assemblies are loaded into the add-in's application domain.
An instance of the add-in-side adapter is created using the add-in view (with the class identified by the AddInBaseAttribute attribute) as its constructor. The add-in-side adapter inherits from the contract.
The add-in-side adapter, which is typed as the contract, is passed across the (optional) isolation boundary to the host-side adapter's constructor.
The host view of the add-in, host-side adapter, and the contract assemblies are loaded into the host's application domain.
An instance of the host-side adapter is created using the contract as its constructor. The host-side adapter inherits from the host view of the add-in.
The host has the add-in, which is typed as the host view of the add-in, and can continue calling its methods.
Attributes required:
Add-ins require AddInAttribute.
Contracts require AddInContractAttribute.
Add-in views require AddInBaseAttribute.
Add-in-side adapters require AddInAdapterAttribute.
Host-side adapters require HostAdapterAttribute.
Host view of addin is the type passed to AddInStore.FindAddIns method meaning this type need not be discovered, hence no attribute required.
Pipeline Directory Structure:
Important:
The host application and the host view of the add-in pipeline segment are typically deployed in the same directory, which can be at any location. The host application requires a reference to the host view of the add-in segment that represents the add-in to activate.
You are not required to have add-ins in the pipeline directory structure. If they are not in the pipeline directory structure, you must call the AddInStore.UpdateAddIns method or the RebuildAddIns method that takes the path to the containing directory of the add-ins as its parameter.
Change the Output path for the pipeline segments to their respective directories in the pipeline directory structure.
Pipeline deployment:
Pipeline Segment References in Visual Studio:
When adding references from one segment to another make a reference to the segment’s project instead of the assembly.
To add a project reference:
In Solution Explorer, right-click the References folder and choose Add Reference.
On the Projects tab, choose the desired project and click OK.
Under the References folder, click the project reference you just added.
In the reference Properties, set Copy Local to False.
The host view of the add-in has no reference requirements but it is required for the host application.
This pretty much covers all the background required to work with the MAF. Of course a lot of important stuff hasn’t been covered here like the Lifetime management and details of contracts and views and adapters. But since this is only a quick reference I’ll leave it at this.
In the next post I’ll walthrough creating an addin and note down all the points to note while doing the same.
Until then…
Sidharth
Comments
Anonymous
May 02, 2009
PingBack from http://microsoft-sharepoint.simplynetdev.com/working-with-the-managed-addin-framework-systemaddin/Anonymous
May 03, 2009
Thank you for submitting this cool story - Trackback from DotNetShoutoutAnonymous
September 02, 2009
So how do I verify that a particular addin I have discovered is from a valid source? With the old practice of loading assemblies into a separate appdomain allowed me to start with an untrusted appdomain and check the strong name public key. Anyone know if that sort of thing is possible with this?Anonymous
January 02, 2010
Hi siddarth, Even i am trying to learn MAf in detail. If you have any samples, it would begreat if you can share with me Thanks PrashanthAnonymous
January 02, 2010
@Prashanth - Please leave your email address where I can send you any samples.Anonymous
December 22, 2014
I've seen examples of MAF addins and have a question concerning the addincontract attribute. When do you decorate an interface with this in your contracts solution? I've seen some contracts that don't have this attribute included.