1

Is there any dark, obscured way to convert all of the method parameters to an object[]?

While implementing the integration between two systems using a message broker, I noticed that most of the methods exposed by the broker uses a lot of parameters.

I want an easy way to log each call to the broker with every parameter. Something like:

[WebMethod]
public void CreateAccount(string arg1, int arg2, DateTime arg3, ... ) {
    object[] args = GetMethodArgs();
    string log = args.Aggregate("", (current, next) => string.Format("{0}{1};", current, next));
    Logger.Log("Creating new Account: " + args);

    // create account logic
}

I'm curious if C# provides something that simulates GetMethodArgs();

dcarneiro
  • 7,060
  • 11
  • 51
  • 74
  • 1
    Try this previous question: http://stackoverflow.com/questions/3288597/is-there-a-way-to-get-an-array-of-the-arguments-passed-to-a-method – Ash Eldritch Aug 03 '11 at 14:45

3 Answers3

2

You could just have 2 methods.

[WebMethod]
public void CreateAccount(string arg1, int arg2, DateTime arg3)
{ 
    CreateAccountImpl(arg1, arg2, arg3);
}

protected void CreateAccountImpl(params object[] args)
{
    string log = args.Aggregate("", (current, next) => string.Format("{0}{1};", current, next));
    Logger.Log("Creating new Account: " + args);

    // create account logic
}
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • Then you have to know the position and type of the arguments for the rest of the create account logic. – Ray Aug 03 '11 at 14:55
  • I adapted your solution to reach something more generic. The CreateAccountImpl was renamed to LogMessage. It gets a params object[] args and log then. The create account logic will stay on the create account method right after the LogMessage call. – dcarneiro Aug 03 '11 at 16:47
1

PostSharp can capture this using a method boundary aspect. Here's some sample code to see it in action.

public sealed class Program
{
    public static void Main()
    {
        Go("abc", 234);
    }

    [ParamAspect]
    static void Go(string a, int b)
    {
    }
}

[Serializable]
public class ParamAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        object[] argumentContents = args.Arguments.ToArray();
        foreach (var ar in argumentContents)
        {
            Console.WriteLine(ar);
        }
    }
}

The output is:

abc
234
Joe Enos
  • 39,478
  • 11
  • 80
  • 136
  • PostSharp looks like the best option, but it seems to have some compatibility issues with .net framework 3.5 – dcarneiro Aug 03 '11 at 16:41
  • @Daniel: I've been using PostSharp with .NET 3.5 without any trouble at all. I know they made significant changes in their application a year or two ago, so it's possible that older versions might have a problem - but if you stick with current versions, I'd expect you'll be fine. – Joe Enos Aug 03 '11 at 17:46
  • I've download the 2.0.9.3 version and when I try to reference the dll it says that 'PostSharp.dll', or one of its dependencies, requires a later version of the .NET Framework. – dcarneiro Aug 04 '11 at 08:45
  • It's definitely a VS problem, not a framework or PostSharp problem (maybe an installation problem, but not runtime). I noticed that I got the same warning in VS2010 with .NET 3.5, but I ignored it, and the app still worked properly. VS2008 seems ok, and VS2010 with .NET 4.0 is ok, but there's something weird about this reference with VS2010/3.5. But if you're feeling lucky, I'd say go ahead and use it and you should be fine. – Joe Enos Aug 04 '11 at 16:00
  • I promise I'll give it a try. Thanks for the tip – dcarneiro Aug 04 '11 at 23:48
0

For logging/auditing purposes, I have used Castle.DynamicProxy to wrap the Web Service implementation. All method calls are intercepted and passed to an IInterceptor object that has access to the parameters and the return value.

lnmx
  • 10,846
  • 3
  • 40
  • 36