我目前正在使用以下方法检查测试程序集:
private bool IsTestAssembly(string path)
{
var assembly = Assembly.LoadFrom(path);
foreach (var type in assembly.GetTypes())
{
var a = type.GetCustomAttributes(true).Select(x => x.ToString());
if (a.Contains("Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute"))
return true;
}
return false;
}
但是我想在没有将程序集加载到内存中的情况下检查这个,因为我需要能够在验证失败后删除它。
我希望我可以简单地卸载装配,但我很快就发现了,根据MSDN:
如果不卸载包含它的所有应用程序域,就无法卸载单个程序集。
提前致谢!
答案 0 :(得分:2)
我按照TheGreatCO的建议制定了一个简短的解决方案,即将程序集加载到新的AppDomain
中:
1)用法:
// assemblies are unloaded on disposal
using (var analyser = new AssemblyAnalyser())
{
var path = "my.unit.tests.dll";
var b = analyser.IsTestAssembly(path);
Assert.IsTrue(b);
}
2)实施:
public class AssemblyAnalyser : MarshalByRefObject, IDisposable
{
public AssemblyAnalyser()
{
var evidence = new Evidence(AppDomain.CurrentDomain.Evidence);
var appSetup = new AppDomainSetup()
{
ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};
appDomain = AppDomain.CreateDomain(otherDomainFriendlyName, evidence, appSetup);
}
public bool IsTestAssembly(string assemblyPath)
{
if (AppDomain.CurrentDomain.FriendlyName != otherDomainFriendlyName)
{
var analyser = appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, GetType().FullName);
return ((AssemblyAnalyser)analyser).IsTestAssembly(assemblyPath);
}
else
{
var assembly = Assembly.LoadFrom(assemblyPath);
return ContainsTestClasses(assembly);
}
}
public void Dispose()
{
if (AppDomain.CurrentDomain.FriendlyName != otherDomainFriendlyName)
{
AppDomain.Unload(appDomain);
GC.SuppressFinalize(this);
}
}
~AssemblyAnalyser()
{
Dispose();
}
private bool ContainsTestClasses(Assembly assembly)
{
foreach (var type in assembly.GetTypes())
{
var attr = type.GetCustomAttributes(true).Select(x => x.ToString());
if (attr.Contains("Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute"))
return true;
}
return false;
}
private const string otherDomainFriendlyName = "AssemblyAnalyser";
private AppDomain appDomain;
}
答案 1 :(得分:1)
使用Mono.Cecil检查装配体。塞西尔不需要加载组件来检查它。