|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionIf you had the chance to work with LINQ, the latest Object Relational Mapping tool (ORM) added to the .NET 3.5 platform, then you understand how LINQ maps your database structure into several classes in your application. It creates for each table an entity class that has its properties mapped to the columns of the table in context. The whole point of ORM tools is to bring the database structure up to the language’s level so that your code would be aware of the structure at compile time. Nowadays developers tend to divide their application’s architecture into several distinct layers, usually 3 layers:
I am not going to go into the details of the benefits of dividing your design into multi layers, nor discuss the pros and cons of LINQ itself, there are a lot of article on the Internet on this subject. When you use LINQ in your physical layer to access the database, LINQ creates entity objects. A quick example will explain this. If you have a table called To keep the spirit of multi-tier architecture, developers usually create a set of parallel classes that map the entity classes, by doing this, we add a layer of abstraction necessary to keep things clean between the dependencies between layers. This way, the presentation layer would only depend on the business layer and no longer on any layer below that. Usually there are two approaches to these intermediate classes, also known as data transfer objects, dtos. Somewhere along your code, you will need to transfer the data between the entity objects and between your data transfer objects. So how do we do this? Some choose to code this part manually which is good, performance wise, but big trouble when it comes to maintaining these classes, not to mention all the amount of wasted human energy in donkey work. Some choose to benefit from the powerful features of reflection and write some code to copy the objects at runtime based on their properties, this is usually the preferred approach. The properties of the objects are discovered at runtime using Reflection, and copied to each other. This method has the big advantage that you do not need to write code for each pair of classes to copy properties from the entity classes to the data transfer objects, this saves you a lot of maintenance and a lot of time. Unfortunately this method suffers from low performance as reflection is slow, and you will not know how low the performance is until you really test it. The Solution, A Better ApproachWhat if you can take the advantages of these two methods and none of their disadvantages? What if you choose to go with the first approach, where you write code for each and every pair of classes to copy their properties but instead of writing them yourself, you would have a developer working for you at runtime and writing this code for you very quickly and best of all, he works for free. This programmer is Mr. Emit. Mr. Emit or his full name is Using the CodeUsing this code is very simple, just add it to your solution or add a reference to its DLL. And whenever you have two objects to copy, just pass them to the Performance BenefitsBefore I wrote this code, I had code that used reflection. Using reflection, copying 10,000 objects (with around 15 properties for the object’s class) took around 32 seconds on a 1.8 Mhz Core 2 Duo Centrino CPU with 2 GB of RAM Laptop (non debug), in debug mode it took 1 minute, 19 seconds. Doing the same operation using the new Emit code took 19 milliseconds in non debug and 22 milliseconds in debug mode. Yes that is correct, milliseconds. The numbers speak for themselves. A Look Under the HoodExplaining how to write IL (Intermediate Language) code is beyond the scope of this article, however I will try to give you a head start if you are interested in understanding what the code does and how it does it. The code creates classes at runtime that implement the interface Conclusion
History
|
||||||||||||||||||||||