Reshef’s tip of the day

.net development tips

Archive for the ‘code generation’ Category

DynamicMethod full example

Tuesday, December 18th, 2007

My last post described how to generate a dynamic method for object instantiation that its type is not known at compilation time.

I felt that the code snippets in that post were too technical and it was hard to understand how and when to use it in the real world. Therefore I created a small sample application that shows how and when it can be used.

The application is a small rule engine that gets a rule definitions file about a user’s credit, parses the rules, generates C# code and compiles the code on runtime. The rule engine is then instantiated by using a dynamic method.

The file UserCreditRules.rules contains the definitions of the rules and the dynamic method is generated in the file RulesFactory.cs by the method GenerateFactoryMethod(…).

The sample application is here.

Reflection and performance: DynamicMethod

Monday, December 17th, 2007

Reflection has a performance price, however, there are times that it just can’t be avoided, like when creating a new instance of a type generated and compiled at runtime. Since the type does not exist when compiling the code, it can’t be referenced and therefore can’t be instantiated by:

BaseType instance = new GeneratedType();

where BaseType is the a type that GeneratedType inherits from.

So how to instantiate?

After generating the assembly, we have a reference to that assembly. The most naive and simple way is to call:

BaseType instance = (BaseType)generatedAssembly.
    CreateInstance("GeneratedType");

But unfortunately this is also the worst way performance-wise, since on runtime first it looks for the name of the generated type through all the types in the assembly, then it looks for the appropriate constructor and then it instantiates the object. It can be optimized by caching the ConstructorInfo of the  type and then calling it, which highly optimizes the instantiation time. There are other ways to achieve this goal but I am not going to go into it. For a thorough article and analysis take a look here (the source code is here).

In order to get the best performance, we can use the DynamicMethod class which generates IL code at runtime and creates a method out of it. This is done like this:

Type generatedType = CompilerSimulator.Compile().
    GetType("generated type name");

DynamicMethod dm =
    new DynamicMethod("GeneratedCtor", generatedType,
        Type.EmptyTypes, typeof(ContainingType).Module, true);

ILGenerator ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Nop);
ilgen.Emit(OpCodes.Newobj,
    generatedType.GetConstructor(Type.EmptyTypes));
ilgen.Emit(OpCodes.Ret);

GeneratedTypeFactoryMethod factoryMethod =
    (GeneratedTypeFactoryMethod)dm.CreateDelegate(
    typeof(GeneratedTypeFactoryMethod));

The GeneratedTypeFactoryMethod is a delegate:

delegate BaseType GeneratedTypeFactoryMethod();

Now, our code can return the generated method as delegate that will be called to to create a new instance of the generated type. By tests that I did I got results similar to direct instantiation (after setting up the factory delegate - but this happens only once).

Since writing IL code is not much fun, you can use a project named RunSharp that wraps IL emitting with a high-level interface.

Tip of the day: DictionaryAdapter

Sunday, November 25th, 2007

The is a part of the Castle project but can be used as a standalone assembly.

The dictionary adapter lets you wrap a dictionary with an interface definition and access that dictionary through the interface. This gives the advantage of typed data access on top of a dictionary and don’t forget the intellisense in the IDE.

The example I will use shows the use of a dictionary adapter in order to enable access to configuration data.  It contains a class:

/// 
/// This class uses configuration.
/// Instead of accessing the configuration directly,
/// it receives it in the constructor.
/// 
public class DataBaseAccess
{
    private IDataBaseAccessConfig m_config;

    /// The configuration that
    /// this class uses to access the database.
    /// 
    public DataBaseAccess(IDataBaseAccessConfig config)
    {
        m_config = config;
    }

    public void ConnectToDataBase()
    {
        Console.WriteLine("Server Ip: {0}", m_config.ServerIp);
        Console.WriteLine("DataBase: {0}", m_config.DataBaseName);
        Console.WriteLine("User: {0}", m_config.UserName);
        Console.WriteLine("Password: {0}", m_config.Password);
        Console.ReadLine();
    }
}

As you can see, this class expects a config object that implements the the IDataBaseAccessConfig interface. This interface is defined as:

/// 
/// Defines the data for data base access.
/// 
public interface IDataBaseAccessConfig
{
    string ServerIp { get;}
    string DataBaseName { get;}
    string UserName { get;}
    string Password { get;}
}

In the example, the database access data is defined in the appSettings section of the application configuration file. In order to pass it to the DataBaseAccess class, it is being wrapped like this:

// In real world example the factory should be cached.
// Create the adapter on top of the configuration dictionary.
IDataBaseAccessConfig configAdapter =
    new DictionaryAdapterFactory().
        GetAdapter(configData);

where the configAdapter is passed.

Now what happened here? The DictionaryAdapterFactory emit code in runtime that implements a wrapper class that implemets the IDataBaseAccessConfig interface and this class, when a property is being read, gets the value for the dictionary that is wrapped, in this case, the configData dictionary.

What is it good for?

1) In my opinion, it is nicer to access an interface rather than passing a configuration dictionary to the class which involves querying the data by using string literals.

2) When passing the data through the constructor instead of accessing the ConfigurationManager directly in the code we make our code better by preventing access to singletons, therefore making the code testable and agnostic to the real implementation, may it be the application configuration file, configuration defined in the database or any other implementation.

3) Intellisense…

The example solution is here

Jajah is the VoIP player that brought you web-activated telephony.