VictorTzeng / ProxyEmitter

Generate C# proxy class at run-time with ILGenerator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Emit C# Proxy Class at Runtime with ILGenerator

Problem Description

In C#, we often run into objects or services that provide dynmaic method invocation by a single method like:

public abstract class ProxyBase
{
  protected abstract object Invoke(object someMethodRelatedInfo, object[] arguments);
}

It is good practice to create a proxy class that wraps all remote methods and call the Invoke method internally to provide strong typed interface.

Say we have a remote service. The first thing to do is declare its methods with interface:

public interface IFooService
{
  void MethodWithNoReturn();
  int MethodTakeParameterAndReturn(int a, int b);
}

Then we implement invocation method:

public class FooProxyBase : ProxyBase 
{
  protected override object Invoke(object someMethodRelatedInfo, object[] arguments)
  {
    // Pack to JSON and send via http
    // Or adapte and call other classes
    // Or whatever
  }
}

Finally we create a proxy class for IFooService:

public class FooService : FooProxyBase, IFooService
{
  #region Implement IFooService
  public void MethodWithNoReturn() 
  {
    Invoke("MethodWithNoReturn", new object[0]);
  }
  
  public int MethodTakeParameterAndReturn(int a, int b)
  {
    return Invoke("MethodTakeParameterAndReturn", new object[] { a, b });
  }
  #endregion
}

As you can see, the implementation of proxy class is quite trival but will take many work if methods are too many.

The point of interest here is to automatically generate FooService class at runtime. This goal can be achieved by various methods. This project in particular uses C#'s ILGenerator to emit IL code at runtime.

Instead manually writing FooService, all you need is one line of code:

IFooService proxy = ProxyEmitter.CreateProxy<FooProxyBase, IFooService>(/*Constructor parameters are supported*/);

How To Use

  1. Include project in your solution, or add reference to compiled ProxyEmitter.dll.
  2. Make an base class that derives from ProxyBase and implement all abstract methods (just slightly differenct from above). You can create whatever constructors you want. ProxyEmitter will make sure the generated class have the same ones.
  3. Declare an service interface for the service. You can provide additional namespace information by tagging it with ProxyNamespace attribute.
  4. Call ProxyEmitter.CreateProxy<YourProxyBase, YourServiceInterface(/*constructor arguments*/) to get an instance of the generated proxy class.
  5. That's all. Just do your stuff with the service.

About

Generate C# proxy class at run-time with ILGenerator


Languages

Language:C# 100.0%