Click here to Skip to main content
11,639,861 members (59,549 online)
Click here to Skip to main content

Tagged as

Creating classes at runtime

, 15 Jun 2009 CPOL 11.3K 11
Rate this:
Please Sign up or sign in to vote.
Creating classes at runtime

I've been working on an application that has a number of forms that need to be laid out based on configuration data in the database. This enables the application to meet the requirements of many different customers. Laying out the forms based on the configuration data is relatively trivial - it is just a matter of writing the code that normally ends up in the .designer file. However, because there could be any number of controls on the form, binding an object to them is a little more tricky. I approached this problem by creating a class that describes a control that will added to the form together with a boolean, integer and string value field that is used to initialise the control and capture the users input based on the type of control. I had a list of these objects representing all of the controls that needed to be rendered on the form, to bind the controls to these objects, I needed an adapter which I created at runtime.

Effectively, the adapter was pretty straight forward. It required a constructor which would take a list of the control classes described above. Then it would have a series of properties which would get and set values in the list, for example:

public Adapter
{
    private IList<POWPageControl> _controls;

    public Adapter(IList<POWPageControl> controls)
    {
        _controls = controls;
    }

    public Property1
    {
        get { return _controls[0].StringValue; }
        set { _controls[0].StringValue = value; }
    }

    public Property2
    {
        get { return _controls[1].BoolValue; }
        set { _controls[1].BoolValue = value; }
    }
}

In order to prevent a memory leak, I added the following code to the views constructor - it checks that I haven't already created the assembly that will contain the dynamic code, before I create it:

private const string ADAPTER_ASSEMBLY_NM = "DynamicPOWAdapterAssembly";
private const string ADAPTER_MODULE_NM = "DynamicPOWAdapterModule";

private AssemblyBuilder _adapterAssemBuild;

public POWEditView()
{
    AppDomain adapterDomain = AppDomain.CurrentDomain;

    AssemblyName adapterAssemNm = new AssemblyName(ADAPTER_ASSEMBLY_NM);

    foreach (Assembly assembly in adapterDomain.GetAssemblies())
    {
        AssemblyName assemNm = assembly.GetName();

        // This isn't perfect, but should be good enough 
        // to determine if we have already created
        // the dynamic assembly (this is to prevent a memory leak)
        if (assemNm.FullName.StartsWith(adapterAssemNm.FullName) 
        	&& assembly is AssemblyBuilder)
        {
            _adapterAssemBuild = assembly as AssemblyBuilder;
            break;
        }
    }

    if (_adapterAssemBuild == null)
    _adapterAssemBuild = adapterDomain.DefineDynamicAssembly
    	(adapterAssemNm, AssemblyBuilderAccess.Run);

    InitializeComponent();
}

Once you have an assembly for the dynamic class, there are then a series of other steps to go through - create a module, create the type, add the properties to the type and then create the get and set methods for the properties:

/// <span class="code-SummaryComment"><summary>
</span>

The one thing that proved invaluable when creating this code was ildasm.exe. For example, I kept on getting a ProgramException when I ran my code and couldn't see what was wrong with my code. Knocking together the example adapter above and running it through ildasm soon showed me that the problem was because I was usingLdind_I4 instead of Ldc_I4.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

S1mm0t
United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150731.1 | Last Updated 15 Jun 2009
Article Copyright 2009 by S1mm0t
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid