Search code examples
c#visual-studiomsbuildassembly-resolution

msbuild reference assemblies resolve order while building solution with multiple .csproj in visual studio


I have a solution with multiple projects and these projects have nuget packages installed which are different in version. Looks when solution is rebuild, the version of dll copied to output directory is not deterministic and often I end up with runtime "file not found" exception for obvious reason. I will try to over simply the problem with below example :

Let's say ProjectA is cossole application and refers version 1.0.0 of assembly xyz.

ProjectA also refers to ProjectB in same solution via project reference. Now let say ProjectB references version 2.0.0 of assembly xyz.

I would like to know when solution is rebuild, is it deterministic which version of xyz dll will be copied to output directory ? If no, is there a way to ensure this. I know in that case I need to update config with appropriate binding re direction policy.


Solution

  • I would like to know when solution is rebuild, is it deterministic which version of xyz dll will be copied to output directory?

    Yes, the version 1.0.0 of xyz dll will be copied to output directory.

    According to the document Dependency resolution with PackageReference:

    When the package graph for an application contains different versions of the same package, NuGet chooses the package that's closest to the application in the graph and ignores all others. This behavior allows an application to override any particular package version in the dependency graph.

    In you case, the version 1.0.0 of xyz.dll is nearer to the projectA in the graph, that version will be copied to the output directory.

    Then I also created a test package xyz with version 1.0.0 and 2.0.0, add those two nuget package to the projectA and projectB, then ProjectA also refers to ProjectB, after build, the version 1.0.0 xyz.dll copied to the output directory:

    enter image description here

    Update:

    Can you check and confirm on the behavior when dll version is different in ProjectA and ProjectB \

    To verify this question, I have created a project xyz, generated the version 1.0.0 xyz.dll and 2.0.0 xyz.dll, then refers 2.0.0 xyz.dll to the project B and 1.0.0 xyz.dll to the project A, build the solution, got the same result: 1.0.0 xyz.dll will be copied to the output directory:

    enter image description here

    As the above test results, 1.0.0 xyz.dll will be copied to the output directory. When you got the file not found error, please check if you are invoke the method in version 2.0.0 the xyz.dll.

    Update2:

    screen shot you showing says file version (but file version is not same as assembly version)

    That because I want to be able check the AssemblyVersion in the windows explorer more convenient, I change the AssemblyVersion and AssemblyFileVersion at the same time before gnenerating the different version dll:

    Like:

    1.0.0 xyz.dll:

    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]
    

    2.0.0xyz.dll:

    [assembly: AssemblyVersion("2.0.0.0")]
    [assembly: AssemblyFileVersion("2.0.0.0")]
    

    So we just need check the file version instead of assembly version in wondows explorer for more convenient.

    Hope this helps.