LoadCatalog Result

Contributed by janoveh

The following is a simple IResult implementation for using MEF's DeploymentCatalog to dynamically download and plug in xaps. In order for it to work properly, you must make sure to add the AggregateCatalog as an exported value in the container.

Implementation

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.ReflectionModel;
using System.Linq;

public class LoadCatalog : IResult
{
    static readonly Dictionary<string, DeploymentCatalog> Catalogs = new Dictionary<string, DeploymentCatalog>();
    readonly string uri;

    [Import]
    public AggregateCatalog Catalog { get; set; }

    public LoadCatalog(string relativeUri)
    {
        uri = relativeUri;
    }

    public void Execute(ActionExecutionContext context)
    {
        DeploymentCatalog catalog;

        if(Catalogs.TryGetValue(uri, out catalog))
            Completed(this, new ResultCompletionEventArgs());
        else
        {
            catalog = new DeploymentCatalog(uri);
            catalog.DownloadCompleted += (s, e) =>{
                if(e.Error == null)
                {
                    Catalogs[uri] = catalog;
                    Catalog.Catalogs.Add(catalog);
                    catalog.Parts
                        .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
                        .Where(assembly => !AssemblySource.Instance.Contains(assembly))
                        .Apply(x => AssemblySource.Instance.Add(x));
                }

                Completed(this, new ResultCompletionEventArgs {
                    Error = e.Error,
                    WasCancelled = false
                });
            };

            catalog.DownloadAsync();
        }
    }

    public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
}

Usage

public IEnumerable<IResult> LoadCatalogs()
{
    yield return new LoadCatalog("TestCatalog1.xap");
    yield return new LoadCatalog("TestCatalog2.xap");
    yield return new LoadCatalog("TestCatalog3.xap");
    yield return new LoadCatalog("TestCatalog4.xap");
}

Much thanks to codeplex user janoveh on whose work this recipe was based.

Last edited Dec 8, 2013 at 12:56 PM by tibel, version 9