I recently started a project where I needed to add logging to an existing codebase. One of the requirements is that the class and method is logged along with the severity, message, exception (if there is one), date and time, etc, etc, etc. It started out not looking pretty with constants added to each class for just the class name or writing out typeof(blah).FullName and the method name each and every time, a message needed to be logged. I figured there had to be better way and parsing Environment.StackTrace (type string) didn’t seem to be it.
Looking through System.Diagnostics, I stumbled upon the StackTrace class and from there it was a skip, hop and a jump to figure out how to unwind the stack and get the information I needed.
StackTrace stackTrace = new StackTrace(1); //skip at least this frame
for (int frameCounter = 0; frameCounter < stackTrace.FrameCount; frameCounter ++)
{
StackFrame frame = stackTrace.GetFrame(frameCounter);
MethodBase method = frame.GetMethod();
Console.WriteLine("Class: {0}, Method: {1}",
method.DeclaringType.FullName,
method.Name);
}
Simples.
Read more
I’m all for adding new language constructs but this one I just can’t endorse – implicity typed variables.
Now, I’m not a fan of scripting languages (perl, javascript, python, etc) and am pretty sure I’m not I’m ever going to use this.
So instead of writing
string url = "http://mymojo.ca";
int port = 80;
you can write
var url = "http://mymojo.ca";
var port = 80;
And everything is suppose to just work as if it were strongly typed.
var x = 5;
var y = "11";
var z = x + y;
And what is the result of z - 16 or “511″?
Read more
First let me say, I hate writing the same code twice since I know as soon as I start writing it a third time that I am seriously doing something very very wrong. I was writing some wrapper code around a web service call – common error handling code, when I first took a deep breath and started to look for a better way.
Let’s say I got to this point:
1 class WebServiceWrapper
2 {
3 public WebServiceWrapper()
4 {
5 }
6
7 public void WebServiceMethod1()
8 {
9 try
10 {
11 // call the actual web service method here
12 }
13 catch (SoapHeaderException ex)
14 {
15 // common exception handling code
16 }
17 catch (SoapException ex)
18 {
19 // common exception handling code
20 }
21 catch (WebException ex)
22 {
23 // common exception handling code
24 }
25 }
26
27 public void WebServiceMethod2()
28 {
29 try
30 {
31 // call another actual web service method here
32 }
33 catch (SoapHeaderException ex)
34 {
35 // common exception handling code
36 }
37 catch (SoapException ex)
38 {
39 // common exception handling code
40 }
41 catch (WebException ex)
42 {
43 // common exception handling code
44 }
45 }
46 }
Now imagine if you had 10, 20, or 100 more web service method to call. Clearly this starts to become bloated, unmaintainable, error prone and crude looking fast – nevermind I am already pitying the guy that is going to have to go through all the methods if an additional exception needs to be handled. There had to be a better way and with .NET 2.0 (an higher) there is – anonymous delegates.
Lets start by refactoring,
1 class BetterWebServiceWrapper
2 {
3 public BetterWebServiceWrapper()
4 {
5 }
6
7 protected void HandlePossibleExceptions()
8 {
9 try
10 {
11 }
12 catch (SoapHeaderException ex)
13 {
14 // common exception handling code
15 }
16 catch (SoapException ex)
17 {
18 // common exception handling code
19 }
20 catch (WebException ex)
21 {
22 // common exception handling code
23 }
24 }
25
26 public void WebServiceMethod1()
27 {
28 HandlePossibleExceptions();
29 // call the actual web service method here
30 }
31
32 public void WebServiceMethod2()
33 {
34 HandlePossibleExceptions();
35 // call another actual web service method here
36 }
37 }
38 }
Looking better, but the exception handling doesn’t exactly do anything at this point. What we need to do is pass the code we want to execute to the HandlePossibleExceptions method as a reference to a method and then in the try block call the method – this is where the anonymous delegates comes in.
Allow me to demonstrate:
1 class BetterWebServiceWrapper
2 {
3 private delegate void WebServiceCode();
4
5 public BetterWebServiceWrapper()
6 {
7 }
8
9 private void HandlePossibleExceptions(WebServiceCode code)
10 {
11 try
12 {
13 code();
14 }
15 catch (SoapHeaderException ex)
16 {
17 // common exception handling code
18 }
19 catch (SoapException ex)
20 {
21 // common exception handling code
22 }
23 catch (WebException ex)
24 {
25 // common exception handling code
26 }
27 }
28�
29 public void WebServiceMethod1()
30 {
31 HandlePossibleExceptions(delegate
32 {
33 // call the actual web service here
34 });
35
36 }
37
38 public void WebServiceMethod2()
39 {
40 HandlePossibleExceptions(delegate
41 {
42 // call the actual web service here
43 });
44 }
45 }
Pretty simple, no? And now for the real magic…
1 class BetterWebServiceWrapper
2 {
3 private delegate void WebServiceCode(bool someParameter);
4
5 public BetterWebServiceWrapper()
6 {
7 }
8
9 private void HandlePossibleExceptions(WebServiceCode code)
10 {
11 bool someParam = true;
12 try
13 {
14 code(someParam);
15 }
16 catch (SoapHeaderException ex)
17 {
18 // common exception handling code
19 }
20 catch (SoapException ex)
21 {
22 // common exception handling code
23 }
24 catch (WebException ex)
25 {
26 // common exception handling code
27 }
28 }
29
30 public void WebServiceMethod1()
31 {
32 int identifier = 0;
33
34 HandlePossibleExceptions(delegate(bool someParameter)
35 {
36 // call the actual web service method here
37 identifier++;
38 });
39
40
41 }
42
43 public void WebServiceMethod2()
44 {
45 HandlePossibleExceptions(delegate(bool someParameter)
46 {
47 if (someParameter)
48 {
49 // call another actual web service method here
50 }
51 });
52 }
53 }
So next time you are standing around the water cooler discussing your favourite C# feature, don’t forget those nameless delegates that can make you job just a little bit easier…
Read more