PostSharp is a great open-source tool that allows you to encapsulate the non-business logic in custom attributes. That’s the Aspect Oriented Programming paradigm main goal: the separation of concerns.
This tool heps you to free the business logic from the infrastructure code such as:
Your code will be cleaner than never.
…and why do I call it a “great tool”? Because, unlike other tools that uses reflection and other techniques that reduces performance, PostSharp works at MSIL level!. It generates MSIL code to be injected in your code at compilation time, in that way it supports any .NET language and get the best performance possible.
Furthermore, this tool is really easy to learn. You can quickly get started by using the basic features, follow this simple quick start:
The following example shows a simple PostSharp aspect to trace the execution of the methods marked with that attribute:
public class SimplestTraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionEventArgs eventArgs)
{
Trace.TraceInformation(“Entering {0}.”, eventArgs.Method);
Trace.Indent();
}
public override void OnExit( MethodExecutionEventArgs eventArgs)
{
Trace.Unindent();
Trace.TraceInformation(“Leaving {0}.”, eventArgs.Method);
}
}
…and it works like a charm!
The evidence:
Building the project:
Inspecting the binaries:
Results:
Enjoy it!
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:
A MAF solution usually have seven types of projects:
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.
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.
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\”.
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);
}