Modifying a type at runtime (cross post)

  • Thread starter Thread starter Richard Dutton
  • Start date Start date
R

Richard Dutton

I would like to be able to modify a type at runtime so that I can add an IL
prologue and epilogue to its methods (either to implement some kind of
aspect-oriented programming framework, or a simple profiling tool). I know
that a simlpe way to achieve the same behaviour, at least for a type's
virtual methods, is to derive a new type and add my code before and after
calls to the inner object's methods, but for my own edification I'd like to
try to actually inject the code into the existing type.

TypeBuilder, MethodRental and their cohorts in Reflection.Emit look like
they are capable of performing such injection, but only on types in a
dynamic assembly so my questions are these:
Is it at all possible to use Reflection.Emit.*Builder on types in an
assembly that has been loaded from disc (and acquired using
Assembly.GetExecutingAssembly, for example).
If not, is it possible somehow to copy an Assembly into an AssemblyBuilder
(or Module into ModuleBuilder and so on) in order to modify that.
Is there another dynamic way to perform the injection (i.e. not using
il(d)asm).

Many thanks,

Richard Dutton
 
Richard,

There is an article on the September 2003 issue of MSDN Magazine that could
be what you're looking for.

From the article summary: "In this article, the author shows how to
dynamically rewrite Microsoft Intermediate Language code on the fly using
the Profiling API of the CLR. Unlike approaches based on Reflection.Emit,
this scheme works with the existing assemblies and doesn't require the
creation of proxy or dynamic assemblies. The needs for IL code rewriting
emerges when you want to make your changes transparent to the client and
preserve the identity of classes. This technique can be used for creation of
interceptors, pre- and post-processing method calls, and code
instrumentation and verification."

Rewrite MSIL Code on the Fly with the .NET Framework Profiling API
http://msdn.microsoft.com/msdnmag/issues/03/09/NETProfilingAPI/default.aspx

Regards,

Gabriele
 
Richard said:
I would like to be able to modify a type at runtime so that I can add an IL
prologue and epilogue to its methods (either to implement some kind of
aspect-oriented programming framework, or a simple profiling tool). I know
that a simlpe way to achieve the same behaviour, at least for a type's
virtual methods, is to derive a new type and add my code before and after
calls to the inner object's methods, but for my own edification I'd like to
try to actually inject the code into the existing type.

TypeBuilder, MethodRental and their cohorts in Reflection.Emit look like
they are capable of performing such injection, but only on types in a
dynamic assembly so my questions are these:
Is it at all possible to use Reflection.Emit.*Builder on types in an
assembly that has been loaded from disc (and acquired using
Assembly.GetExecutingAssembly, for example).

No, it is not, unless you perform the loading yourself. I.e. you could
write an assembly loader that parses the module files and builds
corresponding in-memory modules using Reflection.Emit. That way, you
could do the code injection as a part of the loading process.
If not, is it possible somehow to copy an Assembly into an AssemblyBuilder
(or Module into ModuleBuilder and so on) in order to modify that.

No easy way I know of, apart from analyzing the module using Reflection
and building a copy of it using Reflection.Emit (which would be a lot of
work; also, you wouldn't change the existing module, but create a new one).
Is there another dynamic way to perform the injection (i.e. not using
il(d)asm).

As Gabriele G. Ponti suggests, you can use the Profiling API to do
code-rewriting at load-time. However, this is also not that easy, there
is a lot of work involved, and you have to do it all from unmanaged C++.

Fabian
 
Thanks a lot guys.


Fabian Schmied said:
No, it is not, unless you perform the loading yourself. I.e. you could
write an assembly loader that parses the module files and builds
corresponding in-memory modules using Reflection.Emit. That way, you
could do the code injection as a part of the loading process.


No easy way I know of, apart from analyzing the module using Reflection
and building a copy of it using Reflection.Emit (which would be a lot of
work; also, you wouldn't change the existing module, but create a new one).

As Gabriele G. Ponti suggests, you can use the Profiling API to do
code-rewriting at load-time. However, this is also not that easy, there
is a lot of work involved, and you have to do it all from unmanaged C++.

Fabian
 
Back
Top