- に関して。提案された重複:この質問は リンクされた質問 の反対を示唆しているので、 not 重複だと思います。
最初、私は読みました 「ローカルコピー」のベストプラクティスとプロジェクト参照を使用しますか? (また this )そして私はとにかくこれを試してみるために、しかしこれに関する一般的なフィードバックを得る必要があるようです docs このようなものはひどいですそして私はVS2010だけを使っていますそして多分彼らは新しいバージョンで何かを変更しました知っている。
Second、私は project references にのみ興味があります。私は GACからのアセンブリは異なる方法で処理されることを読んでください そしてGACは私の問題とは無関係です。
Third、提案された重複を読んだ後、しかしもっとそうニース answer ここ@Albireoによって、ファイルを区別することも重要であるように見えます依存関係。依存関係はdllアセンブリファイルを参照し、 project 依存関係(つまり、私が質問しているもの)は、依存関係はを参照します。 project および暗黙的にそのプロジェクトの出力ファイル。
/x1
/x2
/lib
すべてのdllアセンブリDLLアセンブリ all は、すべて同じ出力にビルドされるため、プロジェクト参照用にCopy Local
をfalse
に設定しますディレクトリ。
2 実行可能プロジェクトは、参照するすべてのDLLアセンブリプロジェクト参照に対してCopy Local
をtrue
に設定しましたDLLがそれぞれ/x1
/x2
にコピーされるように直接。
質問今はwrtです。 実行可能プロジェクトによって直接参照されていないであるが、参照されているアセンブリを介して推移的にのみであるDLLへ:アセンブリ、 「ローカルコピー」 is setの場合、 only は別のアセンブリを介して推移的に参照され、実行可能ファイルの出力フォルダーにコピーされます最初のアセンブリで本当ですか?
例:
x1.csproj
(例:出力= x1/one.exe
)dlA.csproj
(例:出力= lib/a.dll
)とCopy Local = *true*
dlA.csproj
(例:出力= lib/a.dll
)dlB.csproj
(例:出力= lib/b.dll
)とCopy Local = **false**
dlC.csproj
(例:出力= lib/c.dll
)したがって、one.exe -> a.dll -> b.dll -> c.dll
の論理依存関係があり、a.dll
のみがone.exe
の出力ディレクトリに明らかにコピーされます。 他の2つのdllも出力ディレクトリにコピーされますか?これはどこかに文書化されていますか?
そして、はい、私はそれを試しました。そして、はい、それは動作しているようですですが、私はまだそれを十分に突っ込んでおらず、とにかく私が見逃したかもしれない何かがあります。 (また、公式ドキュメントに関する質問もあります。)
また、依存関係がdllアセンブリファイルとプロジェクトの依存関係(つまり、私が求めているもの)を参照するファイルの依存関係を区別することが重要であるように見えます。依存関係はプロジェクトを参照し、暗黙的にそのプロジェクトの出力ファイルを参照します。
そうではありません。
MSBuildは、参照がソリューション内の別のプロジェクトを指しているのか、DLLを指しているのかを実際には気にしません。
ProjectA
がProjectB
に依存してビルドする場合ProjectA
ProjectB
はすでにビルドされている(そして最新である)必要がある場合、MSBuildはそのDLL(C#コードではありません)そしてそれをProjectA
にリンクします。
DLLの代わりにプロジェクト参照を追加することは、便宜上「シンタックスシュガー」です。このようにして、MSBuildは、出力が何であれ、参照されるプロジェクトの出力を選択する必要があることを認識します。
それ以外の場合は、依存関係を手動で事前ビルドし、そのDLLを見つけてプロジェクトにリンクし、ビルド構成を切り替えたり、移動したり、名前を変更したりするたびにプロセスを繰り返す必要があります。あまり実用的ではありません。
他の2つのdllも出力ディレクトリにコピーされますか?
依存関係の要素が、アセンブリが参照されているプロジェクトから直接使用されている場合、その参照がコピーされます。
例として、次のソリューションレイアウトがあります。
この依存関係チェーンの場合:
このソリューションをビルドすると、MySolution.ConsoleApplication
出力ディレクトリにMySolution.FirstDependency
、MySolution.SecondDependency
、およびMySolution.ThirdDependency
のDLLがありますが、MySolution.FourthDependency
のDLLはありません。
なぜそうなのですか? MSBuildがMySolution.SecondDependency
をビルドすると、MySolution.FourthDependency
に宣言された依存関係があることに気付きますが、MySolution.FourthDependency
コード内のMySolution.SecondDependency
からの要素の使用法が見つからないため、何らかの「最適化」を実行することにします。そして、出力からMySolution.FourthDependency
Assemblyを省略します。
これと同じ問題が過去にNuGetAutoMapperを介して「深い依存関係」に追加したときに私を悩ませました。AutoMapperを追加すると、2つのアセンブリ参照AutoMapper
とAutoMapper.Net4
が追加され、2番目のアセンブリは最初のアセンブリによって最初のアセンブリによって読み込まれます。 .NET Framework 4によって導入された新しいコレクションオブジェクトに対して特定の種類のアクションを実行する必要があります。2番目のアセンブリはリフレクションを介して読み込まれるため、MSBuildは未使用であると見なし、わざわざコピーする必要はありません。
つまり、yes、直接使用している限りコピーされますリフレクションではありません。
これはどこかに文書化されていますか?
この動作はMSBuildの「機能」のようです。この問題が発生したときに、Microsoftの何人かの人々によるブログ投稿を見つけることができましたが、現時点では再び見つけることができません。
それは非常に簡単で、ローカルコピーとは何の関係もありません。 MSBuildは、アセンブリのメタデータを調べて、アセンブリの依存関係を確認します。アセンブリでildasm.exeを実行し、マニフェストをダブルクリックします。洞察を得るためにこれを試してみてください。 .Assembly
ディレクティブが表示されます。コンパイラがアセンブリをビルドしたときに挿入され、コードで実際に使用した参照アセンブリのみが一覧表示されます。
MSBuildが同じディレクトリでそのようなアセンブリを見つけることができる場合、MSBuildはそれを自動的にコピーします。そうでない場合は、サイレントコピーをスキップします。
これから、故障モードを推測できます。アンマネージDLLはコピーできず、メタデータには表示されません。 Assembly.Load/From()を介して間接的に依存しているアセンブリをコピーすることはできません。また、メタデータにも表示されません。まだビルドされていないアセンブリをコピーすることはできません。ビルド順序の問題です。また、CopyLocalプロパティをFalseに設定したアセンブリをコピーすることはできません。これは通常、アセンブリがGACに存在する場合にのみ有効な選択であり、コピーは必要ありません。
あなたが助ける必要があるそのような場合のために、ビルド後のイベントのXCOPYは仕事を成し遂げます。