I had blogged earlier about Managed AddIn Framework and the resources to learn the basics. Making use of System.AddIn framework features can appear complex for beginners. In this example we develop a host application and AddIn using Managed AddIn Framework.
Source Code: You can download the source code for this example below.
The diagram below demonstrates how we are going to implement each component in the Managed AddIn Framework in our sample application.
When you activate an Addin from host, you can load the Addin in its own application domain or in an existing application domain or even in a new process separate from host’s process.
Step -1 – HostView
Create a solution with the following solution folders. Create a class library project named HostView under the Pipeline solution folder.
It is important to set the project settings. For HostView, change the output path to ..\output\ (Visual Studio default will be \bin\debug or \bin\release)
The HostView is an abstract class with methods corresponding to the methods exposed by the Addin. In this example I go for a simple method which returns the sum of two integer numbers.
namespace Demo.HostView { public abstract class HostView { public abstract int ComputeSum(int a, int b); } }
Step -2 – Create Host Application
Create a Windows Application project named SampleHost under the HostApplication solution folder.
- Change the output path to ..\output\
- Add reference to assemblies System.AddIn and System.AddIn.Contract
- Add reference to project HostView
The host application UI is given below. It aims to load our addin and use it for computing the sum of numbers supplied from the host application.
Add the following code in the Host to load the AddIn
Collection<AddInToken> _addinTokens; Collection<HostView> _addinList = new Collection<HostView>(); HostView calcAddin;
private void btn_Load_Click(object sender, EventArgs e) { LoadAddins(); }
public void LoadAddins() { // Set root directory for finding Add-ins string addinRoot = Environment.CurrentDirectory; // Rebuild the add-ins and pipeline components AddInStore.Rebuild(addinRoot); // Find add-ins of type HostView _addinTokens = AddInStore.FindAddIns(typeof(HostView), addinRoot); foreach (AddInToken addinToken in _addinTokens) { // Activate the add-in _addinList.Add( addinToken.Activate<HostView>(AddInSecurityLevel.Internet)); // Display Addin-Details richText1.AppendText(String.Format("Loaded Add-in {0} Version {1}", addinToken.Name, addinToken.Version)); } calcAddin = _addinList[0]; }
And we are ready to use the addin instance.
private void btn_Add_Click(object sender, EventArgs e) { if (calcAddin != null) { //Invoking the AddIn method int sum = calcAddin.ComputeSum( Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text)); lblResult.Text = sum.ToString(); } else MessageBox.Show("AddIn is not loaded"); }
Step -3 –Create AddIn View
Create a class library project named AddInView under the Pipeline solution folder.
-
Change the output path to ..\output\AddInViews\
-
Add reference to assemblies System.AddIn and System.AddIn.Contract
The AddInView is an abstract class with methods corresponding to the methods exposed by the Addin. Note that this class should have the attribute [AddInBase]
using System.AddIn.Pipeline; namespace Demo.AddinView { [AddInBase] public abstract class AddInView { public abstract int ComputeSum(int a, int b); } }
Step – 4 – Create Contract
The contract in the middle of the pipeline is loaded into both Host’s app domain and AddIn’s app domain.
Create a class library and;
- Change the output path to ..\output\Contracts\
- Add reference to assemblies System.AddIn and System.AddIn.Contract
The contract interface should have the [AddInContract] attribute as shown below.
using System.AddIn.Contract; using System.AddIn.Pipeline; namespace Demo.Contracts { [AddInContract] public interface IContracts:IContract { int ComputeSum(int a, int b); } }
Step -5 –Create Host Side Adapter
The host-side converts the flow of types between Host View and the contract.
Create a class library project named HostSideAdapters under the Pipeline solution folder
-
Change the output path to ..\output\HostSideAdapters\
-
Add reference to assemblies System.AddIn and System.AddIn.Contract
-
Add reference to project Contracts, set Copy Local property to False
-
Add reference to project HostView, set Copy Local property to False
Note the [HostAdapter] attribute of the ContractToHostViewAdapter Class below.
using System.AddIn.Pipeline; using Demo.Contracts; namespace Demo.HostSideAdapters { [HostAdapter] public class ContractToHostViewAdapter : HostView.HostView { private IContracts _calcContract; private ContractHandle _handle; public ContractToHostViewAdapter(IContracts contract) { _calcContract = contract; _handle = new ContractHandle(_calcContract); } public override int ComputeSum(int a, int b) { return this._calcContract.ComputeSum(a,b); } } }
Step -6 – Create AddIn Side Adapter
Create a class library project named AddInSideAdapters under the Pipeline solution folder
- Change the output path to ..\output\AddInSideAdapters\
- Add reference to assemblies System.AddIn and System.AddIn.Contract
- Add reference to project Contracts, set Copy Local property to False
- Add reference to project AddInView, set Copy Local property to False
Note the [AddInAdapter] attribute of the AddInViewToContractAdapter Class below. The adapter inherits from System.AddIn.Pipeline.ContractBase class and implements IContracts interface.
using System.AddIn.Pipeline; using Demo.AddinView; using Demo.Contracts; namespace Demo.AddInSideAdapters { [AddInAdapter] public class AddInViewToContractAdapter: ContractBase, IContracts { private AddInView _view; public AddInViewToContractAdapter(AddInView view) { this._view = view; } public int ComputeSum(int a, int b) { return this._view.ComputeSum(a,b); } } }
Step -7 –Implement AddIn
Create a class library project named CalcAdd under the AddIn solution folder
Change the output path to ..\output\AddIns\CalcAddin\ (If you have multiple Addin, each AddIn would be deployed into separate directories)
- Add reference to assemblies System.AddIn and System.AddInx.Contract
- Add reference to project AddInView, set Copy Local property to False
namespace Demo.CalcAddIn { [System.AddIn.AddIn("Demo Add-In", Version = "1.0.0.0", Description = "Description of Demo AddIn", Publisher = "XYZ Company")] public class CalcAddIn : Demo.AddinView.AddInView { public override int ComputeSum(int a, int b) { return a+b; } } }
Step -8 – Run the host application
Build the solution and run the host application. You should see the following result.
Alternately you can download the source code from the link below and run it.
Thanks a lot