.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でエラーの説明を送信するか、 エラートラッカーに登録してください 。 開発者ガイドでは、プロジェクトが参照するアセンブリの評価基準について説明し、拡張機能の一般的なアーキテクチャの概念を示します。



All Articles