Example #1
0
        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);
        }
Example #2
0
        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());
        }
Example #3
0
		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;
		}
Example #4
0
        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());
        }
        private IDbFunctionHelper CreateDbFunctionHelper(Type type)
        {
            var typeBuilderHelper = assemblyBuilderHelper.DefineType(type.Name + "Helper", typeof(object),
                                                                     typeof(IDbFunctionHelper));

            CreateProperty(typeBuilderHelper);
            CreateUpdateFunction(type, typeBuilderHelper);
            CreateInsertFunction(type, typeBuilderHelper);
            CreateReadObjectFunction(type, typeBuilderHelper);
            var desType = typeBuilderHelper.Create();
            var result  = (IDbFunctionHelper)Activator.CreateInstance(desType);

            result.DbObjectContainer = dbObjectContainer;
            return(result);
        }
Example #6
0
        public Materializer <T> CreateMaterializer <T>()
        {
            var baseType       = typeof(Materializer <T>);
            var localType      = TypeCache.Get <T>();
            var emptyArgsArray = new Type[] {};

            var typeBuilderHelper = AssemblyBuilder.DefineType(localType.Type.Name + "Materializer", baseType);

            //constructor
            typeBuilderHelper.DefaultConstructor.Emitter.ldarg_0.call(baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, emptyArgsArray, null)).ret();

            //getobject impl
            var defineMethod = typeBuilderHelper.DefineMethod(baseType.GetMethod("GetObject"));

            var emitter   = defineMethod.Emitter;
            var returnVar = emitter.DeclareLocal(localType.Type);

            //create new T
            emitter
            .newobj(localType.Type.GetConstructor(emptyArgsArray))
            .stloc(returnVar);

            foreach (var propertyInfo in localType.Properties)
            {
                emitter =
                    emitter
                    .ldloc_0
                    .ldarg_0
                    .ldarg_1
                    .ldstr(propertyInfo.Name)
                    .ldloc_0
                    .callvirt(propertyInfo.GetGetMethod())
                    .call(baseType.GetMethod("GetValue").MakeGenericMethod(propertyInfo.PropertyType))
                    .callvirt(propertyInfo.GetSetMethod())
                    .nop;
            }

            emitter
            .ldloc_0
            .ret();

            var type = typeBuilderHelper.Create();

            AssemblyBuilder.Save();

            return((Materializer <T>)Activator.CreateInstance(type));
        }
Example #7
0
        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());
        }
Example #8
0
        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();
        }
Example #9
0
        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 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);
        }
Example #11
0
        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);
        }
Example #12
0
        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);
        }