通过CustomAttribute获取方法,然后调用

本文关键字:然后 调用 方法 CustomAttribute 获取 通过 | 更新日期: 2023-09-27 17:51:04

随着对自定义属性和反射的大量学习曲线,我似乎仍然在挣扎。有人能帮我解决这个问题吗?

基本上我想调用一个基于它的属性的方法。

这是修饰一个方法的CustomAttribute(它只能是一个方法): [ControllerName (Name = "博客"))

public static string GetContent(string controllerName, string singleItemName = "") 
{
    string returnVal = null;
    //Get the class type
    Type thisType = typeof(ContentFacade);
    //Get member info 
    System.Reflection.MemberInfo info = typeof(ContentFacade);
    Loop through attributes
    foreach (object attrib in info.GetCustomAttributes(true))
    {
        //if the attribute matches the param controller name
        //then invoke
        if (attrib == controllerName)
        { 
            //Get the method by attribute not method name
            //I dont want to get the method by MethodName
            MethodInfo theMethod = thisType.GetMethod(controllerName);
            //Return the value as it will be html for the end user
            returnVal = (string)theMethod.Invoke(controllerName, null);
        }
    }
    return returnVal;
}

同样,如果可能的话,我希望通过属性获得方法。

真的很期待在这方面得到一些帮助。

编辑

///对不起,我在代码中添加了注释来说明这个问题。基本上我想:

  • 通过controllerName == "blog"获取属性
  • 通过属性获取方法并调用

我不想通过方法名来获取方法

认为,

通过CustomAttribute获取方法,然后调用

一个简单的例子是:

public static string GetContent(Type type, string controllerName) 
{
    foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
    {
        ControllerNameAttribute controller = (ControllerNameAttribute)method.GetCustomAttribute(typeof(ControllerNameAttribute));
        if (controller == null)
        {
            continue;
        }
        if (controller.Name != controllerName)
        {
            continue;
        }
        if (method.IsGenericMethod)
        {
            throw new InvalidOperationException();
        }
        if (method.GetParameters().Length != 0)
        {
            throw new InvalidOperationException();
        }
        if (method.ReturnType != typeof(string))
        {
            throw new InvalidOperationException();
        }
        string result = (string)method.Invoke(null, null);
        return result;
    }
    throw new InvalidOperationException();
}

你可以这样使用:

string result = GetContent(typeof(Program), "blog");

其中Program为方法所在的类。

请注意,正如所写的那样,这段代码只适用于static方法。如果你想使用实例方法,把它改成:

public static string GetContent(object instance, string controllerName) 
{
    Type type = instance.GetType();
    foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
    {
        ControllerNameAttribute controller = (ControllerNameAttribute)method.GetCustomAttribute(typeof(ControllerNameAttribute));
        if (controller == null)
        {
            continue;
        }
        if (controller.Name != controllerName)
        {
            continue;
        }
        if (method.IsGenericMethod)
        {
            throw new InvalidOperationException();
        }
        if (method.GetParameters().Length != 0)
        {
            throw new InvalidOperationException();
        }
        if (method.ReturnType != typeof(string))
        {
            throw new InvalidOperationException();
        }
        string result = (string)method.Invoke(instance, null);
        return result;
    }
    throw new InvalidOperationException();
}

一般情况下,两种方法都不检查给定controllerName是否存在单一方法。它们只是执行找到的第一个。这是可能的,甚至检查,通常使用LINQ,但我想保持foreach循环简单和线性,并显示所有其他检查应该做的。

代码示例

public class MyClass
{
    [System.ComponentModel.DisplayName("my test method")]
    public bool TestMethod(string input)
    {
        return input == "OK";
    }
    [System.ComponentModel.DisplayName("my second method")]
    public string TestMethod2(string input)
    {
        return input;
    }
    public void Invoke(string displayName)
    {
        // attribute type we search
        Type attributeType = typeof(System.ComponentModel.DisplayNameAttribute);
        // find method
        var methodInfo = (from e in this.GetType().GetMethods()
                          let attributes = e.GetCustomAttributes(attributeType).Cast<System.ComponentModel.DisplayNameAttribute>().ToArray()
                          where attributes.Length != 0 &&
                                attributes.Any(x => string.Equals(x.DisplayName, displayName, StringComparison.InvariantCultureIgnoreCase))
                          select e).FirstOrDefault();
        if (methodInfo != null)
        {
            // method found
            Console.WriteLine("Invoke {0} method: {1}", methodInfo.Name, methodInfo.Invoke(this, new object[] { "OK" }));
        }
    }
}
评论>
  1. this.GetType().GetMethods() -获取所有方法,你可以通过BindingFlags指定你想返回哪种方法。
  2. e.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute)) -获取指定类型的所有属性
  3. methodInfo.Invoke(this, new object[] { "OK" }) -方法调用,this -类实例(null为静态方法),new object[] { "OK" } -参数数组。