views:

283

answers:

3

I've got a custom handler applied to a class (using the Policy Injection Application Block in entlib 4) and I would like to know whether the input method is a property when Invoke is called. Following is what my handler looks like.

[ConfigurationElementType(typeof(MyCustomHandlerData))]
public class MyCustomHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_")))
        {
            Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name);
        }
        return getNext().Invoke(input, getNext);
    }

    public int Order { get; set; }
}

As you can see from my code sample, the best way I've thought of so far is by parsing the method name. Isn't there a better way to do this?

A: 

You could check the IsSpecialName property; it will be true for property getters and setters. However, it will also be true for other special methods, like operator overloads.

Fredrik Kalseth
A: 

I'm not familiar with that application block, but assuming that MethodBase property is of type System.Reflection.MethodBase, you could take a look at the IsSpecialName property.

System.Reflection.MethodBase.IsSpecialName on MSDN

Nathan Baulch
+2  A: 

You can also check IsSpecialName is true. this will be true in a property (amongst other things)

At the il level the methods are exposed as follows (using Environment.ExitCode as example):

.method public hidebysig specialname static int32 get_ExitCode() cil managed
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed

If you wanted to get fancy you could verify after extracting the name that said property exists but to be honest

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0))

as well as starts with get_ or set_ then you should be good even for people using nasty names (faking the hidebysig is easy enough, faking the IsSpecialName would be very tricky)

Nothing is guaranteed though. Someone could emit a class with a set_Foo method that looked just like a real set method but actually wasn't a set on a read only property. Unless you check whether the property CanRead/CanWrite as well.

This strikes me as madness for you though you aren't expecting deliberate circumvention. A simple utility/extension method on MethodInfo which did this logic wouldn't be too hard and including IsSpecialName would almost certainly cover all your needs.

ShuggyCoUk