Friday, 5 March 2010

Lazy loading an IEnumerable with MEF version 1

Here is an application of a Factory using MEF based on an example from Mike Taulty…

namespace Ccp.Contracts.Task
{
    public interface ITask
    {
        void Run(TaskClaimCheck ticket);
    }
}

using System.ComponentModel.Composition;
namespace CCP.BusinessLogic.Tasks
{
    [Export(typeof(ITask))]
    [ExportMetadata("TaskTypeID", TaskType.Test)]
    public class TestTask : ITask

    }
}
namespace Ccp.Contracts.Task
{
    public enum TaskType
    {
        None = 0,
        Test = 7,
    }
}

using Ccp.Contracts.Task;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace CCP.BusinessLogic.Tasks
{
    public class TaskFactory
    {
        [ImportMany(typeof(ITask))]
        public IEnumerable<Lazy<ITask, Dictionary<string, object>>> TaskEngines { get; set; }

        public TaskFactory()
        {
            InitializeMef();
        }

        public ITask Create(TaskType taskType)
        {
            foreach (var task in TaskEngines)
            {
                if (task.Metadata.ContainsKey("TaskTypeID"))
                {
                    object oTaskTypeID;
                    task.Metadata.TryGetValue("TaskTypeID", out oTaskTypeID);
                    TaskType itaskType = (TaskType)oTaskTypeID;
                    if (itaskType == taskType)
                    {
                        return task.Value;
                    }
                }
            }
            throw new NotImplementedException("must add mapping to task mapping dictionary");
        }

        private void InitializeMef()
        {
            DirectoryCatalog directoryCatalog = new DirectoryCatalog(@".");
            CompositionBatch batch = new CompositionBatch();
            batch.AddPart(this);
            CompositionContainer container = new CompositionContainer(directoryCatalog);
            container.Compose(batch);
        }
    }
}