Get Drunk on the Power of Reflection.Emit

Get Drunk on the Power of Reflection.Emit

# is a small language. It doesn’t support writing regular expressions, for example, or accessing a relational database, or even using simple data-structures like stacks, queues, and lists. Of course C# programmers use these things every day through class libraries that ship with .NET. The point is that text processing, data objects, and collections are platform features, not language features.

There’s nothing too surprising about using class libraries to supplement programming language facilities. What is surprising is that the .NET framework allows you to simulate the features of a dynamically typed language using C#.

This article will take you through the process of dynamically generating new types, methods, and even code at runtime with .NET. For a geek like me, this is an interesting exercise even if the code never makes it to production. But programmatically manipulating type information is more useful and more common than you might think. The .NET framework uses Reflection.Emit in diverse areas, from regular expressions to remoting. So who knows?maybe you’ll find a use for it too.

First Things First
Occasionally, C#’s static typing can seem excessively rigid. Let’s say I have two classes with identical interfaces:

[Serializable]public class Gun {   public virtual void Shoot()   {      MessageBox.Show("Bang!");   }}[Serializable]public class Camera {   public virtual void Shoot()   {      MessageBox.Show("Click!");   }}

Since the two types are so similar, it might be nice to treat them interchangeably?maybe iterate through a collection of guns and cameras, shooting each of them. But, you can’t because they don’t share a common base class or a common interface.

With access to the source code, adding an interface implementation is easy. But it turns out you can add an interface implementation dynamically as well using the Reflection.Emit namespace. The real advantage to this approach is that you only have to write the code once, and you can dynamically add an interface implementation to any class that exposes the necessary members.

Author’s Note: What’s with all the shooting?
I chose the names for these simple classes as a precautionary example. In general, .NET developers don’t attach semantics to a method signature outside the context of a type. So identical methods on unrelated types that don’t implement a common interface or share a common base class ? like Gun.Shoot() and Camera.Shoot()? may not offer similar functionality at all. The point is: be careful.

Conceptually, building types dynamically is exactly the same as writing code by hand. With the Reflection.Emit namespace, you can do anything at runtime that you can do at compile time?but often in a way that’s not so user friendly. Accordingly, my approach throughout this article will be to examine a static implementation first before showing you how to build the dynamic equivalent.

When building a standard, statically typed .NET application, the first thing you do is create a project. Similarly, before defining any dynamic classes, you need a place to put them. This part is pretty simple: Create a dynamic assembly, and then add a dynamic module. All of which should sound familiar because it’s exactly the same thing that your IDE does for you when you’re programming everyday. The only difference is that we’re doing this at runtime.

Here’s the code to dynamically build an assembly and a module:

AssemblyName an = new AssemblyName();an.Name = "ExtendedTypes";assemblyBuilder =      AppDomain.CurrentDomain.DefineDynamicAssembly      (an, AssemblyBuilderAccess.RunAndSave);      moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");    AppDomain.CurrentDomain.AssemblyResolve+=new ResolveEventHandler(OnAssemblyResolve);

Strategy #1: Subclassing On the Fly
Now it’s time to start dynamically implementing interfaces. But first, let’s review the plan. Both the Gun class and the Camera class need to implement a common interface called IShootable:

public interface IShootable{   void Shoot();}

If you were coding by hand, inheriting from a common interface would be very simple:

public class ShootableCamera: IShootable{}

You might have done something like the above when working with third-party components. The dynamic equivalent isn’t too much harder:

public Type Subclass  (ModuleBuilder builder,   Type target,   Type interfaceToImplement,   string newTypeName){   TypeAttributes attributes =      TypeAttributes.Public |     TypeAttributes.Serializable;   TypeBuilder tb =           moduleBuilder.DefineType("newTypeName ",    attributes, target);      tb.AddInterfaceImplementation(toImplement);   Type subClass = tb.CreateType();   return subClass;}
Figure 1. Your Gun Is Now IShootable: Now that you’ve dynamically added the interface, you can use the Gun class, wherever you’d use IShootable.

That code should look pretty straightforward. Here’s the English-language translation: “Define a new type (subclassing an existing type) and add an interface implementation.” The only non-intuitive line is the one containing the CreateType()?this is the method that “bakes in” any members, interfaces, etc, of the previous steps, and gets your new type ready for use.

That’s it. You’ve just build a subtype dynamically. Let’s give it a test run:

Type shootableGunType =   Subclass(     builder,       typeof(gun),     typeof(IShootable),      "ShootableGun");object shootableGun =   Activator.CreateInstance(       shootableGunType,       true);(shootableGun as IShootable).Shoot();

In the simplest case, all you have to do is create the subtype, create an instance of the subtype, and cast it to the appropriate interface (see Figure 1).

Mass Producing Your Dynamic Types
The next step is to figure out how to instantiate your dynamic type. The simplest method (shown above) is to use reflection, using Activator.CreateInstance(). But, there are a couple of problems with the reflection-based approach. First, there’s no obvious way to instantiate an object with a non-default set of parameters. Also, you might be wary of the poor performance that’s often associated with reflection (but more on that later).

An alternative to the reflection-based approach is to use the Prototype pattern. The idea here is to create new objects by copying a prototypical instance. The good news about using the prototype pattern is that it doesn’t require any reflection at all. Here’s the implementation:

class HydratingCopier{   readonly BinaryFormatter b       = new BinaryFormatter();    MemoryStream stream       = new MemoryStream();   public HydratingCopier       (object toSerialize)   {       factoryType=          toSerialize.GetType();       b.Serialize         (stream, toSerialize);   }   public object New()   {       stream.Position=0;       return b.Deserialize(stream);   }}

The advantage of this pattern is that you only have to use Activator.CreateInstance a single time?to create your initial prototype. After that, you can create new instances by “hydrating” a serialized copy?that is, populating the properties of the serialized copy with values.

The bad news is that this particular prototype implementation uses serialization. This puts a constraint on the target class: It must be serializable.

Strategy #2: Building Dynamic Adapters
If dynamically subclassing an object seems way too easy, you’ve got good instincts. It turns out that subclassing a type to add an interface has at least three limitations:

  • Methods of the base class must be explicitly marked as virtual.
  • The base class has to be a class, and not a struct.
  • The target class can’t be sealed.

So what’s the alternative to subclassing? One option is to dynamically build an object adapter that wraps the target class, and implements the specified interface. My approach here was inspired by a really cool CodeProject article by R?diger Klaehn called Autocaster.

Before you get into building more dynamic classes, take a look at the non-dynamic object adapter. The ShootableCameraAdapter wraps a Camera object to make it compatible with the IShootable interface:

public class ShootableCameraAdapter: IShootable{   private Camera wrappedCamera;   public ShootableCameraAdapter (Camera camera)   {      this.wrappedCamera = camera;   }   public void Shoot()   {      wrappedCamera.Shoot();   }}

Listing 1 looks convoluted, but it’s not doing any rocket science. Really, it’s just building a new type that implements the specified interface, and looping through the interface methods, adding a call to the wrapped object for each one. The only downside to this approach is that it doesn’t pass the substitution test. That is, you can’t substitute an instance of the wrapper type for an instance of the base type because they don’t participate in an inheritance relationship.

Thinking about Performance
I know what you’re thinking: Building types dynamically is interesting, but it must be an absolute pig, performance-wise. You’re right. Sort of. Reflection has a reputation for poor performance that’s well-deserved in certain areas. But remember that dynamically creating a new type is a one-time cost. Once the type is built, it’s compiled into an assembly just like any other type in .NET.

The process of copying prototype objects, however, incurs an ongoing performance penalty. Table1 shows the three different methods of instantiating dynamic types and, just for comparison, I also timed the creation of the baseclass using the new operator. Not surprisingly, using the new operator is the fastest. But instantiating dynamic types using reflection wasn’t too far behind. The prototype pattern ended up way behind the reflection-based approach, as deserialization proved to be the bottleneck.

Table 1. Hydration is the pig. When creating new instances of dynamic types, serialization ends up being the biggest performance penalty.

Approach Objects created/second *
Reflection.Activator 708,160
Hydration (Subclass) 33,483
Hyrdration (Adapter) 18,928
New Operator 3,160,493

*My desktop has PentiumIV, and 1GB of RAM.

You should still consider these numbers with some perspective. In absolute terms, creating 18,000 objects per second isn’t too bad?even if it is two orders of magnitude slower than using the new operator. And there are ways to mitigate even these costs. Depending on the specifics of your application, you could build a factory class that copies prototypes on a low-priority worker thread, building up a cache of objects for when they’re needed.

Moderation in All Things
This is not idiomatic C#, not yet anyway. But the platform is still young, and the ability to dynamically create new types is one thing setting .NET apart from Java. After all, it took the C++ community years to discover the true power of templates. Maybe, over the next few years, we’ll all be taking advantage of the dynamic typing power of the .NET framework.

devx-admin

devx-admin

Share the Post:
USA Companies

Top Software Development Companies in USA

Navigating the tech landscape to find the right partner is crucial yet challenging. This article offers a comparative glimpse into the top software development companies

Software Development

Top Software Development Companies

Looking for the best in software development? Our list of Top Software Development Companies is your gateway to finding the right tech partner. Dive in

India Web Development

Top Web Development Companies in India

In the digital race, the right web development partner is your winning edge. Dive into our curated list of top web development companies in India,

USA Web Development

Top Web Development Companies in USA

Looking for the best web development companies in the USA? We’ve got you covered! Check out our top 10 picks to find the right partner

Clean Energy Adoption

Inside Michigan’s Clean Energy Revolution

Democratic state legislators in Michigan continue to discuss and debate clean energy legislation in the hopes of establishing a comprehensive clean energy strategy for the

Chips Act Revolution

European Chips Act: What is it?

In response to the intensifying worldwide technology competition, Europe has unveiled the long-awaited European Chips Act. This daring legislative proposal aims to fortify Europe’s semiconductor

USA Companies

Top Software Development Companies in USA

Navigating the tech landscape to find the right partner is crucial yet challenging. This article offers a comparative glimpse into the top software development companies in the USA. Through a

Software Development

Top Software Development Companies

Looking for the best in software development? Our list of Top Software Development Companies is your gateway to finding the right tech partner. Dive in and explore the leaders in

India Web Development

Top Web Development Companies in India

In the digital race, the right web development partner is your winning edge. Dive into our curated list of top web development companies in India, and kickstart your journey to

USA Web Development

Top Web Development Companies in USA

Looking for the best web development companies in the USA? We’ve got you covered! Check out our top 10 picks to find the right partner for your online project. Your

Clean Energy Adoption

Inside Michigan’s Clean Energy Revolution

Democratic state legislators in Michigan continue to discuss and debate clean energy legislation in the hopes of establishing a comprehensive clean energy strategy for the state. A Senate committee meeting

Chips Act Revolution

European Chips Act: What is it?

In response to the intensifying worldwide technology competition, Europe has unveiled the long-awaited European Chips Act. This daring legislative proposal aims to fortify Europe’s semiconductor supply chain and enhance its

Revolutionized Low-Code

You Should Use Low-Code Platforms for Apps

As the demand for rapid software development increases, low-code platforms have emerged as a popular choice among developers for their ability to build applications with minimal coding. These platforms not

Cybersecurity Strategy

Five Powerful Strategies to Bolster Your Cybersecurity

In today’s increasingly digital landscape, businesses of all sizes must prioritize cyber security measures to defend against potential dangers. Cyber security professionals suggest five simple technological strategies to help companies

Global Layoffs

Tech Layoffs Are Getting Worse Globally

Since the start of 2023, the global technology sector has experienced a significant rise in layoffs, with over 236,000 workers being let go by 1,019 tech firms, as per data

Huawei Electric Dazzle

Huawei Dazzles with Electric Vehicles and Wireless Earbuds

During a prominent unveiling event, Huawei, the Chinese telecommunications powerhouse, kept quiet about its enigmatic new 5G phone and alleged cutting-edge chip development. Instead, Huawei astounded the audience by presenting

Cybersecurity Banking Revolution

Digital Banking Needs Cybersecurity

The banking, financial, and insurance (BFSI) sectors are pioneers in digital transformation, using web applications and application programming interfaces (APIs) to provide seamless services to customers around the world. Rising

FinTech Leadership

Terry Clune’s Fintech Empire

Over the past 30 years, Terry Clune has built a remarkable business empire, with CluneTech at the helm. The CEO and Founder has successfully created eight fintech firms, attracting renowned

The Role Of AI Within A Web Design Agency?

In the digital age, the role of Artificial Intelligence (AI) in web design is rapidly evolving, transitioning from a futuristic concept to practical tools used in design, coding, content writing

Generative AI Revolution

Is Generative AI the Next Internet?

The increasing demand for Generative AI models has led to a surge in its adoption across diverse sectors, with healthcare, automotive, and financial services being among the top beneficiaries. These

Microsoft Laptop

The New Surface Laptop Studio 2 Is Nuts

The Surface Laptop Studio 2 is a dynamic and robust all-in-one laptop designed for creators and professionals alike. It features a 14.4″ touchscreen and a cutting-edge design that is over

5G Innovations

GPU-Accelerated 5G in Japan

NTT DOCOMO, a global telecommunications giant, is set to break new ground in the industry as it prepares to launch a GPU-accelerated 5G network in Japan. This innovative approach will

AI Ethics

AI Journalism: Balancing Integrity and Innovation

An op-ed, produced using Microsoft’s Bing Chat AI software, recently appeared in the St. Louis Post-Dispatch, discussing the potential concerns surrounding the employment of artificial intelligence (AI) in journalism. These

Savings Extravaganza

Big Deal Days Extravaganza

The highly awaited Big Deal Days event for October 2023 is nearly here, scheduled for the 10th and 11th. Similar to the previous year, this autumn sale has already created

Cisco Splunk Deal

Cisco Splunk Deal Sparks Tech Acquisition Frenzy

Cisco’s recent massive purchase of Splunk, an AI-powered cybersecurity firm, for $28 billion signals a potential boost in tech deals after a year of subdued mergers and acquisitions in the

Iran Drone Expansion

Iran’s Jet-Propelled Drone Reshapes Power Balance

Iran has recently unveiled a jet-propelled variant of its Shahed series drone, marking a significant advancement in the nation’s drone technology. The new drone is poised to reshape the regional

Solar Geoengineering

Did the Overshoot Commission Shoot Down Geoengineering?

The Overshoot Commission has recently released a comprehensive report that discusses the controversial topic of Solar Geoengineering, also known as Solar Radiation Modification (SRM). The Commission’s primary objective is to

Remote Learning

Revolutionizing Remote Learning for Success

School districts are preparing to reveal a substantial technological upgrade designed to significantly improve remote learning experiences for both educators and students amid the ongoing pandemic. This major investment, which

Revolutionary SABERS Transforming

SABERS Batteries Transforming Industries

Scientists John Connell and Yi Lin from NASA’s Solid-state Architecture Batteries for Enhanced Rechargeability and Safety (SABERS) project are working on experimental solid-state battery packs that could dramatically change the

Build a Website

How Much Does It Cost to Build a Website?

Are you wondering how much it costs to build a website? The approximated cost is based on several factors, including which add-ons and platforms you choose. For example, a self-hosted