2013-11-11 3 views
3

Предположим, у вас есть сборка A, содержащая кучу довольно стандартных не обфусканных классов.Ввод кода в .NET

Есть ли способ программно создать какую-то «насмешливую» сборку B, которая будет содержать все методы, находящиеся в сборке A, но все эти методы в сборке B должны иметь код пользователя, введенный в начале метода и в конце, так что, когда сборка B будет выполнена, она будет работать с нормальным + введенным кодом пользователя. Введенный код будет использоваться для профилирования. Можно ли как-то выполнить (я уже использую профилировщик ANTS, поэтому нет необходимости в каких-либо инструментах профилирования, меня просто интересует, можно ли решить проблему указанным способом)

Спасибо!

EDIT

Ребята, я говорю о написании отдельного приложения (аналог http://codeinject.codeplex.com/), способный принимать любые сборки .NET в качестве входных данных и производит другую, которая будет содержать:

  1. весь код первого один
  2. специального пользовательского код вводится в каждый метод сборки существ ... Ну, будучи «издевался»

Предположим, что мы имеем следующий код:

AssemblyA.dll:

class Test 
{ 
    void Action1(int someArgument) 
    { 
     ... 
    } 

    void Action2(bool someBool) 
    { 
     ... 
    } 

    public void DoSomeAction() 
    { 
     Action1(123); 
     ... 
     Action2(true) 
    } 
} 

Injector.dll:

public class Injector: IInjector 
{ 
    Dictionary<String, Int32> profiler = new Dictionary<String, Int32>(); 

    void BeforeInvoke(IMethodCall call) 
    { 
     Console.WriteLine("A method {0} being called", call.Method.Name); 
    } 

    void AfterInvoke(IMethodCall call) 
    { 
     Console.WriteLine("A method {0} was called, duration {1}", call.Method.Name, call.Duration); 
    } 
} 

Это позволит сделать следующее:

> inject.exe AssemblyA.dll Injector.dll AssemblyB.dll 

когда вы ссылаетесь на AssemblyB.dll и используете в производственной среде, он будет делать все, что делает AssemblyA.dll, но также будет выполнять некоторую регистрацию производительности, которая впоследствии может быть проанализирована и проанализирована более dev-like.

Мой вопрос:

Где я должен начать искать?

+0

[Fody] (https://github.com/Fody/Fody) приходит на ум, как описано ниже [PostSharp] (http://www.postsharp.net/) для AoP, а также общая схема перехвата, используемая при использовании IoC. Ни один из них не свободен, как ваш 'inject.exe', но все они являются жизнеспособным механизмом * того, как может быть написано мифическое приложение. –

ответ

1

Это зависит от того, сколько у вас контроля над сборкой А. Если вы сами создаете сборку A, вы можете использовать аспектно-ориентированное программирование (AOP) для ввода кода, который вы хотите выполнить до и после каждого метода. Популярным инструментом для достижения этого является PostSharp, который вводит код в IL. Посмотрите на OnMethodBoundaryAspect. Существует также бесплатная версия Express.
Для сборок, которые не находятся под вашим контролем, гораздо сложнее:
Если сборка не имеет сильного имени или у вас есть доступ к ключу подписи, вы можете ее разобрать, например. с ILDASM с параметром/out. Затем вы можете вводить новые коды в файл IL и снова собирать файл, используя ILASM. Это, конечно, не слишком просто, но единственный способ, которым я могу думать, это разрешить профилирование всех вызовов. Имейте в виду, что также могут возникнуть юридические проблемы, если вам не разрешается разбирать сборку A и уважать их.
Если вы получаете доступ ко всем методам A через интерфейс или хотите добавить код к виртуальным членам классов, вы можете использовать контейнер Inversion of Control для перехвата вызовов (см. Code Code answer). Это возможно с разумными усилиями, но поскольку перехваты выполняются во время выполнения, это немного ухудшит производительность.
Другой подход - использовать отражение и CodeDOM для анализа типов в сборке A и создания кода, который обертывает вызовы методам. Таким образом, вы можете также профилировать не виртуальных, публичных пользователей. Конечно, внутренние вызовы в сборке А не профилируются.

+0

Нет, это не сильное имя, я просто хочу профилировать мое приложение, но вместо использования профилировщика StopWatch или ANTS я хочу автоматически профилировать каждый метод, я знаю, что это может привести к некоторой деградации производительности, но это не так это большое дело. Reflection + CodeDom - интересный подход, но, к сожалению, для подражания каждой конструкции CLR это будет способ записи другого рефлектора, возможно, есть более простой способ сделать это? – Lu4

+0

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

+0

Я работаю над довольно крупным проектом, около двух лет разработки 10-20 разработчиками, включая общесистемную структуру на данный момент не представляется возможным, мы не сможем охватить еще более или менее значительную часть код с ним. Было бы здорово, если бы мы могли просто выбрать методы, которые хотим профилировать, и собирать тайминги, которые нас интересуют, не уверены, можем ли мы сделать это с AOP – Lu4

Смежные вопросы