Suppose you have an assembly A containing a bunch of pretty standard non-obfuscated classes.
Is there a way to programmatically create some sort of "mocking" assembly B that will contain all the methods located in assembly A but all these methods in assembly B should have a user-code injected in the start of the method and in the end, so that when assembly B us executed, it would run as normal + injected user code is executed. The injected code will be used for profiling purposes. Is it possible to accomplish somehow (I'm already using a ANTS profiler, so no need in any profiling tools, I'm just interested in whether it is possible to solve the problem the specified way)
Thank you!
Guys, I'm talking about writing a separate application (similar to http://codeinject.codeplex.com/) capable of taking any .net assembly as an input and producing the other one, that will contain:
Suppose we have the following code:
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);
}
}
It will allow do the following:
> inject.exe AssemblyA.dll Injector.dll AssemblyB.dll
Now when you reference AssemblyB.dll, and use in production environment, it would do everything the AssemblyA.dll does, but it would also perform some performance logging that can be later reviewed and analysed in more dev-like fashion.
Where should I start looking?
It depends on how much control you have over assembly A. If you build assembly A yourself, you can use aspect oriented programming (AOP) to inject the code you want to execute before and after each method. A popular tool to achieve this is PostSharp that injects the code into the IL. Have a look at OnMethodBoundaryAspect. There also is a free Express edition.
It is much more difficult for assemblies that are not under your control:
If the assembly is not strong named or if you have access to the signing key, you can disassemble it, e.g. with ILDASM with the /out parameter. You can then inject the new codes into the IL file and assemble the file again using ILASM - an endeavor that is of course not all too easy, but the only way I can think of that allows to profile all calls. Keep in mind that also legal issues might arise if you are not allowed to disassemble assembly A and respect them.
If you access all of A's methods through an interface or you only want to add the code to virtual members of the classes, you can use an Inversion of Control container to intercept the calls (see CodeCaster's answer). This is feasible with reasonable effort, but as the interceptions are done at runtime will degrade performance a bit.
Another approach is to use reflection and CodeDOM to analyze the types in assembly A and create code that wraps the calls to the methods. This way, you can also profile non-virtual, public members. Of course, internal calls in assembly A are not profiled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With