首页 > 解决方案 > C# 项目如何链接程序集

问题描述

我想问一个关于 C# 如何链接其依赖项的问题。

第一种情况: 我有一个链接例如系统程序集的 C# 项目。如果我从Assembly->Framework窗口添加引用: 在此处输入图像描述

然后双击参考视图上的系统组件: 在此处输入图像描述

程序集的路径是:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.dll

但是如果我启用了 .nuget 并且它已经下载了程序集,系统程序集的链接将神奇地更改为:C:\Users\.nuget\packages\Microsoft.NETCore.Portable.Compatibility\1.0.0\ref \netcore50\System.dll

为什么我说“神奇”是因为我看不到明确表示的地方 - 从现在开始从那个方向进行组装。

第二种情况: 当我下载了 .nuget 程序集时,在项目参考窗口中,我看到了下一件事:

在此处输入图像描述

我的项目链接了两个不同版本的程序集,一个来自.nuget所在的地方,另一个来自.NET Framework所在的地方。问题:会考虑哪一个?两个都?

不过,只是一个想法。

当我使用 C++ 项目时,一切都非常清晰明了,我可能安装了几个不同的 SDK,但是当我定义 SDK 版本和要使用的工具集时 - 项目将从定义的位置获取程序集。它不会尝试从不同的地方加载某些东西,除非我指定了。

也许 C# 项目具有类似的配置能力,但我不知道它们。有人可以帮助我理解吗?

更新

刚刚意识到我在这里的声明:当我下载了 .nuget 程序集时,在项目参考窗口中,我看到了下一件事:可能令人困惑。在我列出的不同程序集版本中添加全屏截图: 在此处输入图像描述

另外,添加我的项目文件屏幕截图,以表明它没有明确说明从何处获取程序集的地方: 在此处输入图像描述

标签: c#uwp.net-core.net-assemblyassemblies

解决方案


这个问题有点糊涂。您需要考虑的一个重要区别是Visual Studio 如何引用程序集以及您编译的应用程序将如何引用。

视觉工作室

当您在 Visual Studio 中添加引用时,它会在 csproj 文件中添加一条记录:

<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
  <Private>True</Private>
</Reference>

以上包括“提示路径”。这告诉 Visual Studio 它认为程序集所在的位置。当您编译您的应用程序时,VS 将检查程序集的此路径。

当您使用 Nuget 安装程序集时。Nuget 将程序集添加到packages文件夹中,并将对该程序集的引用添加到您的 csproj 文件中。带有指向此位置的提示路径。所以VS会在这个位置加载程序集。

汇编

当您编译您的应用程序时,其结果是一个可运行的应用程序(dll、exe 等)。这个可运行的应用程序是您的 C# 的机器代码翻译。它包括到程序集的“链接”( DLL代表动态链接库)。

bin文件夹

当您编译您的应用程序时,您将在 VS 中的引用上有两个选项:

在此处输入图像描述

如果copy localTrueVisual Studio 将在构建的清单中包含 dll。这基本上意味着 dll 将在bin文件夹中结束。如果它是假的,它将不包括它,并且假定应用程序将能够从其他地方引用这个程序集。

那么它还能从哪里加载程序集呢?

您编译的应用程序将根据层次结构查找程序集。它将查找与您的清单匹配的程序集的第一个位置是bin文件夹。正如我们已经注意到的,尽管程序集并不总是在这里。

如果在这里找不到它,它将检查它正在运行的机器,看看它是否可以访问这些程序集。它检查的下一个位置是一个名为Global Assembly Cache的概念。这是在机器上注册的程序集和程序集位置的寄存器。

如果它仍然找不到它,它会抛出一个异常。

两个不同版本的程序集链接到我的项目,哪一个会被考虑?两个都?

不,它不能同时使用。如评论中所述,您可以使用alias(es) 来引用特定程序集,但这仍然一次使用一个程序集。

如果您不指定一个alias,我不希望这会起作用吗?我希望 VS 抱怨它不知道使用哪一个。您可以在app.config/中配置一个程序集重定向web.config

  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
  </dependentAssembly>

这会将竞争程序集映射到一个特定版本(通常是最新版本)


推荐阅读