NuGet packages not copied from referenced project

后端 未结 3 1656
情话喂你
情话喂你 2021-01-01 23:39

I have a very strange error I have no explanation for.

So my setup is very simple:

I have a solution with 2 projects, let\'s name them ProjectA and

相关标签:
3条回答
  • 2021-01-02 00:23

    Explanation

    For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.

    So the dependency chain looks like this: Y => X => A => B

    Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.

    Solution

    You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:

    1. Add a reference to assembly B in project Y.
    2. Add dummy code to a file in project X that uses assembly B.

    Personally I prefer option 2 for a couple reasons.

    1. If you add another project in the future that references project X, you won't have to remember to also include a reference to assembly B (like you would have to do with option 1).
    2. You can have explicit comments saying why the dummy code needs to be there and not to remove it. So if somebody does delete the code by accident (say with a refactor tool that looks for unused code), you can easily see from source control that the code is required and to restore it. If you use option 1 and somebody uses a refactor tool to clean up unused references, you don't have any comments; you will just see that a reference was removed from the .csproj file.

    Here is a sample of the "dummy code" that I typically add when I encounter this situation.

        // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
        private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
        {
            // Assembly A is used by this file, and that assembly depends on assembly B,
            // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
            // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
            // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
            // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
            var dummyType = typeof(B.SomeClass);
            Console.WriteLine(dummyType.FullName);
        }
    
    0 讨论(0)
  • 2021-01-02 00:24

    If the dependency graph is more complex than what you described you might have some versioning issues.

    1. Set the compiler output to diagnostics to see what’s happening: VS->Options->Projects and Solutions->Build and Run->MSBuild project build output vervosity:->Diagnostic enter image description here
    2. Compile the solution. If you find some issue similar to:

      There was a conflict between "X, Version=2, Culture=neutral, PublicKeyToken=null" and "X, Version=1, Culture=neutral, PublicKeyToken=null".

      "X, Version=2, Culture=neutral, PublicKeyToken=null" was chosen because it was primary and "X, Version=1, Culture=neutral, PublicKeyToken=null" was not.

    3. Try fixing that issue using the same dependency version everywhere and compile again.
    0 讨论(0)
  • 2021-01-02 00:37

    Was your ProjectA take use of the assemblies installed via NuGet packages?

    If types from the assemblies are used in ProjectA, then building ProjectB will place them in the output directory.

    0 讨论(0)
提交回复
热议问题