2

I am using RabbitMQ to communicate between applications (RPC) and I have a dilemma of what is the appropriate way to call the method I need. I have a class which contains a bunch of available methods, and I need to execute the one that matches the string carried in my Rabbit message.

Option1: Using the method shown HERE is much cleaner and nicer to look at, but I wonder if it has anything against it. e.g. performance penalty, bad practice, etc

var method = this.GetType().GetMethod(methodNameString);
method.Invoke(this, messagebody);

Option2: Using a switch

switch(methodNameString)
case: method1
    method1();
case: method2
    method2();
...
Community
  • 1
  • 1
Svet Angelov
  • 799
  • 8
  • 19
  • 1
    Does it have to be very fast? Is methodNameString provided by an external system (because it can call any method on the object)? – Chet Sep 27 '16 at 20:24
  • 1
    My concern about that would be that you're cheerfully calling any random method whose name comes in from a message queue. So make sure the class they belong to has nothing in it but those methods. But that's easy and obvious. I like it much better than the switch, and better than `Dictionary` too. But I live in a cave and I'm afraid of fire. – 15ee8f99-57ff-4f92-890c-b56153 Sep 27 '16 at 20:28
  • @Chet I have an external entity call a WebService which makes a bunch of checks (xsd, etc) on the data being passed and then the WebService sends commands to the Windows Service via a message broker – Svet Angelov Sep 28 '16 at 14:11
  • So performance isn't an issue (you lose more crossing the process boundary). Just make sure you ensure there are no methods on the target class which shouldn't be called by the WS. – Chet Sep 28 '16 at 14:15

2 Answers2

2

You can try using Dictionary<string, Action> in order to keep all the possible actions in the same place; all method1..methodN have to be of the same format:

 // method1..methodN can be called 
 Dictionary<String, Action> myMethods = new Dictionary<String, Action>() {
   {"method1", () => method1()},
   {"method1Synonym", () => method1()},  
   ...
   {"methodN", () => methodN()},
 };

 ...

 myMethods[methodNameString]();
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
2

The reflection thing is alright. Reflection is much faster than a (common) message queue is. This is extremely unlikely to be a performance bottleneck.

Keep in mind that you are allowing message producers to call any method. This might be a security concern, or a layering violation if the producer starts calling into stuff that is meant to be internal.

Also, the system is less statically analyzable. You can't find out what methods are being called by doing a "Find Usages" for example.

I'm mentioning this for completeness. I think it's the right approach, most likely.

usr
  • 168,620
  • 35
  • 240
  • 369