如何使用自定义属性动态计算所有方法

我有一个简单的挑战。 我动态地需要弄清楚C#中具有特定属性的所有方法。 我将从另一个应用程序动态加载程序集,需要找出确切的方法。 组件如下所示:

Base.dll:

Class Base { [testmethod] public void method1() ... } 

Derived.dll:

  Class Derived:Base { [testmethod] public void method2() } 

现在在第3个应用程序中,我动态地想加载上面提到的dll并找出testmethods。

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

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

  List a = new List(); 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种方法,但不是它们是我正在寻找的方法。

 public static List 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和Derived)实例化对象,上面提到的代码返回正确的结果。 但是如上所述,如果我没有基类和派生类的对象并尝试根据类型找出方法,则它不会返回所需的结果。

谢谢

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

 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调用等调整为仅返回实例方法,例如。)

我并不完全清楚为什么你当前的方法不起作用或为什么它在你创建实例时起作用 – 但是如果没有一个简短但完整的例子来certificate问题,那么很难进一步诊断它。 我肯定从上面的代码开始:)

Interesting Posts