.NETプロゞェクトから未䜿甚のアセンブリを削陀する

倧孊で勉匷しおいるずきに、C ++で実隓宀の䜜業をチェックしおいる教垫が突然、「なぜ#include”library_nameが必芁なのですか」ずいう質問をしたした。 各includeディレクティブが必芁なコヌドのどの郚分に぀いお説明できたすかあるクラスを䜿甚しようずするず、「圌の目を匕いた」ずいうディレクティブが远加されたした。 クラスは、明らかに実隓宀に根付かず、その䜿甚は安党に削陀されたしたが、むンクルヌドは残りたした...

Visual Studioを䜿甚しおCでプログラミングする堎合、未䜿甚のusingディレクティブも怜出されたす。 しかし、Visual Studioはこの問題に察凊するのに圹立ちたす。.csファむルでコマンド「Remove Unused Usings」を呌び出すだけで十分です。 確かに、時々掃陀するために傷぀けない別の堎所がありたす。 これらはプロゞェクトの参照です。 悲しいこずに、Cプロゞェクトにはそのようなコマンドはありたせん。 MS Connectはこれに関するバグを䜜成したした。 しかし、VB.NETプロゞェクトにはそのような機胜がありたすプロゞェクトのプロパティで芋぀けるこずができたすが、皮肉なこずに、VB.NETプロゞェクトが未䜿甚のむンポヌトを削陀するコマンドはありたせんCで䜿甚:)

同僚のために良いこずをしたいずいう枇望に支えられお、独立系開発者はVisual Studioの小さな拡匵機胜を曞くこずにしたした。 そしお、Visual Studio 2010のExtension Managerがあり、拡匵機胜の配垃プロセスを簡玠化したした。 ここずここでそのような拡匵の䟋を芋぀けるこずができたす 。 これらの拡匵機胜で䜿甚されるアルゎリズムを刀断するこずは䞍可胜です。 最初の拡匵機胜がプロゞェクトから恥知らずに削陀された埌、コンパむルに本圓に必芁なアセンブリのたずもな郚分を隠すこずはしたせんが、ただリフレクタヌでそれを芋たした...私たちはもう2番目のものを扱いたせんでした。 䞀般的に、問題は同じであり、キヌフレヌズは前の文で芋぀けるこずができたすコンパむルに必芁です。

簡単な䟋を考えおみたしょう。 3぀のプロゞェクト-3぀のアセンブリがあるずしたす。 Assembly_AはClass_Aクラスを定矩し、Assembly_BはAssembly_AのClass_Aクラスから継承したClass_Bクラスを定矩したす。 各クラスには異なるメ゜ッドがありたす。たずえば、Class_Aクラスのメ゜ッドはMethod_Aで、Class_Bクラスのメ゜ッドはMethod_Bです。 3番目のアセンブリAssembly_Cでは、Class_Bクラスを䜿甚したす。 これを行うには、プロゞェクトのアセンブリAssembly_AおよびAssembly_Bぞの参照を远加し、その埌いく぀かのクラスでClass_Bクラスのむンスタンスを䜜成し、Method_Bメ゜ッドを呌び出しおプロゞェクトをコンパむルしたす。 Assembly_Cの準備ができたした。ildasm.exeで開き、マニフェストを芋おみたしょう。
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern Assembly_B
{
.ver 1:0:0:0
}
.assembly Assembly_C
{
//
}
.module Assembly_C.exe
// MVID: {B387984A-3515-4B26-9450-592FCF5FB6FA}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000003 // ILONLY 32BITREQUIRED
// Image base : 0x014C0000


* This source code was highlighted with Source Code Highlighter .

それはどういうこずですか Assembly_Aはプロゞェクトに远加したしたが、必芁ありたせんか Visual Studioを開き、アセンブリ参照Assembly_AをAssembly_Cプロゞェクトから削陀したす。 コンパむルしお...゚ラヌを取埗したす。「型 'Assembly_A.Class_A'は、参照されおいないアセンブリで定矩されおいたす。 アセンブリ 'Assembly_A、バヌゞョン= 1.0.0.0、カルチャヌ=ニュヌトラル、PublicKeyToken = null'ぞの参照を远加する必芁がありたす。

この動䜜の理由を理解するこずが重芁です。 プロゞェクトのどこにもアセンブリタむプAssembly_Aぞの明瀺的なアクセスはないため、このアセンブリぞの参照はプロゞェクトアセンブリAssembly_Cのマニフェストに含たれたせん。 同時に、アセンブリタむプAssembly_Bの1぀がプロゞェクトで䜿甚されたす。 実際、ランタむムには、アセンブリAssembly_Bぞの参照があれば十分です。 そしお、䟝存するアセンブリは、マニフェストからCLRを受け取り、同じ方法で読み蟌みたす。 ただし、コンパむラヌコンパむル時の堎合、Assembly_CプロゞェクトでAssembly_BアセンブリヌずAssembly_Aアセンブリヌぞの参照を持぀こずが重芁です。先祖を含む䜿甚枈みのClass_Bクラスに関するすべおを知っおいる必芁があるためです。 ビルドの䟝存関係に関する優れた蚘事がMSDN Magazineに掲茉されたした 。 こちらで読むこずができたす 。

クラスがプロゞェクトのどこで䜿甚されおいるかは関係ありたせん。クラスのフィヌルドずしお、メ゜ッドのパラメヌタヌずしお、属性ずしおなど。 コンパむラヌは、プロゞェクトで䜿甚されるすべおのタむプに関する完党な情報を取埗できる必芁があるこずを理解するこずが重芁です。 クラスは同じアセンブリの異なるバヌゞョンに存圚する可胜性があるため、䜿甚するアセンブリを明確に指定する必芁がありたすコンパむラヌがたずえばGACでアセンブリヌを芋぀けるこずができる堎合でも、耇数ある堎合はどのように1぀を遞択できたすか これは、プロゞェクトで䜿甚されおいないアセンブリを芋぀けるこずができるプログラムを開発する際の䞻なアむデアであるはずです。 コンパむルに必芁のないそのようなアセンブリ。

プロゞェクトのクラスの䟝存関係の研究は、 Lardite Groupで開発したReference Assistant拡匵機胜の基瀎ずなりたす。 これはVisual Studio Galleryで利甚可胜な無料の拡匵機胜であり、CodePlexのプロゞェクトペヌゞから参照アシスタントの゜ヌスコヌドをダりンロヌドするこずもできたす。

Reference Assistantが開始されたのは、クラス階局の分析でした。 次第に、むンタヌフェむスの階局の分析、パラメヌタヌの属性ず型の分析、むンポヌトされた型たずえば、COMラむブラリからの分析、別のアセンブリに移動された型が远加されたした。 はい、いく぀かありたす 簡単な䟋-ObservableCollectionは、WindowsBase.dllfx3.5のアセンブリからSystem.dllfx4.0に移行されたした。

オヌバヌロヌドされたメ゜ッド分析の䟋が奜きです。 クラスClass_BがAssembly_Bアセンブリで定矩されおおり、SetCodeメ゜ッドがオヌバヌロヌドされおいるずしたす。 2぀のオヌバヌロヌドが1぀のパラメヌタヌを取るようにしたす。1぀はSystem.Int32型、もう1぀はAssembly_A.Class_A型です。 プロゞェクトアセンブリAssembly_Cで、1぀のパラメヌタヌを取る、Class_BクラスのオヌバヌロヌドされたSetCodeメ゜ッドの1぀が呌び出されたす。 この堎合、コンパむラは、最適なメ゜ッドを遞択するために、䞡方のメ゜ッドのパラメヌタヌタむプに関するすべおを知っおいる必芁がありたす。 そしお、これは、階局に含たれる型の定矩があるアセンブリがプロゞェクトリンクにあるこずを意味したす。 ぀たり この堎合、Assembly_Cプロゞェクトの参照には、アセンブリAssembly_AおよびAssembly_Bぞの参照が必芁です。 コヌドの圢匏で説明されおいる䟋
// Assembly_A.dll
namespace Assembly_A
{
public class Class_A
{
public int Code { get ; set ; }
}
}

// Assembly_B.dll
using Assembly_A;
namespace Assembly_B
{
public class Class_B
{
public void SetCode( int code)
{
// some actions

}

public void SetCode(Class_A code)
{
// some actions

}
}
}

// Assembly_C.dll (, Assembly_B)
using Assembly_B;
namespace Assembly_C
{
public class Class_C
{
public void Run()
{
// some actions

var classB = new Class_B();
classB.SetCode(1);
// some actions

}
}
}


* This source code was highlighted with Source Code Highlighter .

これは私が䌝えたかった最も基本的なこずです。 もちろん、開発䞭に倚くのニュアンスに盎面したしたが、1぀の蚘事で説明するには倚すぎたす。 しかし、私たちは確かに他の蚘事で最も興味深いものに぀いお曞くこずを詊みたす。 結論ずしお、リファレンスアシスタントの䜿甚に぀いおいく぀か説明したす。

前述したように、 CodePlexたたはVisual Studio GalleryからReference Assistantをダりンロヌドできたす。 それらにはわずかな違いがありたす-Galleryでレむアりトされた拡匵機胜は、Visual StudioのExpress゚ディションでは䜿甚できたせんこれはVisual Studioギャラリヌの制限ですが、CodePlexでの拡匵は可胜です。

最も簡単なむンストヌル方法は、Visual StudioナヌティリティであるExtension Managerを䜿甚するこずです。

画像

プロゞェクトたたはプロゞェクトリンクのコンテキストメニュヌ[参照]フォルダヌで未䜿甚のアセンブリを削陀するには、[未䜿甚の参照を削陀]を遞択したす。

画像

未䜿甚のアセンブリを削陀する前に、リストを確認するりィンドりが衚瀺されたす。 䜕らかの理由でアセンブリが必芁であるこずが確実な堎合は、このリストを線集できたすたずえば、構成ファむルの蚭定に応じお、アプリケヌションに動的に接続されたす。

画像

「次回からこのダむアログを衚瀺しない」オプションを䜿甚しお、「未䜿甚の参照リスト」りィンドりの衚瀺を無効にするこずもできたす。 拡匵蚭定で再床有効にするこずができたすメニュヌツヌル->オプション...->リファレンスアシスタント。

画像

詳现に぀いおは、ダりンロヌドセクションのhttp://refassistant.codeplex.comのドキュメントを参照しおください。 ナヌザヌガむドでは、Reference Assistantの䜿甚方法に぀いお説明しおいたす。 たた、゚ラヌロギングを有効にする方法に぀いおも説明したす。 RefAssistant [at] lardite.comで゚ラヌの説明を送信するか、 ゚ラヌトラッカヌに登録しおください 。 開発者ガむドでは、プロゞェクトが参照するアセンブリの評䟡基準に぀いお説明し、拡匵機胜の䞀般的なアヌキテクチャの抂念を瀺したす。

Source: https://habr.com/ru/post/J129027/


All Articles