Many .NET tools, libraries, and frameworks implement some kind of metaprogramming in order to modify existing types or create new types based on existing ones. These tools use various techniques to create the resulting types, including so-called subclass proxies and IL rewriting.

This creates two different problems:

Incompatible Tools

Most of these tools use their own code generation facilities and do not account for the possibility of other tools extending the same classes. This can cause difficult or even unsolvable problems, ranging from two tools just not working together to various conflict areas (caching of generated code, incompatible changes, and ordering of modifications made to the code). Even when they do work together, separate generation of multiple subclass proxies might lead to bad runtime and memory performance.

Hard-wired Type-generation Mechanisms

Tool authors have to make a hard decision about code generation techniques, since they all have unique advantages and disadvantages:
  • Using Reflection.Emit, you can generate types at runtime and at compile-time using the same APIs.
    • Runtime generation provides more flexibility and much better build times, especially when many types can potentially be created, but only a few are actually built using a specific execution (very hand for test-driven development). This method does not require users to modify their build process.
    • On the other hand, a production release including pre-generated types will provide much better application startup performance (very important for client applications). Also, runtime generation is not available on platforms like MonoTouch.
  • Tools that use IL (re-)writing to create new assemblies or modify existing ones don't allow for runtime generation, but can do things that can't be implemented using subclass proxies, such as modifying non-virtual methods or controlling object instantiation.

Last edited Jun 12, 2012 at 8:57 AM by JulianLettner, version 8


No comments yet.