开发者

How to identify and call a method tagged with an attribute

I'd like to create a custom attribute to apply to any method within a class, and then, from outside that class, access the method inside the class that has been 'tagged' with the attribute to call the tagged method as if it were a delegate.

e.g.

public delegate string MethodCall( string args);

and

public class MethodAttribute : System.Attribute 
{
    public MethodCall callback;
    ...
}

and

class TypeWithCustomAttributesApplied {

    [Method]
    public string DelegateMethod(string args) {
        ...
    }
}

and then

void callMethods(string args) {
    TypeWithCustomAttributesApplied myObj = new TypeWithCustomAttributesAppli开发者_如何学JAVAed(); 
    DelegateMethod method = MyCustomerHelper.GetMarkedMethod(myObj)
    method(args);
}

or perhaps

void callMethods(string args) {
    TypeWithCustomAttributesApplied myObj = new TypeWithCustomAttributesApplied(); 
    MethodAttribute methodAtrib = MyCustomerHelper.GetMarkedMethod(myObj)
    methodAtrib.callback(args);
}

What I'm ultimately trying to achieve is a Custom Attribute that I can use to 'Mark' Ajax Entry points in arbitary classes, then with a Helper Class, pass the 'Ajax Enabled' control to the helper which identifies which method in the control to call, and hands it the ajax data from the client. I'm not so great with delegates anyway, but I generally understand how to apply custom attributes, but not sure how to 'capture' the method I'm 'tagging'

I could probably manage my task some other way, but I'm trying my hand at attributes, so I'd like to get this method working first.


My Final Solution :

public void CheckAjax(object anObject, string args)
    {
        MethodInfo[] methods = anObject.GetType().GetMethods();
        foreach (MethodInfo method in methods)
        {
            object[] attributes = method.GetCustomAttributes(true);

            bool containsAttribute = (from attribute in attributes
                                       where attribute is AjaxableAttribute
                                          select attribute).Count() > 0;

            if (containsAttribute)
            {
                string result_method = (string)method.Invoke(anObject, new object[] { args });
                Log.Write(string.Format("The Result from the method call was  {0} ", result_method));         
            }
        }         
    }


You can use reflection and LINQ:

IEnumerable<MethodInfo> methods = myObj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(method => method.GetCustomAttributes(typeof(MethodAttribute), true).Length == 1).ToList();

string args = "some args";

foreach(MehtodInfo method in methods)
{
      method.Invoke(myObj, new object[] { args });
}


What you have to do to get this methods is the following:

MethodInfo[] methods = typeof(TypeWithCustomAttributesApplied).GetMethods();
foreach (MethodInfo method in methods)
{
    object[] attributes = method.GetCustomeAttributes(true);

    bool containsAttribute = (from attribute in attributes
                               where attribute is MethodAttribute
                                  select attribute).Count() > 0;

    if (containsAttribute)
         // add attribute to list to return later
}

After returning the methods you can call the methods with

method.Invoke(/* parameters *);

Hope this helps.


I think your solution for that would be Reflection to find the method with the attribute you want.


As shown somewhere else you can do

from m in type.GetMethods()
where m.GetCustomAttributes().OfType<YourAttribute>().Any()
select m

Once you get you MethodInfo via reflection "GetMethods where has attribute" the following code shows how you construct a delegate based on a MethodInfo. In this example it is some Action<> but it could be a different type. Here "parameterType" is a type provided from the outside. The resulting delegate can be cast to the type you require. "target" is the instance this delegate will be called upon.

var fittingDelegateType = typeof(Action<>).MakeGenericType(parameterType);
var @delegate = Delegate.CreateDelegate(fittingDelegateType, target, info);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜