1

Possible Duplicate:
How I can get the calling methods in C#

I have a Log class that's supposed to prepend its client's class and method to the logged message like this:

[ClientClass.ClientMethod] This is the logged message.

And I'm looking for a safe way to obtain these values from the Log class, without passing it as a parameter from the client. I have tried this so far:

var stackFrame = new StackFrame(StackFramesToSkip);
var method = stackFrame.GetMethod();
return string.Format("[{0}.{1}] {2}", method.DeclaringType.Name, method.Name, message);

However, this method doesn't always yield the calling method. Especially when working with multiple threads.

Is there a safe way of doing this? I'm out of ideas.

Thanks!

Community
  • 1
  • 1
Axel Magagnini
  • 855
  • 1
  • 8
  • 19
  • How does the stack frame depend on multiple threads? That doesnt make any sense. Are you sure youre not seeing differences due to jit optimization? If thats the cause of suspect stack frames, you'll have to do some clever parsing. – Christopher Currens May 30 '12 at 16:12
  • Is StackFramesToSkip always valid for the context? Is it possible your threading issue lies there? – roken May 30 '12 at 16:20
  • Until [C# 5 comes along](http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx), I think you'll have to settle for passing names as parameters. Whether you do that manually or use some kind of post-build call site rewriting to do it for you (not sure if PostSharp could do it, but I'd be surprised if not) is mostly a question of patience and budget :P – anton.burger May 30 '12 at 16:23
  • Yes, looks like it's a duplicate. I did search for similar ones but obviously I didn't nail the keywords. Sorry. – Axel Magagnini May 30 '12 at 16:27
  • @ChristopherCurrens: I'm not really sure, doesn't make sense to me either. But right now I'm seeing a case where the calling method reported is `StackBuilderSink._PrivateProcessMessage`, along with some others where it is correct. – Axel Magagnini May 30 '12 at 16:32
  • @roken: That's actually a constant. I don't know in what scenarios there would be additional stack frames between the caller and the callee. – Axel Magagnini May 30 '12 at 18:16
  • @Anton: I'll be taking a look at PostSharp as soon as time permits, it sure looks promising. – Axel Magagnini May 30 '12 at 18:16

1 Answers1

2

You could use System.Reflection.MethodBase.GetCurrentMethod() to get the current method's name and transfer the name to a parameter, but you said you didn't want those. Well, I know several other ways.

  1. For .NET 4.5 beta, you can use this Caller Information.
  2. You can use a dynamic proxy. The logging method will still require a parameter, but a dynamic proxy allows you to make the invocation only once, and dynamically add it to your methods. You can use ContextBoundObject or Castle Dynamic Proxy
  3. You can use an AOP framework. This allows you to do something similar to (2), but it's neater. Basically, depending on the framework, the invocation can be added statically instead of dynamically, at build time. Here is a good AOP framework: PostSharp.

The one time I got to do this, I added the calls by hand. I thought it would be daunting at first, but in my case, it wasn't really that bad. I had a very limited assortment of methods to log (those that communicated with COM).

GregRos
  • 8,667
  • 3
  • 37
  • 63
  • Correct me if I'm wrong, but wouldn't that get me the executing method in the Log class? What I'm looking for is the method that issued the call, without passing it as a parameter. – Axel Magagnini May 30 '12 at 16:06
  • Oh, I'm sorry, I misread. This wouldn't help you. I'll suggest something else. – GregRos May 30 '12 at 16:10
  • There ya go, I added a different answer. – GregRos May 30 '12 at 16:24
  • Awesome, thanks! I think I'm gonna go with PostSharp. Feels like overkill at this stage of the project I'm working on, but it's definitely worth taking a look as soon as time permits. – Axel Magagnini May 30 '12 at 18:13
  • I'm glad. PostSharp is excellent. It's something that should be built-in to C#. It's also really well-polished and clean cut, as a framework. Be careful though, at first you'll probably get power drunk and start doing all sorts of things with it :P – GregRos May 30 '12 at 18:20