首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何动态计算具有自定义属性的所有方法

如何动态计算具有自定义属性的所有方法
EN

Stack Overflow用户
提问于 2013-09-19 21:29:13
回答 1查看 2.8K关注 0票数 2

我有个简单的挑战。我需要动态地计算出C#中具有特定属性的所有方法。我将从另一个应用程序动态加载程序集,并需要找到确切的方法。这些程序集看起来如下:

Base.dll:

代码语言:javascript
复制
 Class Base
   {
   [testmethod]
   public void method1()
   ... 
   }

Derived.dll:

代码语言:javascript
复制
 Class Derived:Base
  {
   [testmethod]
   public void method2()
  }

现在,在第三个应用程序中,我动态地喜欢加载上面提到的dll并查找the方法。

如果我加载Base.dll,我需要得到testmethod1。如果我加载Drived.dll,我应该得到testmethod1和testmethod2吗?

我在网上找到了一些帮助我动态加载dll的代码:

代码语言:javascript
复制
 List<Assembly> a = new List<Assembly>();

    string bin = @"Bin-Folder";

    DirectoryInfo oDirectoryInfo = new DirectoryInfo(bin);

    //Check the directory exists
    if (oDirectoryInfo.Exists)
    {
     //Foreach Assembly with dll as the extension
     foreach (FileInfo oFileInfo in oDirectoryInfo.GetFiles("*.dll", SearchOption.AllDirectories))
     {

      Assembly tempAssembly = null;

     //Before loading the assembly, check all current loaded assemblies in case talready loaded
    //has already been loaded as a reference to another assembly
    //Loading the assembly twice can cause major issues
    foreach (Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
    {
     //Check the assembly is not dynamically generated as we are not interested in these
     if (loadedAssembly.ManifestModule.GetType().Namespace != "System.Reflection.Emit")
     {
       //Get the loaded assembly filename
        string sLoadedFilename =
                                loadedAssembly.CodeBase.Substring(loadedAssembly.CodeBase.LastIndexOf('/') + 1);

      //If the filenames match, set the assembly to the one that is already loaded
        if (sLoadedFilename.ToUpper() == oFileInfo.Name.ToUpper())
        {
            tempAssembly = loadedAssembly;
            break;
        }
      }
     }

     //If the assembly is not aleady loaded, load it manually
     if (tempAssembly == null)
     {
         tempAssembly = Assembly.LoadFrom(oFileInfo.FullName);
     }
     a.Add(tempAssembly); 
    } 

上面的代码运行良好,我可以加载DLL。但是,当我使用下面的代码查找正确的方法时,它不会返回任何想要的结果。我想知道哪一部分不对。下面的代码列出了大约145个方法,但其中没有一个是我正在寻找的。

代码语言:javascript
复制
public static List<string> GetTests(Type testClass)
{
 MethodInfo[] methodInfos = testClass.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
 Array.Sort(methodInfos,
       delegate(MethodInfo methodInfo1, MethodInfo methodInfo2)
 { return methodInfo1.Name.CompareTo(methodInfo2.Name); });

 foreach (MethodInfo mi in methodInfos)
 {
   foreach (var item in mi.GetCustomAttributes(false))
     {
      if
     (item.ToString().CompareTo("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute") == 0)
                    result.Add(mi.Name);
            }
        }

        return result;
   }

有人能帮我解决这个问题吗?

我不知道为什么,但是我尝试从上面提到的类(Base和派生)实例化对象,上面提到的代码返回正确的结果。但是,如前所述,如果我没有一个来自基类和派生类的对象,并且试图根据这些类型找出方法,它就不会返回所需的结果。

Thx

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-19 21:32:16

最简单的方法是使用MethodInfo.IsDefined --很可能也使用LINQ:

代码语言:javascript
复制
var testMethods = from assembly in assemblies
                  from type in assembly.GetTypes()
                  from method in type.GetMethods()
                  where method.IsDefined(typeof(TestMethodAttribute))
                  select method;

foreach (var method in testMethods)
{
    Console.WriteLine(method);
}

(我也会用LINQ做所有的排序。显然,您可以调优GetMethods调用等,以便只返回实例方法(例如)。

我并不完全清楚您当前的方法为什么不能工作,或者在创建实例时为什么会工作--但是如果没有一个演示问题的简短但完整的示例,就很难进一步诊断它。我肯定会从上面的代码开始:)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18905236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档