use*_*405 2 c# reflection methods dll assemblies
我有一个简单的挑战.我动态地需要在C#中找出具有特定属性的所有方法.我将从另一个应用程序动态加载程序集,需要找出确切的方法.程序集如下所示:
Base.dll:
Class Base
{
[testmethod]
public void method1()
...
}
Run Code Online (Sandbox Code Playgroud)
Derived.dll:
Class Derived:Base
{
[testmethod]
public void method2()
}
Run Code Online (Sandbox Code Playgroud)
现在在第3个应用程序中,我动态地想加载上面提到的dll并找出testmethods.
如果我加载Base.dll,我需要获得testmethod1.如果我加载Drived.dll,我应该得到testmethod1和testmethod2.
我在网上找到了一些帮助我动态加载dll的代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,我可以加载DLL.但是,当我使用以下代码找出正确的方法时,它不会返回任何所需的结果.我想知道哪个部分不正确.以下代码列出了大约145种方法,但其中没有一种是我正在寻找的方法.
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;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我解决这个问题吗?
我不确定为什么,但我试图从上面提到的类(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);
}
Run Code Online (Sandbox Code Playgroud)
(我也会使用LINQ进行所有排序.显然,您可以将GetMethods调用等调整为仅返回实例方法,例如.)
为什么你目前的做法不工作或者为什么它不是完全清楚,我不会,但没有一个简短而完整的例子证明了问题,这将是很难进一步诊断是-当你已经创建的实例工作.我肯定从上面的代码开始:)