Friday 5 March 2010

Lazy loading an IEnumerable with MEF version 2

Here I have refactored the previous example to use strongly typed attributes…

using Ccp.Contracts.Task;
namespace CCP.BusinessLogic.Tasks
{
    public interface ITaskEngineMetadata
    {
        TaskType taskType { get; }
    }
}

using System.ComponentModel.Composition;
using Ccp.Contracts.Task;
namespace CCP.BusinessLogic.Tasks
{
    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
    public class TaskEngineAttribute : ExportAttribute
    {
        public TaskEngineAttribute()
            : base(typeof(ITask))
        {
        }
        public TaskType taskType { get; set; }
    }
}

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ccp.Contracts.Task
{
    public interface ITask
    {
        void Run(TaskClaimCheck ticket);
    }
}

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, ITaskEngineMetadata>> TaskEngines { get; set; }

        public TaskFactory()
        {
            InitializeMef();
        }

        public ITask Create(TaskType taskType)
        {
            foreach (var task in TaskEngines)
            {
                if (task.Metadata.taskType == 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);
        }
    }
}

using Ccp.Contracts.Task;
using Ccp.Contracts;
using System.Threading;
using System.ComponentModel.Composition;
namespace CCP.BusinessLogic.Tasks
{
    [TaskEngine(taskType= TaskType.Test)]
    public class TestTask : ITask
    {
        public void Run(TaskClaimCheck ticket)
        {
            return;
        }

    }
}