The problem statement that I am trying to solve is this;
We will retrieve a list of Tasks from an external repository. These tasks will have a type and for each type, there needs to be a specific implementation that defines the Model it needs it order to perform the Task and then the logic needed to Process the task, along with any dependencies.
At one point, the Factory was setup to use Generics, but reverted to this as it seemed simpler.
public interface ITask
{
bool ProcessTask();
}
public interface ITask <TModel>
{
}
public interface IModelBuilder <out TModel>
{
TModel Build(ITaskDefinition taskDefinition);
}
public abstract class BaseTask <TModel> : ITask<TModel> , ITask where TModel: IModel
{
public TModel Model { get; set;}
public ITaskDefinition TaskDefinition { get; set; }
protected BaseTask(ITaskDefinition definition, IModelBuilder <TModel> builder)
{
Model = builder.Build(definition);
}
public abstract bool ProcessTask();
}
public interface ITaskFactory
{
ITask GetTask(ITaskDefinition taskDefinition, TaskType type);
}
Concrete classes
public class TaskFactory: ITaskFactory
{
private readonly IContainer _container;
public TaskFactory(IContainer container)
{
_container = container;
}
public ITask GetTask(ITaskDefinition taskDefinition, TaskType type)
{
return _container
.With(taskDefinition)
.GetInstance < ITask > (type.ToString());
}
}
public class DateTask: BaseTask < DateModel >
{
private readonly ITaskManagementFacade _taskManagementFacade;
public CaptureCompletionDateTask(ITaskDefinition taskDefinition, IModelBuilder < DateModel > builder, ITaskManagementFacade taskManagementFacade): base(taskDefinition, builder)
{
_taskManagementFacade = taskManagementFacade;
}
public override bool ProcessTask()
{
return _taskManagementFacade.CompleteTask(Model.SomeDate < DateTime.Now);
}
}
public class DateModelBuilder: IModelBuilder < DateModel >
{
private readonly ITaskManagementFacade _taskManagementFacade;
public DateModelBuilder(ITaskManagementFacade taskManagementFacade)
{
_taskManagementFacade = taskManagementFacade;
}
public DateModel Build(ITaskDefinition taskDefinition)
{
var model = new DateModel
{
MyDate = DateTime.Now,
Notes = _taskManagementFacade.GetTask((Guid.NewGuid()))
};
return model;
}
}
public class DateModel: IModel
{
public DateTime MyDate
{
get;
set;
}
[Required]
public string Notes
{
get;
set;
}
}
StructureMap container config
config.For<ITask>().Use<CaptureCompletionDateTask>().Named(TaskType.Task1.ToString());
config.For<IModelBuilder<DateModel>>().Use<DateModelBuilder>();
Code to get Task
var task = _taskFactory.GetTask(taskDefinition, TaskType.Task1)
;
What am I looking for? General comments, this is my first attempt at this kind of object construction. It would be great if I could get around the Named config in Structuremap and go back to using a Generic Factory to Load a Task
based on TaskType
.
Thanks