Sunday, April 01, 2007

Solution: QuickFix to Enums

To convert a QuickFix type that has const int's or const char's that represent values into a enum, you can do this:



        static public Type EnumOrdType = new ConstCharsToEnumCreator<OrdType, char>().Convert();


        static public Type EnumProduct = new ConstCharsToEnumCreator<Product, int>().Convert();




Now, if we want to fill a combo box with the values of these objects,


            this.cmbOrdType.Items.AddRange(Enum.GetNames(OrderBO.EnumOrdType));


            this.cmbProduct.Items.AddRange(Enum.GetNames(OrderBO.EnumProduct));




The definition of the helper class is:



    public class ConstCharsToEnumCreator<TQuickFixType, TEnumBaseType>


    {


        static private AssemblyBuilder m_assemblyBuilder;


        static private ModuleBuilder m_moduleBuilder;


        private EnumBuilder m_enumBuilder;


        private Type m_createdEnum;


 


        private Type m_typeThatHasConstChars;


 


        public ConstCharsToEnumCreator()


        {


            this.m_typeThatHasConstChars = typeof(TQuickFixType);


 


            if (m_moduleBuilder == null)


            {


                CreateCallee(Thread.GetDomain());


            }


        }


 


        public Type Convert()


        {


            CreateEnumBuilder();


 


            FieldInfo[] fields = this.m_typeThatHasConstChars.GetFields();


            foreach (FieldInfo field in fields)


            {


                if (field.IsStatic && field.IsLiteral && field.IsPublic && field.FieldType == typeof(TEnumBaseType))


                    m_enumBuilder.DefineLiteral(field.Name, field.GetRawConstantValue());


            }


 


            m_createdEnum = m_enumBuilder.CreateType();


            return m_createdEnum;


        }


 


        private void CreateCallee(AppDomain myAppDomain)


        {


            // Create a name for the assembly.


            AssemblyName myAssemblyName = new AssemblyName();


            myAssemblyName.Name = "EmittedAssembly";


 


            // Create the dynamic assembly.


            m_assemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Save);


 


            // Create a dynamic module.


            m_moduleBuilder = m_assemblyBuilder.DefineDynamicModule("EmittedModule", "EmittedModule.mod");


        }


 


        private void CreateEnumBuilder()


        {


            // Create a dynamic Enum.


            string enumTypeName = string.Format("{0}.{1}Enum", this.GetType().Namespace, this.m_typeThatHasConstChars.Name);


            m_enumBuilder = m_moduleBuilder.DefineEnum(enumTypeName, TypeAttributes.Public, typeof(TEnumBaseType));


        }


    }





©2007 Marc Adler - All Rights Reserved

No comments: