Reputation: 8749
In all the books I've read on reflection they often say that there aren't many cases where you want to generate IL on the fly, but they don't give any examples of where it does make sense.
After seeing Reflection.Emit as a job requirement for a gaming company I was curious where else it's being used.
I'm now wondering if there are any situations you've seen in the real world were it was the best solution to the problem. Perhaps it is used as an implementation to a design pattern?
Note I imagine PostSharp / AOP uses it.
Upvotes: 45
Views: 23903
Reputation: 3134
I'm actually developing my own language and I'm building its compiler using .NET Framework's Reflection.Emit
.
Someone could think that building a compiler using C# is not good, but things are actually working fine and compile-time performances are good enough. Also, this is obviously not related at all to the runtime performances, which will depend upon CLR, not my compiler (except for minimal optimization like operator precedence).
I'll publish it on GitHub as soon as I'll have completed it.
Upvotes: 0
Reputation: 39946
Generate declarative code, such as using interface to declare underlying HTTP REST service. https://github.com/neurospeech/retro-core-fit
Performance booster, most of the time I use Expression.Compile
to create a fragment of code to retrieve information quickly by compiling giving expression to compiled delegate which can be executed in future. If you use PropertyInfo.GetValue
, it is very slow, but if you create an expression to access property and compile it to a delegate (which internally uses Reflection.Emit), it is huge savings on CPU time.
Upvotes: 2
Reputation: 13037
Generating enums from external data:
In that example the data comes from a lookup database and the enum is created at compile-time by reading out of the database. This maintains type-safety without having to manually maintain duplicate sources of information.
Upvotes: 0
Reputation: 780
For instance Entity Framework uses Reflection.Emit
to build proxy classes at run-time which inherit from your model classes to provide lazy loading and change tracking.
Upvotes: 0
Reputation: 1275
I like to explore more for AI-Inspired for self-learning. It allows us to create a class or module at run-time
Upvotes: -1
Reputation: 5
Reflection.Emit namespace is used to develop LinqPad.It helps to create typed Datacontexts dynamically. Check out this link http://www.linqpad.net/HowLINQPadWorks.aspx.
Upvotes: 0
Reputation: 171864
I've used it in an application where a property had to be accessed repeatedly via reflection (because the property name was not known at compile time).
By creating a helper class at runtime that generates code to access the property, the resulting code was an order of magnitude faster than the original reflection-only code.
Upvotes: 3
Reputation: 1063619
Expression.Compile
essentially does this - that is key to some of LINQ.
I am currently using reflection emit to re-write a serialization API - because sometimes reflection just isn't good enough. As it happens this will also allow it to generate dlls (much like how sgen works), allowing fully static code (I'm hopeful this will make it iPhone friendly).
I also use a similar approach in HyperDescriptor to provide very fast name-based property-lookup.
I've also used emit to do things like:
all related to SO questions.
Finally, this IL approach is the core of protobuf-net "v2"; the reason here is that it allows me both to have a fast model at runtime (compiling it via IL on the fly), and to write the same directly to a static-compiled dll, so that it works on things like iPhone, Phone 7, etc (which lack the necessary meta-programming APIs).
Upvotes: 16
Reputation: 3815
I have recently used it to create a proof of concept for compiling a set of operations that's very expensive to do at runtime, and achieved a 200% improvement in speed. The operations were to use RegEx to parse a large string, and loop over the matches, use Reflection to find and instantiate types, and a bunch of other things that aren't exactly fast. By using IL emit, I created dynamic functions that matched a delegate type (using DynamicMethod) and cached them. I did the normal RegEx/Reflection dance once per input value to figure out what it should do, then used StringBuilder to concatenate the strings as literals, and instead of Reflection/Activator I now could use the actual types themselves in the emitted IL. Here's a helpful tip: don't try to write IL yourself unless you're a sado-masochist. Write a sample function or type in C# that does what you want, compile it, and use Reflector or ILDASM to see the generated IL. Then use Emit to do similar logic. Another tip is you can create locals and store them to variables, then use Emit(OpCodes.Ldloc, myLocalVar) and it'll get the local address for you, instead of having to keep track of the local index (i.e. ldloc_1).
Upvotes: 2
Reputation: 629
I remember seeing Relection.Emit
used in chapter 8: "On-the-Fly Code Generation for Image Processing" of Beautiful Code. Basicly the author specializes a function for doing a certain set of image processing operations on a given image, which in turn leads to greatly reduced execution time.
Upvotes: 3
Reputation: 66753
Dynamically generating a mock object which implements some interface. Example frameworks which do this: moq, rhino mocks.
Upvotes: 13
Reputation: 5955
Mocking libraries also use Reflection.Emit to generate proxies used in Unit Testing.
Upvotes: 2
Reputation: 59685
Castle DynamicProxy uses it for, you guess, dynamic proxies. DynamicProxy is then used by the Castle's IoC container Windsor and OR mapper ActiveRecord.
Upvotes: 7
Reputation: 755219
The DLR and DLR related languages heavily rely on Reflection.Emit
Upvotes: 6
Reputation: 5955
The XMLSerializer actually generates code and compiles it on first run. You can read this great blog post on Scott Hanselman's site regarding how to debug XML Serialization if you know this is happening.
Upvotes: 2
Reputation: 39862
I'm using it as a way to create dynamic proxies on the fly to wrap a class. NHibernate uses this same pattern to proxy calls to POCO objects to instead query a database.
Any time you want to be able to "write code" (i.e. create a new function, etc.) dynamically, you'll need Emit
.
Upvotes: 8