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;
}
}
}