Как найти все зависимости (файлы классов) для файла класса C # - PullRequest
0 голосов
/ 21 октября 2011

У меня есть несколько тестовых классов в C # ( NUnit Test scripts , компиляция в Mono).

Вместо того, чтобы собирать все модульные тесты в одну большую сборку, как обычно, яЯ хотел бы скомпилировать отдельные файлы классов в отдельные сборки.Для этого я хотел бы выполнить анализ зависимостей, чтобы я мог автоматически генерировать отдельные сборки.

То, что я ищу, похоже на анализатор зависимостей классов, который существует для Java

Ответы [ 2 ]

0 голосов
/ 24 октября 2011

Посмотрите на Моно Сесил.

Эта библиотека имеет возможность «отражать» (не очень удачное название для этого) фактическое изображение сборки для проведения анализа.Это предполагает, что вы захотите скомпилировать в «большую» сборку, чтобы запустить анализ зависимостей с помощью Mono.Cecil.

Редактировать На самом деле вы можете простоиспользуйте Сесил, чтобы скопировать «большую» сборку, отфильтровывая ее части.Таким образом, у вас не будет большой сложности компиляции отдельных сборок;Посмотрите на пример CecilRoundtrip для примера того, как выполнить циклическое ( чтение -> манипулирование -> сохранить ) сборок в Cecil.

Ранее я опубликовал довольно обширные примеры использования 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.String, System.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
0 голосов
/ 23 октября 2011

Предполагая, что вы хотите запустить nunit тесты на моно, это должно работать нормально (я рад, что использую NUnit 2.5 и 2.4 на моно 2.10.6).

Одной из распространенных ошибок является только копирование или отслеживание 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 );
  }
}

Осторожно, при этом будут найдены только имена сборок, с которыми была скомпилирована программа или библиотека, а не имена, которые могут динамически загружаться во время выполнения.

...