13

説明のつかない非常に奇妙なエラーがあります。

したがって、私のセットアップは非常に簡単です。

ProjectAProjectBという名前を付けましょう。 ProjectAはいくつかの NuGet パッケージを参照しており、 ProjectAをビルドすると、出力ディレクトリのbinフォルダー にすべてのアセンブリが表示されます。ProjectBはProjectAを参照するようになりましたが、ProjectBをビルドすると、出力ディレクトリにProjectAアセンブリがありますが、 ProjectAから参照される NuGet パッケージはありません。

ProjectBからProjectAへの参照は、 References -> Add Reference... -> Solution -> ProjectAで追加されます。

このケースをカバーする小さなテスト プロジェクトも作成しましたが、テスト プロジェクトでは問題なく動作します。

何か案は?

4

3 に答える 3

19

説明

サンプル シナリオとして、プロジェクト X、アセンブリ A、およびアセンブリ B があるとします。アセンブリ A はアセンブリ B を参照するため、プロジェクト X には A と B の両方への参照が含まれます。また、プロジェクト X には、アセンブリ A を参照するコードが含まれます (たとえば、A. SomeFunction())。ここで、プロジェクト X を参照する新しいプロジェクト Y を作成します。

したがって、依存チェーンは次のようになります: Y => X => A => B

Visual Studio / MSBuild は賢く、プロジェクト X に必要であると検出された参照のみをプロジェクト Y に持ち込もうとします。これは、プロジェクト Y での参照汚染を回避するために行われます。問題は、プロジェクト X にはアセンブリ B を明示的に使用するコード (B.SomeFunction() など) が実際には含まれていないため、VS/MSBuild は B が必要であることを検出しないことです。したがって、プロジェクト Y の bin ディレクトリにコピーしません。X および A アセンブリのみをコピーします。

解決

この問題を解決するには 2 つの方法があります。どちらの方法でも、アセンブリ B がプロジェクト Y の bin ディレクトリにコピーされます。

  1. プロジェクト Y のアセンブリ B への参照を追加します。
  2. アセンブリ B を使用するプロジェクト X のファイルにダミー コードを追加します。

個人的には、いくつかの理由からオプション 2 を好みます。

  1. 将来、プロジェクト X を参照する別のプロジェクトを追加する場合、アセンブリ B への参照も含めることを忘れないでください (オプション 1 で行う必要があるように)。
  2. ダミーコードが必要な理由を明示的にコメントして、それを削除しないようにすることができます。そのため、誰かが誤ってコードを削除してしまった場合 (未使用のコードを探すリファクタリング ツールなどで)、ソース管理からそのコードが必要であることを簡単に確認して、それを復元することができます。オプション 1 を使用し、誰かがリファクタリング ツールを使用して未使用の参照をクリーンアップした場合、コメントはありません。参照が .csproj ファイルから削除されたことがわかります。

これは、この状況に遭遇したときに通常追加する「ダミー コード」のサンプルです。

    // 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);
    }
于 2014-01-10T22:27:20.273 に答える