public void Test() { var typeBuilder = new AssemblyBuilderHelper("HelloWorld.dll").DefineType("Test", typeof(TestObject)); // Property // var propertyInfo = typeof(TestObject).GetProperty("Property"); var methodBuilder = typeBuilder.DefineMethod(propertyInfo.GetGetMethod()); var emit = methodBuilder.Emitter; emit .ldc_i4(10) .ret() ; // Method1 // var methodInfo = typeof(TestObject).GetMethod( "Method1", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); methodBuilder = typeBuilder.DefineMethod(methodInfo); emit = methodBuilder.Emitter; emit .ldc_i4(10) .ret() ; // Method2 // methodInfo = typeof(TestObject).GetMethod("Method2", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); methodBuilder = typeBuilder.DefineMethod( "Method2", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.PrivateScope | MethodAttributes.VtableLayoutMask, typeof(int), new Type[] { typeof(float) }); typeBuilder.TypeBuilder.DefineMethodOverride(methodBuilder, methodInfo); emit = methodBuilder.Emitter; emit .ldc_i4(10) .ret() ; // Create type. // var type = typeBuilder.Create(); var obj = (TestObject)Activator.CreateInstance(type); Assert.AreEqual(10, obj.Property); Assert.AreEqual(10, obj.Method3(0)); Assert.AreEqual(10, obj.Method2(0)); }
private static void SaveAssembly(AssemblyBuilderHelper assemblyBuilder, Type type) { if (_globalAssembly != null) { return; } if (_saveTypes) { try { assemblyBuilder.Save(); WriteDebug("The '{0}' type saved in '{1}'.", type.FullName, assemblyBuilder.Path); } catch (Exception ex) { WriteDebug("Can't save the '{0}' assembly for the '{1}' type: {2}.", assemblyBuilder.Path, type.FullName, ex.Message); } } }
private static AssemblyBuilderHelper GetAssemblyBuilder(Type type, string suffix) { var ab = GlobalAssemblyBuilder; if (ab == null) { #if SILVERLIGHT var assemblyDir = "."; #else var assemblyDir = AppDomain.CurrentDomain.BaseDirectory; // Dynamic modules are locationless, so ignore them. // _ModuleBuilder is the base type for both // ModuleBuilder and InternalModuleBuilder classes. // if (!(type.Module is ModuleBuilder) && type.Module.FullyQualifiedName != null && type.Module.FullyQualifiedName.IndexOf('<') < 0) { assemblyDir = Path.GetDirectoryName(type.Module.FullyQualifiedName); } #endif var fullName = type.FullName; if (type.IsGenericType) { fullName = AbstractClassBuilder.GetTypeFullName(type); } fullName = fullName.Replace('<', '_').Replace('>', '_'); ab = new AssemblyBuilderHelper(Path.Combine(assemblyDir, fullName + "." + suffix + ".dll")); } return(ab); }
public Type Build(AssemblyBuilderHelper assemblyBuilder) { if (assemblyBuilder == null) { throw new ArgumentNullException("assemblyBuilder"); } // Check InternalsVisibleToAttributes of the source type's assembly. // Even if the sourceType is public, it may have internal fields and props. // _friendlyAssembly = false; // Usually, there is no such attribute in the source assembly. // Therefore we do not cache the result. // var attributes = _originalType.Type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), true); foreach (InternalsVisibleToAttribute visibleToAttribute in attributes) { var an = new AssemblyName(visibleToAttribute.AssemblyName); if (AssemblyName.ReferenceMatchesDefinition(assemblyBuilder.AssemblyName, an)) { _friendlyAssembly = true; break; } } if (!_originalType.Type.IsVisible && !_friendlyAssembly) { return(typeof(ExprTypeAccessor <,>).MakeGenericType(_type, _originalType)); } var typeName = GetTypeName(); _typeBuilder = assemblyBuilder.DefineType(typeName, _accessorType); _typeBuilder.DefaultConstructor.Emitter .ldarg_0 .call(TypeHelper.GetDefaultConstructor(_accessorType)) ; BuildCreateInstanceMethods(); BuildTypeProperties(); BuildMembers(); BuildObjectFactory(); _typeBuilder.DefaultConstructor.Emitter .ret() ; var result = _typeBuilder.Create(); foreach (TypeBuilderHelper tb in _nestedTypes) { tb.Create(); } return(result); }
public void Test() { EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll") .DefineType("Hello", typeof(object), typeof(IHello)) .DefineMethod(typeof(IHello).GetMethod("SayHello")) .Emitter; /*[a]*/ emit /*[/a]*/ // string.Format("Hello, {0}!", toWhom) // ./*[a]*/ ldstr/*[/a]*/ ("Hello, {0}!") ./*[a]*/ ldarg_1 /*[/a]*/ ./*[a]*/ call/*[/a]*/ (typeof(string), "Format", typeof(string), typeof(object)) // Console.WriteLine("Hello, World!"); // ./*[a]*/ call/*[/a]*/ (typeof(Console), "WriteLine", typeof(string)) ./*[a]*/ ret/*[/a]*/ () ; Type type = emit.Method.Type.Create(); IHello hello = (IHello)TypeAccessor.CreateInstance(type); hello.SayHello("World"); }
private static AssemblyBuilderHelper GetAssemblyBuilder(Type type, string suffix) { AssemblyBuilderHelper ab = GlobalAssemblyBuilder; if (ab == null) { string assemblyDir = AppDomain.CurrentDomain.BaseDirectory; // Dynamic modules are locationless, so ignore them. // _ModuleBuilder is the base type for both // ModuleBuilder and InternalModuleBuilder classes. // if (!(type.Module is _ModuleBuilder)) { assemblyDir = Path.GetDirectoryName(type.Module.FullyQualifiedName); } string fullName = type.FullName; if (type.IsGenericType) { fullName = AbstractClassBuilder.GetTypeFullName(type); } ab = new AssemblyBuilderHelper(assemblyDir + "\\" + fullName + "." + suffix + ".dll"); } return(ab); }
public Type Build(AssemblyBuilderHelper assemblyBuilder) { if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); // Check InternalsVisibleToAttributes of the source type's assembly. // Even if the sourceType is public, it may have internal fields and props. // _friendlyAssembly = false; // Usually, there is no such attribute in the source assembly. // Therefore we do not cache the result. // var attributes = _originalType.Type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), true); foreach (InternalsVisibleToAttribute visibleToAttribute in attributes) { var an = new AssemblyName(visibleToAttribute.AssemblyName); if (AssemblyName.ReferenceMatchesDefinition(assemblyBuilder.AssemblyName, an)) { _friendlyAssembly = true; break; } } if (!_originalType.Type.IsVisible && !_friendlyAssembly || ( from p in _originalType.GetProperties(BindingFlags.Instance | BindingFlags.Public) from a in p.GetCustomAttributes(typeof(MapFieldAttribute), true).Cast<MapFieldAttribute>() where a.Storage != null select a ).Any()) return typeof (ExprTypeAccessor<,>).MakeGenericType(_type, _originalType); var typeName = GetTypeName(); _typeBuilder = assemblyBuilder.DefineType(typeName, _accessorType); _typeBuilder.DefaultConstructor.Emitter .ldarg_0 .call (TypeHelper.GetDefaultConstructor(_accessorType)) ; BuildCreateInstanceMethods(); BuildTypeProperties(); BuildMembers(); BuildObjectFactory(); _typeBuilder.DefaultConstructor.Emitter .ret() ; var result = _typeBuilder.Create(); foreach (TypeBuilderHelper tb in _nestedTypes) tb.Create(); return result; }
private static Type CreateResponseType(string typeName, Type returnType, AssemblyBuilderHelper assemblyBuilderHelper) { if (returnType == typeof(void)) { return(typeof(VoidResultResponse)); } var responseType = typeName + "Response"; var typeBuilderHelper = assemblyBuilderHelper.DefineType("Response." + responseType, typeof(Response)); var resultField = typeBuilderHelper.DefineField("result", returnType, FieldAttributes.Public); var constructorEmit = typeBuilderHelper.DefinePublicConstructor(returnType).Emitter; var defaulConstructor = typeof(Response).GetConstructor(Type.EmptyTypes); constructorEmit .ldarg_0 .call(defaulConstructor) .ldarg_0 .ldarg_1 .stfld(resultField) .ret(); constructorEmit = typeBuilderHelper.DefinePublicConstructor(Type.EmptyTypes).Emitter; constructorEmit .ldarg_0 .call(defaulConstructor) .ret(); var resultProperty = typeBuilderHelper.TypeBuilder.DefineProperty("Result", PropertyAttributes.None, returnType, new[] { returnType }); var getResultPropertyMethod = typeBuilderHelper.DefineMethod("get_Result", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, returnType, Type.EmptyTypes); var getResultPropertyMethodEmit = getResultPropertyMethod.Emitter; getResultPropertyMethodEmit .ldarg_0 .ldfld(resultField) .ret(); var setResultPropertyMethod = typeBuilderHelper.DefineMethod("set_Result", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, returnType); var setResultPropertyMethodEmit = setResultPropertyMethod.Emitter; setResultPropertyMethodEmit .ldarg_0 .ldarg_1 .stfld(resultField) .ret(); resultProperty.SetGetMethod(getResultPropertyMethod); resultProperty.SetSetMethod(setResultPropertyMethod); var getResultMethod = typeof(Response).GetMethod("GetResult"); var getResultMethodEmit = typeBuilderHelper.DefineMethod(getResultMethod).Emitter; getResultMethodEmit .ldarg_0 .ldfld(resultField) .boxIfValueType(returnType) .ret(); return(typeBuilderHelper.Create()); }
public static Type CreateSerializableType(Type originalType) { var originalAsmName = new AssemblyName(originalType.FullName + "Proxy"); var assemblyBuilderHelper = new AssemblyBuilderHelper(originalAsmName.Name + ".dll"); var returnType = CreateType(originalType, assemblyBuilderHelper); #if DEBUG assemblyBuilderHelper.Save(); #endif return(returnType); }
public Type Build(AssemblyBuilderHelper assemblyBuilder) { _context = new BuildContext(_sourceType); _builders = new AbstractTypeBuilderList(); _context.TypeBuilders = GetBuilderList(_context.Type); _context.AssemblyBuilder = assemblyBuilder; _builders.AddRange(_context.TypeBuilders); _builders.Add(_defaultTypeBuilder); return(Build()); }
public static void SaveGlobalAssembly() { if (_globalAssembly != null) { _globalAssembly.Save(); WriteDebug("The global assembly saved in '{0}'.", _globalAssembly.Path); _globalAssembly = null; _globalAssemblyPath = null; _globalAssemblyVersion = null; _globalAssemblyKeyFile = null; } }
static void SaveAssembly(AssemblyBuilderHelper assemblyBuilder, Type type) { if (!SaveTypes) { return; } try { assemblyBuilder.Save(); WriteDebug($"The '{type.FullName}' type saved in '{assemblyBuilder.Path}'."); } catch (Exception ex) { WriteDebug($"Can't save the '{assemblyBuilder.Path}' assembly for the '{type.FullName}' type: {ex.Message}."); } }
public static Assembly CreateSerializableAssembly(Assembly originalAssembly) { var originalAsmName = originalAssembly.GetName(); var assemblyBuilderHelper = new AssemblyBuilderHelper(originalAsmName.Name + "Proxy.dll"); var types = originalAssembly.GetTypes(); foreach (var type in types) { CreateType(type, assemblyBuilderHelper); } #if DEBUG assemblyBuilderHelper.Save(); #endif return(assemblyBuilderHelper); }
public Type Build(AssemblyBuilderHelper assemblyBuilder) { _typeBuilder = assemblyBuilder.DefineType(GetTypeName(), typeof(DuckType), _interfaceType); if (!BuildMembers(_interfaceType)) { return(null); } foreach (Type t in _interfaceType.GetInterfaces()) { if (!BuildMembers(t)) { return(null); } } return(_typeBuilder.Create()); }
public void RegisterService(object service, bool isOverride) { var originalAsmName = new AssemblyName("NTSock" + service.GetType().FullName); var assemblyBuilderHelper = new AssemblyBuilderHelper(originalAsmName.Name + ".dll"); servicesLock.EnterWriteLock(); try { var serviceType = service.GetType(); var methods = serviceType.GetMethods(); if (methods != null) { for (var i = 0; i < methods.Length; i++) { var method = methods[i]; if (method.GetCustomAttributes(typeof(ServiceMethodAttribute), false).Length == 0) { continue; } var executor = ExecutorFactory.CreateExecutor(service, method, i, assemblyBuilderHelper); if (methodMaps.ContainsKey(executor.ExecutorKey)) { if (!isOverride) { throw new ArgumentException("Cannot override an existing service."); } methodMaps.Remove(executor.ExecutorKey); } methodMaps.Add(executor.ExecutorKey, executor); } ExecutorFactory.CreateProxy(service, assemblyBuilderHelper); } #if DEBUG assemblyBuilderHelper.Save(); #endif } finally { servicesLock.ExitWriteLock(); } }
public void Register(Assembly assembly) { var types = assembly.GetTypes(); var asmBuilderHelper = new AssemblyBuilderHelper("Db" + assembly.GetName().Name + ".dll"); var dict = new Dictionary <ClassMetaData, bool>(); foreach (var type in types) { var result = ClassMetaDataManager.Instace.GetClassMetaData(type); if (result != null && !dict.ContainsKey(result)) { dict.Add(result, true); tableExecutor.CreateTable(result); } } tableExecutor.CreateRelation(dict.Keys); #if DEBUG asmBuilderHelper.Save(); #endif }
public static Type GetType(object hashKey, Type sourceType, ITypeBuilder typeBuilder) { if (hashKey == null) { throw new ArgumentNullException("hashKey"); } if (sourceType == null) { throw new ArgumentNullException("sourceType"); } if (typeBuilder == null) { throw new ArgumentNullException("typeBuilder"); } try { Hashtable builderTable = (Hashtable)_builtTypes[typeBuilder.GetType()]; Type type; if (builderTable != null) { type = (Type)builderTable[hashKey]; if (type != null) { return(type); } } lock (_builtTypes.SyncRoot) { builderTable = (Hashtable)_builtTypes[typeBuilder.GetType()]; if (builderTable != null) { type = (Type)builderTable[hashKey]; if (type != null) { return(type); } } else { _builtTypes.Add(typeBuilder.GetType(), builderTable = new Hashtable()); } AssemblyBuilderHelper assemblyBuilder = GetAssemblyBuilder(sourceType, typeBuilder.AssemblyNameSuffix); type = typeBuilder.Build(sourceType, assemblyBuilder); if (type != null) { builderTable.Add(hashKey, type); SaveAssembly(assemblyBuilder, type); } return(type); } } catch (TypeBuilderException) { throw; } catch (Exception ex) { throw new TypeBuilderException(string.Format( "Could not build the '{0}' type: {1}", sourceType.FullName, ex.Message), ex); } }
public static Type GetType(object hashKey, Type sourceType, ITypeBuilder typeBuilder) { if (hashKey == null) { throw new ArgumentNullException("hashKey"); } if (sourceType == null) { throw new ArgumentNullException("sourceType"); } if (typeBuilder == null) { throw new ArgumentNullException("typeBuilder"); } try { Hashtable builderTable = (Hashtable)_builtTypes[typeBuilder.GetType()]; Type type; if (builderTable != null) { type = (Type)builderTable[hashKey]; if (type != null) { return(type); } } lock (_builtTypes.SyncRoot) { builderTable = (Hashtable)_builtTypes[typeBuilder.GetType()]; if (builderTable != null) { type = (Type)builderTable[hashKey]; if (type != null) { return(type); } } else { _builtTypes.Add(typeBuilder.GetType(), builderTable = new Hashtable()); } if (_loadTypes) { Assembly originalAssembly = sourceType.Assembly; Assembly extensionAssembly; if (_assemblies.Contains(originalAssembly)) { extensionAssembly = (Assembly)_assemblies[originalAssembly]; } else { extensionAssembly = LoadExtensionAssembly(originalAssembly); _assemblies.Add(originalAssembly, extensionAssembly); } if (extensionAssembly != null) { type = extensionAssembly.GetType(typeBuilder.GetTypeName()); if (type != null) { builderTable.Add(hashKey, type); return(type); } } } AssemblyBuilderHelper assemblyBuilder = GetAssemblyBuilder(sourceType, typeBuilder.AssemblyNameSuffix); type = typeBuilder.Build(assemblyBuilder); if (type != null) { builderTable.Add(hashKey, type); SaveAssembly(assemblyBuilder, type); } return(type); } } catch (TypeBuilderException) { throw; } catch (Exception ex) { // Convert an Exception to TypeBuilderException. // throw new TypeBuilderException( string.Format(Resources.TypeFactory_BuildFailed, sourceType.FullName), ex); } }
private static Type CreateRequestType(string typeName, ParameterInfo[] infos, AssemblyBuilderHelper assemblyBuilderHelper) { var requestTypeName = typeName + "Request"; var typeBuilderHelper = assemblyBuilderHelper.DefineType("Request." + requestTypeName, typeof(Request)); var requestDescriptionField = typeof(Request).GetField("requestDescription"); var fieldInfos = new FieldInfo[infos.Length]; var propertyInfos = new PropertyBuilder[infos.Length]; var constructorEmit = typeBuilderHelper.DefinePublicConstructor(Type.EmptyTypes).Emitter; var defaultConstructor = typeof(Request).GetConstructor(Type.EmptyTypes); constructorEmit .ldarg_0 .call(defaultConstructor) .ldarg_0 .ldstr(typeName) .stfld(requestDescriptionField) .ret(); for (var i = 0; i < infos.Length; i++) { fieldInfos[i] = typeBuilderHelper.DefineField(infos[i].Name, infos[i].ParameterType, FieldAttributes.Public); var propertyName = char.IsLower(infos[i].Name[0]) ? char.ToUpper(infos[i].Name[0]) + infos[i].Name.Substring(1) : infos[i].Name + "_"; propertyInfos[i] = typeBuilderHelper.TypeBuilder.DefineProperty(propertyName, PropertyAttributes.None, infos[i].ParameterType, new[] { infos[i].ParameterType }); var getPropertyMethod = typeBuilderHelper.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, infos[i].ParameterType, Type.EmptyTypes); var getPropertyMethodEmit = getPropertyMethod.Emitter; getPropertyMethodEmit .ldarg_0 .ldfld(fieldInfos[i]) .ret(); var setPropertyMethod = typeBuilderHelper.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, infos[i].ParameterType); var setPropertyMethodEmit = setPropertyMethod.Emitter; setPropertyMethodEmit .ldarg_0 .ldarg_1 .stfld(fieldInfos[i]) .ret(); propertyInfos[i].SetGetMethod(getPropertyMethod); propertyInfos[i].SetSetMethod(setPropertyMethod); } return(typeBuilderHelper.Create()); }
public static void CreateProxy(object service, AssemblyBuilderHelper assemblyBuilderHelper) { if (service == null) { throw new ArgumentNullException("Cannot create null proxy"); } var serviceType = service.GetType(); var proxyTypeName = serviceType.Namespace + "." + serviceType.Name + "Proxy"; var proxyType = assemblyBuilderHelper.DefineType(proxyTypeName, typeof(IProxy)); var serviceContainerField = typeof(IProxy).GetField("container", BindingFlags.Instance | BindingFlags.NonPublic); var poolField = typeof(IProxy).GetField("pool", BindingFlags.Instance | BindingFlags.NonPublic); var defaultConstructor = typeof(IProxy).GetConstructor(Type.EmptyTypes); var construtorEmit = proxyType.DefinePublicConstructor(typeof(ServiceContainer), typeof(SocketPool)).Emitter; construtorEmit .ldarg_0 .call(defaultConstructor) .ldarg_0 .ldarg_1 .stfld(serviceContainerField) .ldarg_0 .ldarg_2 .stfld(poolField) .ret(); var methods = serviceType.GetMethods(BindingFlags.Instance | BindingFlags.Public); for (var i = 0; i < methods.Length; i++) { var method = methods[i]; if (method.GetCustomAttributes(typeof(ServiceMethodAttribute), false).Length == 0) { continue; } var returnType = method.ReturnType; var requestTypeName = "Request." + serviceType.Name + "_" + method.Name + i + "Request"; var requestType = assemblyBuilderHelper.AssemblyBuilder.GetType(requestTypeName); if (requestType == null) { throw new ApplicationException("Cannot find request type: " + requestTypeName); } var responseTypeName = "Response." + serviceType.Name + "_" + method.Name + i + "Response"; var responseType = returnType != typeof(void) ? assemblyBuilderHelper.AssemblyBuilder.GetType(responseTypeName) : typeof(VoidResultResponse); if (responseType == null) { throw new ApplicationException("Cannot find response type: " + responseTypeName); } var paramInfos = method.GetParameters(); var synParamTypes = new Type[paramInfos.Length]; var asyncParamTypes = new Type[paramInfos.Length + 2]; asyncParamTypes[0] = typeof(WaitCallback); //callback function asyncParamTypes[1] = typeof(object); //context param for (var j = 0; j < synParamTypes.Length; j++) { synParamTypes[j] = paramInfos[j].ParameterType; asyncParamTypes[j + 2] = paramInfos[j].ParameterType; } //Generate synchronous proxy method var synchronousMethodEmit = synParamTypes.Length == 0 ? proxyType.DefineMethod(method.Name, MethodAttributes.Public, returnType, Type.EmptyTypes).Emitter : proxyType.DefineMethod(method.Name, MethodAttributes.Public, returnType, synParamTypes).Emitter; var syncRequestLocal = synchronousMethodEmit.DeclareLocal(requestType); synchronousMethodEmit .newobj(requestType) .stloc(syncRequestLocal); synchronousMethodEmit = synchronousMethodEmit.ldarg_0; for (var j = 1; j <= paramInfos.Length; j++) { synchronousMethodEmit .ldloc(syncRequestLocal) .ldarg(j) .stfld(requestType.GetField(paramInfos[j - 1].Name)); } if (returnType == typeof(void)) { synchronousMethodEmit .ldloc(syncRequestLocal) .call(typeof(IProxy).GetMethod("DoRequest", BindingFlags.Instance | BindingFlags.NonPublic)) .ret(); } else { var doRequestMethod = typeof(IProxy).GetMethod("RequestSync", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod( returnType); synchronousMethodEmit .ldloc(syncRequestLocal) .call(doRequestMethod) .ret(); } //Generate asynchronous proxy method var asynchronousMethodEmit = proxyType.DefineMethod("Begin" + method.Name, MethodAttributes.Public, null, asyncParamTypes).Emitter; var asynRequestLocal = asynchronousMethodEmit.DeclareLocal(requestType); asynchronousMethodEmit .newobj(requestType) .stloc(asynRequestLocal); asynchronousMethodEmit = asynchronousMethodEmit.ldarg_0; for (var j = 1; j <= paramInfos.Length; j++) { asynchronousMethodEmit .ldloc(asynRequestLocal) .ldarg(j + 2) .stfld(requestType.GetField(paramInfos[j - 1].Name)); } asynchronousMethodEmit .ldloc(asynRequestLocal) .ldarg_1 .ldarg_2 .call(typeof(IProxy).GetMethod("BeginRequest", BindingFlags.Instance | BindingFlags.NonPublic)) .ret(); } proxyType.Create(); }
public static IExecutor CreateExecutor(object service, MethodInfo method, int methodIndex, AssemblyBuilderHelper assemblyBuilderHelper) { if (service == null) { throw new ArgumentNullException("Cannot create null executor"); } var type = service.GetType(); var typeName = type.Name + "_" + method.Name + methodIndex; var typeBuilderHelper = assemblyBuilderHelper.DefineType("Executor." + typeName, typeof(object), typeof(IExecutor)); var serviceFieldBuilder = typeBuilderHelper.DefineField(type.Name, type, FieldAttributes.Public); var emit = typeBuilderHelper.DefineMethod(typeof(IExecutor).GetMethod("Execute")).Emitter; var returnType = method.ReturnType; var paramInfos = method.GetParameters(); var requestType = CreateRequestType(typeName, paramInfos, assemblyBuilderHelper); var responseType = CreateResponseType(typeName, returnType, assemblyBuilderHelper); var getExecutorKeyEmit = typeBuilderHelper.DefineMethod(typeof(IExecutor).GetMethod("get_ExecutorKey")).Emitter; getExecutorKeyEmit .ldstr(typeName) .ret(); emit .ldarg_0 .ldfld(serviceFieldBuilder); for (var j = 0; j < paramInfos.Length; j++) { var paramInfo = paramInfos[j]; var fieldInfo = requestType.GetField(paramInfo.Name); emit = emit .ldarg_1 .ldfld(fieldInfo); } if (returnType != typeof(void)) { var resultLocal = emit.DeclareLocal(returnType); var responseLocal = emit.DeclareLocal(responseType); emit .call(method) .stloc(resultLocal) .newobj(responseType) .stloc(responseLocal) .ldloc(responseLocal) .ldloc(resultLocal) .stfld(responseType.GetField("result")) .ldloc(responseLocal) .ret(); } else { emit .call(method) .newobj(typeof(VoidResultResponse)) .ret(); } var executorType = typeBuilderHelper.Create(); var executor = (IExecutor)TypeAccessor.CreateInstance(executorType); var serviceField = executorType.GetField(type.Name); serviceField.SetValue(executor, service); return(executor); }
public DbFunctionHelperManager() { dbFunctionHelperMap = new Dictionary <Type, IDbFunctionHelper>(); dbMapLock = new ReaderWriterLockSlim(); assemblyBuilderHelper = new AssemblyBuilderHelper("DbFunctionBuilderHelper.dll"); }
public static Type CreateType(Type type, AssemblyBuilderHelper assemblyBuilderHelper) { var typeName = type.Name; var typeNamespace = type.Namespace + ".Serializable"; var typeBuilderHelper = assemblyBuilderHelper.DefineType(typeNamespace + "." + typeName, type, typeof(ISerializable)); typeBuilderHelper.SetCustomAttribute(typeof(SerializableAttribute)); var constructorEmit = typeBuilderHelper.DefaultConstructor.Emitter; var defaultConstructor = type.GetConstructor(Type.EmptyTypes); constructorEmit .ldarg_0 .call(defaultConstructor) .ret(); constructorEmit = typeBuilderHelper.DefinePublicConstructor(type, typeof(IDictionary <object, ISerializable>)).Emitter; constructorEmit .ldarg_0 .call(defaultConstructor) .ldarg_2 .ldarg_1 .ldarg_0 .call(typeof(IDictionary <object, ISerializable>).GetMethod("Add", new[] { typeof(object), typeof(ISerializable) })); //Serialize var propperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var serializerEmit = typeBuilderHelper.DefineMethod(typeof(ISerializable).GetMethod("Serialize", new Type[] { typeof(BinaryWriter), typeof(IDictionary <object, int>), typeof(int) })).Emitter; var deserializeEmit = typeBuilderHelper.DefineMethod(typeof(ISerializable).GetMethod("Deserialize", new Type[] { typeof(BinaryReader), typeof(IDictionary <int, object>) })).Emitter; //Write type name so we can construct it again serializerEmit .ldarg_1 .ldstr(type.FullName + ", " + type.Assembly) .call(typeof(BinaryWriter).GetMethod("Write", new[] { typeof(string) })) //Add current object to the object graph .ldarg_2 .ldarg_0 .ldarg_3 .call(typeof(IDictionary <object, int>).GetMethod("Add", new[] { typeof(object), typeof(int) })) .ldarg_3 .ldc_i4_1 .add .starg(3); //Serialize/Deserialize properties foreach (var property in propperties) { var propertyType = property.PropertyType; if (property.GetCustomAttributes(typeof(NonSerializeAttribute), true).Length > 0 || !property.CanWrite || !property.CanRead) { continue; } if (propertyType.IsPrimitive || propertyType == typeof(string) || propertyType == typeof(DateTime) || propertyType == typeof(decimal)) { constructorEmit .ldarg_0 .ldarg_1 .call(property.GetGetMethod()) .call(property.GetSetMethod()); primitiveSerializeEmitter.Emit(property, ref serializerEmit, ref deserializeEmit); } else if (propertyType.IsArray) { var elementType = propertyType.GetElementType(); if (elementType.IsPrimitive || elementType == typeof(string) || elementType == typeof(DateTime) || elementType == typeof(decimal) || elementType.IsSubclassOf(typeof(ISerializable))) { constructorEmit .ldarg_0 .ldarg_1 .call(property.GetGetMethod()) .call(property.GetSetMethod()); } else if (elementType.IsClass) { var originalArrayLocal = constructorEmit.DeclareLocal(propertyType); var originalArrayLocalNull = constructorEmit.DefineLabel(); var originalArrayLocalNotNull = constructorEmit.DefineLabel(); var arrayLocal = constructorEmit.DeclareLocal(propertyType); var ilocal = constructorEmit.DeclareLocal(typeof(int)); var lenLocal = constructorEmit.DeclareLocal(typeof(int)); var beginForLabel = constructorEmit.DefineLabel(); var beginForBodyLabel = constructorEmit.DefineLabel(); constructorEmit .ldarg_1 .call(property.GetGetMethod()) .stloc(originalArrayLocal) .ldloc(originalArrayLocal) .brtrue(originalArrayLocalNotNull) .ldarg_0 .ldnull .call(property.GetSetMethod()) .br(originalArrayLocalNull) .MarkLabel(originalArrayLocalNotNull) .ldloc(originalArrayLocal) .ldlen .conv_i4 .stloc(lenLocal) .ldloc(lenLocal) .newarr(elementType) .stloc(arrayLocal) .ldarg_0 .ldloc(arrayLocal) .call(property.GetSetMethod()) .ldc_i4_0 .stloc(ilocal) .br(beginForLabel) .MarkLabel(beginForBodyLabel) .ldloc(arrayLocal) .ldloc(ilocal) .ldloc(originalArrayLocal) .ldloc(ilocal) .ldelem_ref .ldarg_2 .call(typeof(Converter).GetMethod("Convert", new Type[] { typeof(object), typeof(IDictionary <object, ISerializable>) })) .castclass(elementType) .stelem_ref .ldloc(ilocal) .ldc_i4_1 .add .stloc(ilocal) .MarkLabel(beginForLabel) .ldloc(ilocal) .ldloc(lenLocal) .blt(beginForBodyLabel) .MarkLabel(originalArrayLocalNull); } else { throw new ArgumentException("Element of list not supported: " + elementType); } arraySerializeEmitter.Emit(property, ref serializerEmit, ref deserializeEmit); } else if (propertyType.IsGenericType && (propertyType.GetGenericTypeDefinition() == typeof(IDictionary <,>) || propertyType.GetGenericTypeDefinition() == typeof(Dictionary <,>))) { constructorEmit .ldarg_0 .ldarg_1 .call(property.GetGetMethod()) .call(property.GetSetMethod()); dictGenericEmitter.Emit(property, ref serializerEmit, ref deserializeEmit); } else if (propertyType.IsGenericType && (propertyType.GetGenericTypeDefinition() == typeof(IList <>) || propertyType.GetGenericTypeDefinition() == typeof(List <>))) { var elementType = propertyType.GetGenericArguments()[0]; if (elementType.IsPrimitive || elementType == typeof(string) || elementType == typeof(DateTime) || elementType == typeof(decimal) || elementType.IsSubclassOf(typeof(ISerializable))) { constructorEmit .ldarg_0 .ldarg_1 .call(property.GetGetMethod()) .call(property.GetSetMethod()); } else if (elementType.IsClass) { var originalListLocal = constructorEmit.DeclareLocal(propertyType); var originalListLocalNull = constructorEmit.DefineLabel(); var originalListLocalNotNull = constructorEmit.DefineLabel(); var listLocal = constructorEmit.DeclareLocal(propertyType); var ilocal = constructorEmit.DeclareLocal(typeof(int)); var lenLocal = constructorEmit.DeclareLocal(typeof(int)); var beginForLabel = constructorEmit.DefineLabel(); var beginForBodyLabel = constructorEmit.DefineLabel(); var getCountMethod = typeof(ICollection <>).MakeGenericType(elementType).GetMethod("get_Count"); var addElementMethod = typeof(ICollection <>).MakeGenericType(elementType).GetMethod("Add"); var propertyInstanceType = propertyType.IsInterface ? typeof(List <>).MakeGenericType(elementType) : propertyType; constructorEmit .ldarg_1 .call(property.GetGetMethod()) .stloc(originalListLocal) .ldloc(originalListLocal) .brtrue(originalListLocalNotNull) .ldarg_0 .ldnull .call(property.GetSetMethod()) .br(originalListLocalNull) .MarkLabel(originalListLocalNotNull) .ldloc(originalListLocal) .call(getCountMethod) .stloc(lenLocal) .ldloc(lenLocal) .newobj(propertyInstanceType, typeof(int)) .stloc(listLocal) .ldarg_0 .ldloc(listLocal) .call(property.GetSetMethod()) .ldc_i4_0 .stloc(ilocal) .br(beginForLabel) .MarkLabel(beginForBodyLabel) .ldloc(listLocal) .ldloc(originalListLocal) .ldloc(ilocal) .call(propertyType.GetMethod("get_Item")) .ldarg_2 .call(typeof(Converter).GetMethod("Convert", new Type[] { typeof(object), typeof(IDictionary <object, ISerializable>) })) .castclass(elementType) .call(addElementMethod) .ldloc(ilocal) .ldc_i4_1 .add .stloc(ilocal) .MarkLabel(beginForLabel) .ldloc(ilocal) .ldloc(lenLocal) .blt(beginForBodyLabel) .MarkLabel(originalListLocalNull); } else { throw new ArgumentException("Element of list not supported: " + elementType); } iListGenericEmitter.Emit(property, ref serializerEmit, ref deserializeEmit); } else if (propertyType.IsClass) { constructorEmit .ldarg_0 .ldarg_1 .call(property.GetGetMethod()) .ldarg_2 .call(typeof(Converter).GetMethod("Convert", new[] { typeof(object), typeof(IDictionary <object, ISerializable>) })) .castclass(propertyType) .call(property.GetSetMethod()); objectGenericEmitter.Emit(property, ref serializerEmit, ref deserializeEmit); } } serializerEmit.ret(); deserializeEmit.ret(); constructorEmit.ret(); var serializableType = typeBuilderHelper.Create(); SerializableTypeManager.Instance.Add(type, serializableType); return(serializableType); }
public Type Build(Type sourceType, AssemblyBuilderHelper assemblyBuilder) { if (sourceType == null) { throw new ArgumentNullException("sourceType"); } if (assemblyBuilder == null) { throw new ArgumentNullException("assemblyBuilder"); } // Check InternalsVisibleToAttributes of the source type's assembly. // Even if the sourceType is public, it may have internal fields and props. // _friendlyAssembly = false; // Usually, there is no such attribute in the source assembly. // Therefore we do not cache the result. // object[] attributes = sourceType.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), true); foreach (InternalsVisibleToAttribute visibleToAttribute in attributes) { AssemblyName an = new AssemblyName(visibleToAttribute.AssemblyName); if (AssemblyName.ReferenceMatchesDefinition(assemblyBuilder.AssemblyName, an)) { _friendlyAssembly = true; break; } } if (!sourceType.IsVisible && !_friendlyAssembly) { throw new TypeBuilderException(string.Format("Can not build type accessor for non-public type '{0}'.", sourceType.FullName)); } string typeName = GetTypeAccessorClassName(_type); _typeBuilder = assemblyBuilder.DefineType(typeName, _accessorType); _typeBuilder.DefaultConstructor.Emitter .ldarg_0 .call(TypeHelper.GetDefaultConstructor(_accessorType)) ; BuildCreateInstanceMethods(); BuildTypeProperties(); BuildMembers(); BuildObjectFactory(); _typeBuilder.DefaultConstructor.Emitter .ret() ; Type result = _typeBuilder.Create(); foreach (TypeBuilderHelper tb in _nestedTypes) { tb.Create(); } return(result); }
public static IExecutor CreateExecutor(object service, MethodInfo method) { if (service == null) { throw new ArgumentNullException("Cannot create a null executor"); } var type = service.GetType(); var typeName = type.Name + method.Name; var assemblyBuilderHelper = new AssemblyBuilderHelper(typeName + "_Executor" + ".dll"); var typeBuilderHelper = assemblyBuilderHelper.DefineType(typeName, typeof(object), typeof(IExecutor)); var serviceFieldBuilder = typeBuilderHelper.DefineField(type.Name, type, FieldAttributes.Public); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); var emit = typeBuilderHelper.DefineMethod(typeof(IExecutor).GetMethod("Execute")).Emitter; var returnType = method.ReturnType; var paramInfos = method.GetParameters(); emit .ldarg_0 .ldfld(serviceFieldBuilder); for (var j = 0; j < paramInfos.Length; j++) { var paramInfo = paramInfos[j]; var paramType = paramInfo.ParameterType; emit = emit .ldarg_1 .ldc_i4(j) .ldelem_ref; if (paramType.IsValueType) { emit .unbox_any(paramType); } else if (paramType.IsClass || paramType.IsInterface) { emit.castclass(paramType); } } emit.call(method); if (returnType != typeof(void)) { emit .boxIfValueType(returnType) .ret(); } else { emit .ldnull .ret(); } var executorType = typeBuilderHelper.Create(); var executor = (IExecutor)TypeAccessor.CreateInstance(executorType); var serviceField = executorType.GetField(type.Name); serviceField.SetValue(executor, service); #if DEBUG assemblyBuilderHelper.Save(); #endif return(executor); }