如何查找C#类文件的所有依赖项(类文件)

时间:2011-10-21 10:35:57

标签: visual-studio-2010 c#-4.0 mono nunit code-analysis

我在C#中有许多测试类(NUnit Test scripts,在Mono上编译)。

我没有像往常一样将所有单元测试编译成一个大型程序集,而是将各个类文件编译成单独的程序集。为此,我想进行依赖性分析,因此我可以自动生成单独的程序集。

我正在寻找的类似于Java

存在的类依赖性分析器

2 个答案:

答案 0 :(得分:0)

假设您想在单声道上运行nunit测试,那应该可以正常工作(我很高兴在单声道2.10.6上使用NUnit 2.5和2.4)。

一个常见的错误是只复制或跟踪包含测试的.dll文件。像任何程序一样,测试具有依赖性,在您的情况下,它们至少是nunit.framework.dll加上您希望测试的类/程序集(以及它的任何依赖项)

如果你想要的只是找到给定dll引用的程序集(它需要运行的东西),你可以很容易地做到这一点:

using System.Reflection;

void PrintRefs( string dllfile ){
  var asm = Assembly.ReflectionOnlyLoad ( dllfile );

  foreach ( var aname in asm.GetReferencedAssemblies() ){
    Console.WriteLine( aname.Name );
  }
}

请注意,这只会找到编译程序或库的程序集的名称,而不是可能在运行时动态加载的程序集的名称。

答案 1 :(得分:0)

看看Mono Cecil。

该库能够在实际装配图像上“反映”(不是一个非常好的名称)来进行分析。这假设您愿意编译为“大”程序集,以便使用Mono.Cecil运行依赖项分析。

  

编辑实际上,您可能只是使用Cecil复制“大”程序集,同时过滤掉部分内容。这样,编译单独的程序集就不会有太多复杂性;请查看 CecilRoundtrip sample ,了解如何在Cecil中进行往返( read - >操作 - >保存)程序集的示例。

我之前发布了很多关于如何使用Mono Cecil进行“高级”搜索的示例(实质上是静态调用树搜索):

对您最有用的绝对最低限度可能是:

var types = assemblies
    .SelectMany(assembly => assembly.MainModule.Types.Cast<TypeDefinition>());

var dependencies = types.ToDictionary(
    key => key,
    typedef => new HashSet<string>(typedef.Methods.Cast<MethodDefinition>()
                .Where(method => null != method.Body) // ignore abstracts and generics
                .SelectMany(method => method.Body.Instructions.Cast<Instruction>())
                .Select(instr => instr.Operand)
                .OfType<TypeReference>().Distinct()
          //    .Where(type => !type.Namespace.StartsWith("System"))
                .Select(type => type.Name)));

foreach (var entry in dependencies)
{
     Console.WriteLine("{0}\t{1}", entry.Key.Name, string.Join(", ", entry.Value.ToArray()));
}

注意注释行可选择过滤框架中的内容(System.StringSystem.Char等。)。

这将列出每种声明类型所需的类型。要列出使用的类型,只需在查找程序集名称上标记:

                .Select(type => type.Module.Assembly.Name.Name)));

第一类样本输出(需要的类型):

SegmentSoortKenmerk     SegmentSoortKenmerk
OperatorValue
Koppelpad       Koppelpad, CodeLeidendVolgend
RedenWaarschuwing
RelExceptions
GecontroleerdDocument   GecontroleerdDocument, GecontroleerdDocument[]
OwiExtraKenmerk OwiExtraKenmerk, Gegeven, BackofficeRelatie
Entiteit        Entiteit, SleutelSysteemObject[], EniteitType

类似的查询,但使用程序集名称查找:

SegmentSoortKenmerk     Lspo.Business
OperatorValue
Koppelpad       Lspo.Business
RedenWaarschuwing
RelExceptions
GecontroleerdDocument   Lspo.Business
OwiExtraKenmerk Lspo.Business
Entiteit        Lspo.Business