【问题标题】:Location of original assembly(not the current executing)原始程序集的位置(不是当前执行的)
【发布时间】:2018-11-27 20:29:39
【问题描述】:

假设我有一个包含 4 个项目的解决方案,A、A_UnitTests、B 和 B_UnitTests。

项目 A 有一个数据文件,该文件作为链接添加到 A_UnitTests 并设置为复制到输出目录。当运行单元测试或在生产中执行代码时,使用以下代码 sn-p 正确识别该文件的路径:

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,它也是从 B_UnitTests 调用的,使用它引用的 DLL。这意味着路径返回是 B_UnitTests 输出目录 + 相对路径。所以它没有找到数据文件。

如果不使用硬编码设置和构建脚本,我可以使用什么来指定正确的路径?

更新(澄清) 真正的问题是 typeForClassInA.Assembly.CodeBase 返回执行程序集的路径而不是 A 本身。提供一个来自某个程序集的类型似乎是非常错误的,但它不是返回原始程序集位置,而是返回到执行程序集的路径,而该程序集恰好有对其的引用。

【问题讨论】:

  • 不明白这个问题。项目B_UnitTests和项目A是什么关系?数据文件在项目A中,B_UnitTests?中也用到了?
  • 您是否考虑过使用与 A_Unit Tests 相同的方法,包括从 B_UnitTests 指向它的链接?
  • @Richardissimo 对,这绝对是一个选择。但是为了以后可能会遇到这个问题的其他人,真正的问题是 typeForClassInA.Assembly.CodeBase 返回执行程序集的路径而不是 A 本身。提供一个来自某个程序集的类型似乎是非常错误的,但它不是返回原始程序集位置,而是返回到执行程序集的路径,而该程序集恰好有对其的引用。这个问题有什么明显的解决方案吗?还是这种期望不可行?
  • 如果有对“typeForClassInA”的引用,那么它的程序集将被复制到另一个项目的输出目录中,这就是 CodeBase (正确)指向那里的原因,因为那是它所在的地方从加载。我承认我避免使用 Shadow Copy 来避免这些问题。我有一种方法可以从程序集的位置“上升”到解决方案的位置;并且我的相对路径“植根于”该文件夹。
  • @Richardissimo "[...]因为它是从那里加载的" 好的,这就是我担心的。我想我们可以说这个问题没有干净的解决方案,你的评论是正确的答案。

标签: c# visual-studio build path


【解决方案1】:

如果有对“typeForClassInA”的引用,那么它的程序集将被复制到 B_UnitTests 的输出目录中。因此,当您从 B_UnitTests 中的测试中请求该类型程序集的 CodeBase 时,它​​(正确地)指向 B_UnitTests 输出文件夹中的程序集 A 的版本,因为这是从中加载它的位置。

我承认我避免使用 Shadow Copy 是为了避免出现这类定位程序集旁边的资源的问题,因为 ShadowCopy 不了解它们是必需的,并且它们不会被影子复制。

另一件有帮助的事情是通过将所有项目输出文件夹更改为“..\bin”来将所有项目构建到同一个输出文件夹中。例如,这意味着 A_UnitTests 不需要资源文件的链接(一旦卷影副本关闭)。

我有一种与您展示的方法类似的方法,它从程序集的位置(对我来说是共享 bin 文件夹)“向上”到解决方案的位置;并且我的相对路径“植根于”该文件夹。

如果这听起来太复杂,您可以使用与 A_UnitTests 相同的方法,包括从 B_UnitTests 指向它的链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2014-04-13
    相关资源
    最近更新 更多