A fairly common scenario is that MEF components extend behavior that don’t require the package exporting those components to be loaded and initialized, such as text editor colorizers, etc.

Other components, however, might need the owning package to be loaded, such as components that want to enforce certain commands with dynamic query status are initialized, tools options pages, etc.

Clide provides a base ExportingPackage class that can be used for this purpose. The usage involves exposing a new exported contract that the package implements, and importing that on your MEF components.

/// <summary>
/// Marker interface implemented by the package that 
/// components can import to force the package to load
/// before exports are used.
/// </summary>
public interface ISamplePackage
{
}

The package implements the interface, and inherits from the ExportingPackage base class:

[Guid(Constants.PackageGuid)]
[PackageRegistration(UseManagedResourcesOnly = true)]
[PartCreationPolicy(CreationPolicy.Shared)]
public class ShellPackage : ExportingPackage, ISamplePackage
{
    [Export(typeof(ISamplePackage))]
    public ISamplePackage Package
    {
        get { return (ISamplePackage)base.LoadedPackage.Value; }
    }

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

        // Do some required initialization step here.
    }
}

Note the PartCreationPolicy is set to Shared, so that only one instance of the package is created by MEF, and how the Export attribute of the marker interface is exposed on a property rather than at the class level. This property accesses the delay-loaded property on the base class, which takes care of forcing VS to load and initialize the package. Now components that want to force their owning package to load before use can simply import the marker interface:

[Export]
public class ForcePackageLoadComponent
{
    [ImportingConstructor]
    public ForcePackageLoadComponent(ISamplePackage package)
    {
        // No need to do anything special with the package here, 
        // although we might use state from it if needed.
    }
}

Last edited May 11, 2011 at 1:03 PM by dcazzulino, version 2

Comments

No comments yet.