2

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?

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry to switch on you - the Attributes answer seems perfect.
@grefly - no problem. You should go with the best answer, as you see it. However, perhaps in the future, wait for a day or two before accepting an answer to see what comes up.
Yep, will do - jumped the gun.
1

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

3 Comments

Wow - I haven't done any Attribute coding, that looks too incredibly easy. Thanks for that!
@grefly, it's well-suited for use cases like this. MS used the same pattern for associating TypeConverter classes: msdn.microsoft.com/en-us/library/…
I think that is exactly what I was looking for, without knowing what I was looking for. Thanks, re-assigned Answer to you, with apologies to @Oded.
0

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

2 Comments

Thanks for going into a little more detail. Sorry I can't mark both as Answer.
My implementation (which I think will help describe the issue) would be like this: GetByType(TaskType) if( TaskType Is AddUserTask ) return AddUserTaskResolution if( TaskType Is RemoveUserTask ) return RemoveUserTaskResolution etc.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.