Search code examples
c#genericsdry

How to remove switch to convert string to generic function


This is probably a newbie question but I couldn´t find a good answer even googling and reading a lot about the subject.

I have a generic method, lets call it Execute()

My code receives a message1:

 {
   serviceProvider: "Sever1",
   serviceType: "query",
   service: "authors"
 }

and message2 could be:

 {
   serviceProvider: "Sever2",
   serviceType: "query",
   service: "bookTitles"
}

Now, I have

public void ProcessMessage(Message message)
{
   switch (message.service)
   {
      case "authors":
        Execute<Authors>();
        break;
      case "booTitle":
        Execute<BookTitle>();
        break;
   }
}

I really don´t like this ProcessMessage method, as it does not look DRY at all. And if we add more types of services, then we need to keep adding to the switch.

How should I implement this thing? Do I need reflection? I´d rather not use reflection as the ProcessMessage can be called thousands of times and reflection would probably add a lot of overhead.


Solution

  • If you want to have a dynamic switch you don't need to resort to reflection, but you'd need to register the services you want to use.

    Based on your question, here's what that might look like:

    void Main()
    {
        this.Register("authors", () => Execute<Authors>());
        this.Register("bookTitles", () => Execute<BookTitle>());
    }
    
    private Dictionary<string, Action> _registry = new Dictionary<string, Action>();
    
    private void Register(string key, Action action)
    {
        _registry[key] = action;
    }
    
    public void ProcessMessage(Message message)
    {
        if (_registry.ContainsKey(message.service))
        {
            _registry[message.service]();
        }
    }
    

    You can add as many actions as you need. And you can do that at run-time.