简体   繁体   中英

How C# projects link the assemblies

I'd like to ask a question about the way how C# links its dependencies.

First case: I have a C# project that links eg System assembly. If I add reference from the Assembly->Framework window: 在此处输入图片说明

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

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

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:

在此处输入图片说明

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. 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. 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. 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. 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

When you add a reference in visual studio it adds a record into the csproj file:

<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. When you compile your app VS will check this path for the assembly.

when you install an assembly using Nuget. Nuget adds the assembly into packages folder and add's a reference to this assembly into you csproj file. with a hint path that points at this location. So VS will load the assembly this location.

Compilation

When you compile your app the result of this is a runnable application (dll,exe, etc). This runnable application is a machine code translation of your C#. It includes "links" (DLL stands for D ynamic L ink L ibrary) to assemblies.

bin folder

When you compile your app you will have two options on the reference in VS:

在此处输入图片说明

If copy local is True visual studio will include the dll in the manifest of the build. This basically means that dll will end up in the bin folder. 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. 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.

If you don't specify an alias though, I wouldn't expect this to work? I'd expect VS to complain it doesn't know which one to use. You could have an assembly re-direct configured in your 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>

This will map competing assemblies to one particular version (usually the most recent)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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