Как найти все методы в сборке, которые создают объект класса X? - PullRequest
3 голосов
/ 24 декабря 2010

Интересный вопрос здесь: в моем текущем проекте мы используем специальный набор для мониторинга производительности, который сильно загружен конфигурацией (в нем используется Perfmon, поэтому мы должны вручную регистрировать каждый счетчик производительности. Для каждого метода, который мымонитор, и их много).

Мне было интересно, есть ли какие-либо инструменты, которые, скажем, позволят мне проанализировать сборку проекта, найти все методы, которые создают экземпляр класса XClass, затемзаписать их в файл?Это позволило бы мне сократить количество ручной настройки, которое мне нужно сделать, с большим запасом.

Спасибо, Эд

РЕДАКТИРОВАТЬ

Извините, пишите ихфайл был немного надуманным: мне действительно нужно переформатировать их с некоторыми дополнительными данными и записать их в формате XML, специфичном для конфигурации.Это было бы лучше, если бы я мог закодировать его, чтобы он мог быть задан как задача сборки (чтобы мне не пришлось запускать его вручную), и любые будущие изменения можно было легко сделать и задокументировать и т. Д.

Ответы [ 4 ]

5 голосов
/ 24 декабря 2010

Открыть сборку в Отражатель (бесплатная версия в порядке); найдите тип ( F3 ), затем откройте анализатор ( Ctrl + R ) и разверните узел «Instantiated By».

Затем щелкните правой кнопкой мыши по самому узлу «Instantiated By» и нажмите «Копировать»; например:

System.Data.SqlClient.SqlConnectionStringBuilder
    Depends On
    Used By
    Exposed By
    Instantiated By
        SqlDependencyProcessDispatcher.GetHashHelper(String, SqlConnectionStringBuilder&, DbConnectionPoolIdentity&, String&, String) : SqlConnectionContainerHashHelper
        System.Data.SqlClient.SqlClientFactory.CreateConnectionStringBuilder() : DbConnectionStringBuilder
        System.Web.Management.SqlWebEventProvider.Initialize(String, NameValueCollection) : Void
        System.Web.SessionState.SqlSessionStateStore.CreatePartitionInfo(String) : IPartitionInfo
        System.Web.SessionState.SqlSessionStateStore+SqlPartitionInfo.get_TracingPartitionString() : String
        System.Web.SessionState.SqlSessionStateStore+SqlStateConnection..ctor(SqlPartitionInfo, TimeSpan)
2 голосов
/ 24 декабря 2010

Если вам нужно написать код для автоматизации вашей задачи, это легко сделать с помощью Mono.Cecil .В качестве примера этот код ищет во всех методах типов верхнего уровня сборки экземпляр класса Foo.Bar.Baz:

using Mono.Cecil;
using Mono.Cecil.Cil;

// ...

static void SearchMethod (MethodDefinition method)
{    
    foreach (var instruction in method.Body.Instructions) {
        if (instruction.OpCode != OpCodes.Newobj)
            continue;

        var constructor = (MethodReference) instruction.Operand;
        if (constructor.DeclaringType.FullName != "Foo.Bar.Baz")
            continue;

        Console.WriteLine ("new Foo.Bar.Baz in {0}", method.FullName);
    }
}

static void Main ()
{
    var module = ModuleDefinition.ReadModule ("Foo.Bar.dll");
    var methods = module.Types.SelectMany (t => t.Methods).Where (m => m.HasBody);
    foreach (var method in methods)
         SearchMethod (method);
}
1 голос
/ 24 декабря 2010

Взгляните на NDepend . Это инструмент статического анализа с очень мощным языком запросов: CQL ( Code Query Language ).

Обновление

NDepend имеет консольное приложение, которое можно использовать для автоматизации (например, для использования в системах сборки) и может выводить отчеты в файл.

Пример запроса для поиска методов, которые создают экземпляр определенного типа:

ВЫБРАТЬ МЕТОДЫ, ГДЕ Создать A "MyNamespace.MyClass"

0 голосов
/ 24 декабря 2010

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

Тем не менее, вы можете посмотреть в пространстве имен System.Reflection (из памяти), где используется класс Assembly.

...