Calling a higher level method deep inside the lower levels of the code

I have encountered this problem many times in my career. Somewhere deep in the code where we have very little context, we need to use some parameters which are only available in the top layers of the code and then if you are really unlucky, you may even need to make a WCF call to another server.

It is not very difficult to solve this problem. This is a scenario where you could "use a method like a variable".

I.e., create a delegate which may take a parameter and may even return a value (if you need). Inside this method, you can write all the high level code you want.

Func<string, string> MyAction = delegate (string var1)
{
      //Whatever you want to do, you can do here.
      return "something";
};

- If you don't want to return anything, use Action<T> instead.
- If you are within a for loop when you declare this delegate, do not use any list variables like list[i] inside this method. Set it to a real variable: var x = list[i] & use "x" instead within the delegate. There are problems using list[i] or any kind of similar code within a delegate which is run later (after the for loop finishes) or in parallel.

Now, you can pass this delegate through the various layers in your code. Remember, you may not always be able to pass this as a static property of your inner class - because your code could be stateless, or multiple threads can use the same internal class.

In your inner classes, this could be a field - be sure to mark this and even lock variables as non serialized because many times, such classes could be sent over the wire. I had this case where the class was being sent over the wire via a MS framework.

[NonSerialized]
public Func<string, string> MyAction;

Within the inner layer class, now you can call the delegate explicitly, even passing parameters if you want to.

Don't underestimate this as a hack. Firstly, you may not have the time to do something more elegant. Secondly, I have seen some cases where to maximize the re-usability in the code, especially to handle very different types of entities, this solves the problem in an excellent manner - just by being able to pass a delegate as a method parameter. When 10 different areas of code can use the same method call, just be passing something small as a delegate, it is worth doing this.

When working with the collections in System.Collections.Concurrent namespace, I notice that some methods there also take delegates (Func) as input parameters. It makes the code harder to read, but if using this, you can reuse the same code for very different scenarios, then it is definitely worth using.

http://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/17/c.net-little-wonders-the-concurrentdictionary.aspx

There is another post, I have written on a similar topic:

http://softwareconceptdesign.blogspot.com/2011/05/dealing-with-ambiguity-zero-does-not.html

"The existing inputs are not adequate for the program to assume something and then exhibit a new behavior, or execute some logic. Most often in such cases, we need to pass these new inputs or parameters right from the user end, through the various layers to the code which needs to decide what to do"

Comments

Popular posts from this blog

Tutorial: Using Google Cloud Storage from C# and .NET

Late 2008 Macbook only giving 1.5 gb/s speed with 6 gb/s Intel SSD?

Enable Visual Studio to use more than 2GB of memory