Pablo Galiano : Wednesday, July 08, 2009 - Posts

Subscriptions

<September 2010>
SuMoTuWeThFrSa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

News

Subscribe to Pablo Galiano by Email

Post Categories

Wednesday, July 08, 2009 - Posts

VS 10 beta 1 Exporting MEF parts from a VS Package (part 1)

***Disclaimer: This information applies to Visual Studio 2010 Beta 1 only.***

 

In this series of post I will create a VS Package that will create a MEF container and export parts.

Those parts are going to be consumed by another project that will be another MEF component.

The source code for this sample is already in the Code Gallery.

 

Let’s first create a VS Package project and name it “MEFContainer”:

image

Then we need to add the following references to the project:

  • Microsoft.VisualStudio.ComponentModelHost.dll
  • Microsoft.VisualStudio.ExtensibilityHosting.dll
  • System.ComponentModel.Composition.dll

 

Creating the container:

As I explained in a previous post, Visual Studio has its own version of a CompositionContainer, and it is the VsCompositionContainer class.

Lets examine the following piece of code:

            var componentModel = this.GetService(typeof(SComponentModel)) as IComponentModel;

            var editorCompositionContainer =
                VsCompositionContainer.Create(
                    componentModel.GetCatalog("MEFContainer"),
                    new VsExportProviderSettings(null, VsExportProvidingPreference.Default, VsExportSharingPolicy.ShareEverything, false));

 

To create the container we need to provide a Catalog. Visual Studio also has its own version of a catalog, and it is the AssemblyListCatalog. This catalog holds a list of AssemblyCatalog instances.

To get the catalog we use the IComponentModel.GetCatalog method. This methods returns a list of assemblies that contains a VsCatalogName attribute with the “MEFContainer” value.

Also we need to provide a VsExportSettings, where we can define a scope, a sharing policy and export providing preference.

The following chunk of code creates the container:

public sealed class MEFContainer : Package
{
    private static object synchLock;

    static MEFContainer()
    {
        synchLock = new object();
    }

    protected override void Initialize()
    {
        base.Initialize();

        InitializeContainer();
    }

    private void InitializeContainer()
    {
        object obj = null;
        bool lockTaken = false;

        try
        {
            Monitor.Enter(obj = synchLock, ref lockTaken);

            var componentModel = this.GetService(typeof(SComponentModel)) as IComponentModel;

            var editorCompositionContainer =
                VsCompositionContainer.Create(
                    componentModel.GetCatalog("MEFContainer"),
                    new VsExportProviderSettings(null, VsExportProvidingPreference.Default, VsExportSharingPolicy.ShareEverything, false));

            var batch = new CompositionBatch();

            batch.AddPart(this);

            editorCompositionContainer.Compose(batch);
        }
        finally
        {
            if (lockTaken)
            {
                Monitor.Exit(obj);
            }
        }
    }
}

 

Exporting a part:

In this example I will declare an Export for the IVsUIShell service. And this export will be imported later in the MEF component project.

[Export(typeof(IVsUIShell))]
public IVsUIShell ServiceProvider
{
    get
    {
        return (IVsUIShell)this.GetService(typeof(SVsUIShell));
    }
}

Once we have the export defined, somehow it needs to be composed in the container, and that is being done when we compose the container:

            var batch = new CompositionBatch();

            batch.AddPart(this);

            editorCompositionContainer.Compose(batch);

 

Specifying the catalog name:

To specify the catalog name we need to add the following attribute to the AssemblyInfo.cs file

[assembly: VsCatalogName("MEFContainer")]

 

The MEF Component content type:

The VS Package itself is a MEFcomponent and we need to specify that in the VSIX extension manifest.

image

 

Stay tuned,

Pablo

posted Wednesday, July 08, 2009 5:36 AM by pga with 0 Comments