假设我有一个包含 4 个项目的解决方案,A、A_UnitTests、B 和 B_UnitTests。
项目 A 有一个数据文件,该文件作为链接添加到A_UnitTests并设置为复制到输出目录。运行单元测试或在生产中执行代码时,使用以下代码片段正确标识该文件的路径:
public static string GetFullPath(string relativePath)
{
string retVal = string.Empty;
if (System.Web.HttpContext.Current == null)
{
string locationBeforeShadowCopy = typeof(A.SomeClassInA).Assembly.CodeBase;
UriBuilder uri = new UriBuilder(locationBeforeShadowCopy);
string locationWithoutUriPrefixes = Uri.UnescapeDataString(uri.Path);
string dir = Path.GetDirectoryName(locationWithoutUriPrefixes);
retVal = Path.Combine(dir, relativePath);
}
else
{
// stuff that doesn't matter
}
return retVal;
}
但是,我在B_UnitTests中有一个新的测试用例,它尝试使用此代码路径来查找文件位置。但是,即使我调用typeof(A.SomeClassInA).Assembly.CodeBase
,它也使用其引用的 DLL 从B_UnitTests调用。这意味着路径返回是B_UnitTests输出目录 + 相对路径。所以它找不到数据文件。
在不诉诸硬编码设置和构建脚本的情况下,我可以使用什么来指定正确的路径?
更新(澄清(真正的问题是typeForClassInA.Assembly.CodeBase返回执行程序集的路径而不是A本身。提供来自某个程序集的类型似乎非常错误,但它不是返回原始程序集位置,而是返回执行程序集的路径,该程序集恰好具有对它的引用。
如果有对"typeForClassInA"的引用,则其程序集将被复制到B_UnitTests的输出目录中。因此,当您从 B_UnitTests 中的测试中请求该类型的程序集的代码库时,它(正确(指向B_UnitTests输出文件夹中程序集 A 的版本,因为这是加载它的位置。
我承认我避免使用卷影复制来避免查找程序集旁边的资源的这类问题,因为 ShadowCopy 不明白它们是必需的,并且它们不会被卷影复制。
另一件有帮助的事情是通过将所有项目输出文件夹更改为"..\bin"。例如,这意味着A_UnitTests不需要指向资源文件的链接(一旦卷影复制关闭(。
我有一个类似于您展示的方法,它从程序集的位置(对我来说是共享 bin 文件夹("向上"到解决方案的位置;我的相对路径在该文件夹"扎根"。
如果这一切听起来太复杂,你可以使用A_UnitTests所做的相同方法,包括一个来自B_UnitTests的链接。