grefly
grefly

Reputation: 1199

Factory Method or Some Other Pattern?

I have a Task entity that needs to be Resolved based on the type of Task it is. I would encapsulate the logic for a specific type of Task in a class, but what is the generally accepted way to match the type with the class that implements the Resolving logic?

My first impulse is to do a Factory, like:

TaskResolverFactory.GetForType(TaskType) // returns IsATaskResolver, which has a Resolve method

Probably inside the Factory, a Case statement or something.

Another thought is to use something like StructureMap, but I think that is overkill for this situation - do you agree?

What other methods am I missing, and what is the generally accepted method for replacing a big Case/Switch statement?

Upvotes: 2

Views: 348

Answers (3)

Dan Bryant
Dan Bryant

Reputation: 27495

You might consider something like this:

public class TaskResolverAttribute : Attribute
{
    public Type ResolverType { get; private set; }

    public TaskResolverAttribute(Type resolverType)
    {
        if (!typeof(ITaskResolver).IsAssignableFrom(resolverType))
            throw new ArgumentException("resolverType must implement ITaskResolver");

        ResolverType = resolverType;
    }
}

public class MyTaskResolver : ITaskResolver
{
}

[TaskResolver(typeof(MyTaskResolver))]
public class MyTask
{
}

public static class TaskResolverFactory
{
    public static ITaskResolver GetForType(Type taskType)
    {
        var attribute =
            Attribute.GetCustomAttribute(taskType, typeof(TaskResolverAttribute)) as TaskResolverAttribute;
        if (attribute == null)
            throw new ArgumentException("Task does not have an associated TaskResolver");

        return (ITaskResolver)Activator.CreateInstance(attribute.ResolverType);
    }
}

Upvotes: 1

Austin Salonen
Austin Salonen

Reputation: 50215

A factory is the way to go.

As for the big switch statement, your other options include:

  • Configuration/lookup file
  • A database
  • Reflection

I think the reflection route is the easiest to maintain but the complexity arises when you don't already have the type (assuming your "type" is a Type).

Since you already have the type, the rest is real easy:

public static Task GetByType(Type taskType)
{
    return Activator.CreateInstance(taskType) as Task;
}

Upvotes: 0

Oded
Oded

Reputation: 498904

You are right - a Factory is the classic pattern for this issue.

If this is the only place you need to do such resolution (and the logic is simple), I agree - StructureMap is overkill.

Upvotes: 2

Related Questions