6

インターフェイス、抽象クラス、列挙型、構造体など、特定の型が依存しているすべての型を見つけようとしています。アセンブリをロードし、その中で定義されているすべての型のリストを出力したいと思います。それらの依存関係。

これまでのところ、CLRアセンブリがMono.Cecilを使用して依存しているすべての外部タイプを見つけることができました。

using System;
using Mono.Cecil;
using System.IO;

FileInfo f = new FileInfo("SomeAssembly.dll");
AssemblyDefinition assemDef = AssemblyFactory.GetAssembly (f.FullName); 
List<TypeReference> trList = new List<TypeReference>();

foreach(TypeReference tr in assemblyDef.MainModule.TypeReferences){
    trList.Add(tr.FullName);
}

このリストは、「monodis SomeAssembly.dll --typeref」などのモノラル逆アセンブラを使用して取得することもできますが、このリストには、System.Void、System.Int32などのプリミティブが含まれていないようです。

タイプが同じアセンブリで定義されている場合でも、各タイプを個別に処理し、特定のタイプが依存するすべてのタイプを取得する必要があります。Mono.Cecilまたは他のプロジェクトを使用してこれを行う方法はありますか?

アセンブリをロードし、定義された各タイプを反復処理し、タイプのILをロードして参照をスキャンすることで実行できることはわかっていますが、もっと良い方法があると確信しています。理想的には、匿名の内部クラスでも機能します。

同じアセンブリで複数のモジュールが定義されている場合にも機能するはずです。

4

2 に答える 2

1

AJ、アセンブリ内のタイプをトラバースする必要があるのと同じ問題があり、Mono.Cecilを使用することにしました。各クラスをウォークスルーする方法と、クラス内のプロパティがCLRタイプではなく別のクラスでない場合は、再帰関数を使用しました。

    private void BuildTree(ModuleDefinition tempModuleDef , TypeDefinition tempTypeDef, TreeNode rootNode = null)
    {
            AssemblyTypeList.Add(tempTypeDef);

            TreeNode tvTop = new TreeNode(tempTypeDef.Name);

            // list all properties
            foreach (PropertyDefinition tempPropertyDef in tempTypeDef.Properties)
            {
                //Check if the Property Type is actually a POCO in the same Assembly
                if (tempModuleDef.Types.Any(q => q.FullName == tempPropertyDef.PropertyType.FullName))
                {
                    TypeDefinition theType = tempModuleDef.Types.Where( q => q.FullName == tempPropertyDef.PropertyType.FullName)
                                                                .FirstOrDefault();
                    //Recursive Call
                    BuildTree(tempModuleDef, theType, tvTop);

                }

                TreeNode tvProperty = new TreeNode(tempPropertyDef.Name);
                tvTop.Nodes.Add(tvProperty);
            }

            if (rootNode == null)
                tvObjects.Nodes.Add(tvTop);
            else
                rootNode.Nodes.Add(tvTop);

    }

この関数は、私のメイン関数によって呼び出されます。その要点は次のとおりです。

      public void Main()
      {
        AssemblyDefinition  assemblyDef = AssemblyDefinition.ReadAssembly(dllname);

        //Populate Tree
        foreach (ModuleDefinition tempModuleDef in assemblyDef.Modules)
        {
            foreach (TypeDefinition tempTypeDef in tempModuleDef.Types)
            {
                BuildTree(tempModuleDef ,tempTypeDef, null);
            }
        }

      }
于 2012-09-04T08:51:28.970 に答える
-1

NDependを見てください-それはこれを行います、そしてはるかに。

-オシーン

于 2010-01-14T04:39:48.577 に答える