简体   繁体   English

C#项目如何链接程序集

[英]How C# projects link the assemblies

I'd like to ask a question about the way how C# links its dependencies. 我想问一个有关C#如何链接其依赖项的方式的问题。

First case: I have a C# project that links eg System assembly. 第一种情况:我有一个C#项目,可以链接例如系统程序集。 If I add reference from the Assembly->Framework window: 如果我从Assembly-> Framework窗口添加引用: 在此处输入图片说明

and then double click on the System assembly on the reference view: 然后在参考视图上双击“系统”程序集: 在此处输入图片说明

the path to the assembly would be: C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.5.2\\System.dll 程序集的路径为: C:\\ Program Files(x86)\\ Reference Assemblies \\ Microsoft \\ Framework.NETFramework \\ v4.5.2 \\ System.dll

But if I have .nuget enabled and it has downloaded the assemblies, the link to the system assembly would be magically changed to the: C:\\Users\\.nuget\\packages\\Microsoft.NETCore.Portable.Compatibility\\1.0.0\\ref\\netcore50\\System.dll 但是,如果启用了.nuget并下载了程序集,则指向系统程序集的链接将被神奇地更改为: C:\\ Users \\ .nuget \\ packages \\ Microsoft.NETCore.Portable.Compatibility \\ 1.0.0 \\ ref \\ netcore50 \\ System.dll中

Why I say "magically" is because I can't see the place that explicitly says - from now take the assembly from that direction. 我之所以说“神奇”是因为我看不到明确指出的地方-从现在开始沿那个方向进行组装。

Second case: When I have .nuget assemblies downloaded, on the Project Reference Window I see next thing: 第二种情况:当我下载了.nuget程序集时,在“项目参考”窗口中,我看到下一件事:

在此处输入图片说明

Two assemblies of the different versions are linked to my project, one is from the place where .nuget resides, the other is from the place where the .NET Framework resides. 不同版本的两个程序集链接到我的项目,一个来自.nuget所在的地方,另一个来自.NET Framework所在的地方。 Question: which one will be taken into account? 问题:将考虑哪一个? Both? 都?

Just a thought, though. 不过,只是一个想法。

When I work with C++ project, everything is super clear and straightforward, I may have few different SDKs installed, but when I define the SDK version and the toolset to be use and - the project will take assemblies from the defined place. 当我使用C ++项目时,一切都非常清晰明了,我可能安装了几种不同的SDK,但是当我定义要使用的SDK版本和工具集时,-该项目将从定义的位置获取程序集。 It doesn't try to load something from different place, unless I specified so. 除非我指定,否则它不会尝试从其他位置加载内容。

Maybe C# projects have similar configuration abilities but I'm not aware of them. 也许C#项目具有类似的配置功能,但我不了解它们。 Could somebody help me with understanding that? 有人可以帮助我理解这一点吗?

Update 更新

Just realized that my statement here: When I have .nuget assemblies downloaded, on the Project Reference Window I see next thing: might be confucing. 刚意识到我在这里的声明: 当我下载了.nuget程序集时,在“项目参考”窗口上,我看到了下一件事:可能令人困惑。 Adding full screen shot where I have listed to different assemblies versions: 将我列出的全屏快照添加到不同的程序集版本: 在此处输入图片说明

Also, adding my project file screenshot, to show that it doesn't have a place where it explicitly says to where from to take the assembly: 另外,添加我的项目文件屏幕快照,以表明它没有明确指出要从哪里组装的位置: 在此处输入图片说明

This question is all a bit muddled. 这个问题有点混乱。 An important distinction you need to think about is how visual studio references assemblies and how your compiled application will. 您需要考虑的重要区别是Visual Studio如何引用程序集以及编译后的应用程序将如何进行引用

Visual Studio 视觉工作室

When you add a reference in visual studio it adds a record into the csproj file: 当您在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>

The above includes a "hint path". 上面包含“提示路径”。 This tells visual studio where it thinks the assembly resides. 这就告诉Visual Studio它认为程序集所在的位置。 When you compile your app VS will check this path for the assembly. 编译应用程序时,VS将检查此路径以进行汇编。

when you install an assembly using Nuget. 当您使用Nuget安装部件时。 Nuget adds the assembly into packages folder and add's a reference to this assembly into you csproj file. Nuget将程序集添加到packages文件夹,并将对该程序集的引用添加到您的csproj文件中。 with a hint path that points at this location. 带有指向该位置的提示路径。 So VS will load the assembly this location. 因此,VS将在此位置加载程序集。

Compilation 汇编

When you compile your app the result of this is a runnable application (dll,exe, etc). 编译应用程序时,其结果是可运行的应用程序(dll,exe等)。 This runnable application is a machine code translation of your C#. 此可运行的应用程序是C#的机器代码翻译。 It includes "links" (DLL stands for D ynamic L ink L ibrary) to assemblies. 它包括“链接”(DLL代表d ynamic 大号墨液L ibrary)至组件。

bin folder bin文件夹

When you compile your app you will have two options on the reference in VS: 编译应用程序时,VS中的引用将有两个选项:

在此处输入图片说明

If copy local is True visual studio will include the dll in the manifest of the build. 如果copy localTrue Visual Studio将在构建清单中包含dll。 This basically means that dll will end up in the bin folder. 这基本上意味着dll将最终位于bin文件夹中。 If it's false it won't include it and it will be assumed that the application will be able to reference this assembly from somewhere else. 如果为假,它将不包含它,并且将假定该应用程序将能够从其他地方引用此程序集。

So where else can it load assemblies from? 那么它还能从哪里加载程序集呢?

Your compiled application will look for assemblies based on a hierachy. 您的已编译应用程序将基于层次结构查找程序集。 The first place it will look for an assembly that matches your manifest is the bin folder. 查找与清单匹配的程序集的第一个位置是bin文件夹。 As we've already noted though the assemblies aren't always here. 正如我们已经指出的,尽管程序集并不总是在这里。

If it can't find it here it will then check the machine it is running on to see if it has access to these assemblies. 如果在这里找不到它,它将检查正在运行的计算机,以查看是否可以访问这些程序集。 The next location it checks is a concept called the Global Assembly Cache . 它检查的下一个位置是称为全局程序集缓存的概念。 This is a register of assemblies registered on the machine and the assemblies location. 这是在机器和组件位置上注册的组件的寄存器。

If it still can't find it it, it will throw an exception. 如果仍然找不到它,它将抛出异常。

Two assemblies of the different versions are linked to my projectwhich one will be taken into account? 两个不同版本的程序集链接到我的项目中,将考虑哪一个? Both? 都?

No it can't use both. 不,它不能同时使用。 As noted in comments you can use alias (es) to reference a particular assembly but this still uses one assembly at a time. 注释中所述,您可以使用alias来引用特定的程序集,但是每次仍使用一个程序集。

If you don't specify an alias though, I wouldn't expect this to work? 如果您没有指定alias ,那么我不希望它起作用吗? I'd expect VS to complain it doesn't know which one to use. 我希望VS抱怨它不知道要使用哪个。 You could have an assembly re-direct configured in your app.config / web.config : 您可以在app.config / web.config配置app.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>

This will map competing assemblies to one particular version (usually the most recent) 这会将竞争程序集映射到一个特定版本(通常是最新版本)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM