1

I am working on a project that needs to be very extendable. It is about performing actions on the basis of a string code or an enum value. I am now using a switch-case statement and calling the methods manually.

What I would like to do is loop through the database records (and eventually get the enum value or string code), call the method "PerformAction" and make it possible to implement the classes or methods later.

 public bool PerformAction(ActionToPerform actionToPerform)
 {
 bool isPerformed = false;
 switch (actionToPerform.Action.Code)
 {
 case "MAIL":
 isPerformed = Actions.SendEmail(actionToPerform);
 break;
 case "RESTART":
 isPerformed = Actions.RestartSendport();
 break;
 case "EVENT-LOG":
 isPerformed = Actions.AddToEventLog();
 break;
 }
 //Do some more
 return isPerformed;
}

I want to be able to implement the actions like SendEmail, RestartSendport and AddToEventLog later. I know this can somehow be done using reflection and giving the methods the name of the CODE (e.g. "MAIL.cs") so I can avoid using the switch case and perform one single call.

I need this to be very dynamic and in another library, so I was wondering if there is a best practice or a nice design pattern for this kind of problem.

asked May 16, 2013 at 11:41
2
  • Composition over inheritance is the way en.wikipedia.org/wiki/Composition_over_inheritance. Make it dependency injected Commented May 16, 2013 at 11:45
  • I don't see how I could use this in my situation, would you be so kind, to give an example? Commented May 16, 2013 at 11:50

2 Answers 2

4

You can start with creating a dictionary:

private Dictionary<ActionType, ActionBase> actions;

So instead of switch (currentActionType) you can do something like this:

if (actions.ContainsKey(currentActionType))
 actions[currentActionType].Run(someArgs);

This way you separate actions mapping from actions invocation. The mapping can be done in constructor:

actions[ActionType.SendEmail] = new SendEmailAction();
actions[ActionType.OtherAction] = new OtherAction();

After this you can extract the actions dictionary to a separate ActionsRepository and inject it as a dependency. The repository can have a method RegisterAction(ActionType type, ActionBase action) for creating a mapping at runtime.

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

Comments

0

If you can manage to unify your action invocation pattern, you can add some ID field to your base Action class and invoke it this way:

public bool PerformAction(ActionToPerform actionToPerform)
{
 bool isPerformed = false;
 var foundAction = Actions.SingleOrDefault(a => a.Code == actionToPerform.Action.Code);
 if (foundAction != null)
 {
 isPerformed = foundAction.Invoke();
 }
 //Do some more
 return isPerformed;
}
answered May 16, 2013 at 12:16

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.