[IronPython] Need help to port dynamic class generation code to IP2

Sakesun Roykiattisak sakesun at boonthavorn.com
Sat Apr 19 13:38:56 CEST 2008


Hi,

   I've been using IP1 with System.Reflection to generate some class  
dynamically,
because my class need to be attached by some [Attribute]
here is my code to build a new class with System.Reflection.Emit

def make_service(cls, servicename, invoker=None, factoryname=None,  
factoryproperties=None):
     # // use System.Reflection.Emit to make a class
     # // C#
     # using IronPython.Runtime;
     # using IronPython.Runtime.Types;
     # [Service(Name=<<servicename>>, InvokerClass=<<invoker>>)]
     # [<<classfactory>>(**factoryproperties)]
     # class <<servicename>>: <<cls>>
     # {
     #     public static UserType pyType;
     #     public <<servicename>>(): base(pyType)
     #     {
     #         pyType.InvokeSpecialMethod(this, SymbolTable.Init, new  
object[0]);
     #     }
     # }
     global _module
     from IronPython.Runtime.Types import DynamicType, UserType
     dynamictype = clr.GetClrType(DynamicType)
     usertype = clr.GetClrType(UserType)
     base = clr.GetClrType(cls)
     t_attrs = type_attrs('Public', 'Class', 'AutoClass', 'AnsiClass',  
'BeforeFieldInit', 'AutoLayout')
     t = _module.DefineType(servicename, t_attrs, base)
     pyType = t.DefineField('pyType', clr.GetClrType(UserType),  
field_attrs('Public', 'Static'))
     base_ctor = base.GetConstructor(TypeArray([usertype]))
     from IronPython.Runtime import SymbolId, SymbolTable
     __init__ = clr.GetClrType(SymbolTable).GetField('Init')
     InvokeSpecialMethod = dynamictype.GetMethod('InvokeSpecialMethod',  
TypeArray([dotnet.Object, SymbolId, ObjectArray]))
     GetDynamicType = dynamictype.GetMethod('GetDynamicType')
     ctor = t.DefineConstructor(method_attrs('Public', 'HideBySig'),  
Reflection.CallingConventions.Standard, TypeArray([]))
     g = ctor.GetILGenerator()
     from System.Reflection.Emit.OpCodes import Ldarg_0, Ldsfld, Call,  
Ldc_I4_0, Newarr, Callvirt, Pop, Ret
     g.Emit(Ldarg_0)
     g.Emit(Ldsfld, pyType)
     g.Emit(Call, base_ctor)
     g.Emit(Ldsfld, pyType)
     g.Emit(Ldarg_0)
     g.Emit(Ldsfld, __init__)
     g.Emit(Ldc_I4_0)
     g.Emit(Newarr, clr.GetClrType(dotnet.Object))
     g.Emit(Callvirt, InvokeSpecialMethod)
     g.Emit(Pop)
     g.Emit(Ret)
     if invoker is None: invoker = get_invoker_from_clrtype(base.BaseType)
     t.SetCustomAttribute(ServiceAttributeBuilder(servicename, invoker))
     if factoryname:  
t.SetCustomAttribute(FactoryAttributeBuilder(factoryname,  
factoryproperties))
     service = clr.GetPythonType(t.CreateType())
     service.pyType = cls
     return service


Recently I try IP2 and found some class are missing

 from my understand
"IronPython.Runtime.Types.DynamicType" is now become  
"IronPython.Runtime.Types.PythonType"
"IronPython.Runtime.Types.UserType" is now become  
"IronPython.Runtime.Types.ExtensibleType"
"IronPython.Runtime.SymbolId" is now become  
"IronPython.Runtime.Types.PythonType"
"IronPython.Runtime.SymbolId" is now become "Microsoft.Scripting.SymbolId"
"IronPython.Runtime.SymbolTable" is now become  
"Microsoft.Scripting.SymbolTable"

Am I right ?

However simply swapping the class is not working.
Can anybody guide me what changed in class-mechanism from IP1 to IP2?

Or better, does IP2 now support attaching class attribute ?

thanks.



More information about the Ironpython-users mailing list