[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