what do you use code generation for? what are the typical scenarios that allow to get real value out of on-the-fly run-time c# code generation? Specifically: what do you use CodeDOM namespace for?
We have a rules engine that has the rules modelled in XML, but deployed as compiled objects for performance reasons. Code generation allows us to take the XML and convert it into standard .NET components. You've gotta love the CodeDOM.
I test an application whose UI is described in XAML. I generate screen interface classes from the XAML for the UI test automation.
On-the-fly codegen? You mean at runtime? I use this for creating high performance access to code that would other wise use reflection. Much of the time you can use things like Delegate.CreateDelegate
, but there are times when ILGenerator
etc have their place.
I use this in protobuf-net to access fields at runtime (by building a wrapper; note that properties use Delegate.CreateDelegate
), and in HyperDescriptor to create a faster PropertyDescriptor
implementation. But in both cases I use ILGenerator
directly - not CodeDom.
In fact, personally I really wouldn't bother to learn CodeDom unless I had to; for runtime work, I would look at Expression
first. I have an article on InfoQ discussing this, or various things here on SO or on my blog that might be interesting.
If you mean regular codegen - i.e. at compile-time (or before), then this is used by any scenario that does modelling separately to implementation. LINQ-to-SQL (SqlMetal), EF, etc would be classic examples, but many other modellers have codegen. For protobuf-net, I use xslt for the codegen (from .proto); I didn't want to use T4 as I wanted to support 2.0 / mono etc, and xslt allows the end-user to customise the codegen with notepad (if they so choose).
Duck typing by creating adaptors at runtime is IMHO a great example of when using code dom is necessary.
I don't do it directly, but I do use the Moq library to generate mocks and stubs on the fly for unit tests. I believe that uses Castle.DynamicProxy behind the scenes, which in turn calls Reflection.Emit.
A fancy word for code generation is "partial evaluation". That is, if you've got a program P(X,Y) that takes two inputs X and Y, where X changes very seldom, and Y changes often, then you can write a code generator that takes X as input and creates a new ad-hoc program PX(Y), which does exactly what P would do when its first argument is a specific value of X. It runs fast because it's not having to process X, because X is "built in" to it. The generation of PX is simple, because it's not having to process Y.
Example: Once I took over a project to build a "bridge" from an old hierarchical database to a new relational one. The inputs were X (the database schema description) and Y (the old database). X changes very seldom, but Y changes often. P(X,Y) had been designed. The design document was about 2 inches thick and was projected to take 2 people 18mos to complete, and performance was a major concern.
Since one of the inputs, X, changes very seldom, this looked like a job for code generation. A C program was written to read X and print out a new C program PX(Y). Then PX was regenerated about once a week, compiled and linked, and used all week for production. It ran at high speed because it did not have to deal with X, only Y. The finished code generator (in C) was only 0.5 inch thick and was completed by 2 people in 3 months.
By the way, this is what compilers do. They take a textual description of a program, X, and translate it into a runnable program PX, which then processes input Y,