This is one of my last posts in this series. If you have not yet read my previous posts, here are the links to them: Chapter One, Chapter Two, Chapter Three, Chapter Four. (I would especially read Chapter Three, as that is where I introduce MEF, and I would also read the MEF Overview and the Programming Guide, which are linked to in Chapter Three.)
If you remember from my last post, I successfully integrated the VSTA IDE into my Contact Manager application. I have now gone a step further, and integrated MEF into the AddIn itself. To do this, I have created two templates: A regular Macro AddIn template, and a MEF Extension Template.
Here is the default code for each of them.
Macro AddIn code:
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports System.ComponentModel.Composition.ImportAttribute
Public Class AppAddIn
Implements IAddIn
Private Application As IContactClass
Private MyContact As IContactObj
Public Sub Startup(ByRef app As IContactClass) Implements IAddIn.Startup
Application = app
MyContact = Application.CreateNewContactObj()
Compose()
End Sub
Public Sub Shutdown() Implements IAddIn.Shutdown
' do nothing
End Sub
Public Sub Compose()
Dim Dir As [String] = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "ContactManager\Macros\Extensions")
Dim Catalog As New DirectoryCatalog(Dir)
Dim Container As New CompositionContainer(Catalog)
Container.SatisfyImportsOnce(Me)
End Sub
Private _Macros As IEnumerable(Of IMEFMacro)
<ImportMany(GetType(IMEFMacro))> _
Private Property Macros() As IEnumerable(Of IMEFMacro) Implements IAddIn.Macros
Get
Return _Macros
End Get
Set(ByVal value As IEnumerable(Of IMEFMacro))
_Macros = value
End Set
End Property
Private Sub RunMacro(ByVal MacroName As String) Implements IAddIn.RunMacro
For Each m As IMEFMacro In Macros
If m.Name = MacroName Then
m.Run(Application, MyContact)
End If
Next
End Sub
End Class
MEF Extension code:
Imports System.ComponentModel.Composition
Imports Interfacelibrary
<Export(GetType(IMEFMacro))> _
Public Class AddJohnSmith
Implements IMEFMacro
Public ReadOnly Property Name() As String Implements IMEFMacro.Name
Get
Return "Add John Smith"
End Get
End Property
Public Sub Run(ByVal Application As IContactClass, ByVal Contact As IContactObj) Implements IMEFMacro.Run
Contact.FirstName = "John"
Contact.LastName = "Smith"
Application.AddContact(Contact)
End Sub
End Class
<Export(GetType(IMEFMacro))> _
Public Class AddJaneDoe
Implements IMEFMacro
Public ReadOnly Property Name() As String Implements IMEFMacro.Name
Get
Return "Add Jane Doe"
End Get
End Property
Public Sub Run(ByVal Application As IContactClass, ByVal Contact As IContactObj) Implements IMEFMacro.Run
Contact.FirstName = "Jane"
Contact.LastName = "Doe"
Application.AddContact(Contact)
End Sub
End Class
Now let’s walk through what this code does. When the user first builds the Macro addIn, and then after any subsequent builds, the AddIn runs the Compose method. This method looks in My Documents\ContactManager\Macros\Extensions for the MEF AddIn Extension. (When the MEF Extension template is built, it automatically installs Extension to this folder.) If an Extension is found, The Macro AddIn imports a collection of Macros from the extension. These Macros are then displayed in the Macro Manager, and can be run. This allows for AddIns themselves to be extensible. A user can import Macros from one or multiple files, and import them into the current Macro addIn project.
Here is a brief walkthrough of this process:
First, run the install file in the root folder of the source code.
Open the App, then select File then click Load IDE.
Build the Macro AddIn.
Click New Project at the top and select MEFAddIn.
Build the MEFAddIn.
Close and then Re-Open the IDE.
Rebuild the Macro AddIn.
Now select file and Click Run Macro.
You should see all the Macros specified in the Macro AddIn.
The Final Result:

I hope this journey has been beneficial in your understanding of VSTA and MEF. Please feel free to email me with any questions.
Posted
Aug 10 2009, 01:36 PM
by
BillL