Beispiel #1
0
        public Func <TEntity> GetFactory <TEntity>()
        {
            Type entityType      = typeof(TEntity);
            var  constructorInfo = MemberAccessorBuilder.GetConstructor <TEntity>(Type.EmptyTypes);

            if (constructorInfo == null)
            {
                throw new FlatFileException(Resources.NoDefaultConstructor);
            }
            var typeName      = GetUniqueTypeName($"{entityType.Name}Factory");
            var typeBuilder   = moduleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed);
            var methodBuilder = typeBuilder.DefineMethod("Create", MethodAttributes.Public | MethodAttributes.Static, entityType, Type.EmptyTypes);
            var generator     = methodBuilder.GetILGenerator();

            generator.Emit(OpCodes.Newobj, constructorInfo);
            generator.Emit(OpCodes.Ret);
            var typeInfo   = typeBuilder.CreateTypeInfo();
            var createInfo = typeInfo.GetMethod(methodBuilder.Name);

            return((Func <TEntity>)createInfo.CreateDelegate(typeof(Func <TEntity>)));
        }
Beispiel #2
0
        private static void EmitCustomWrite <TEntity>(
            ILGenerator generator,
            FieldInfo fieldInfo,
            LocalBuilder contextBuilder,
            LocalBuilder mappingBuilder,
            int mappingIndex)
        {
            // Gets the mapping being processed
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, fieldInfo);
            generator.Emit(OpCodes.Ldc_I4, mappingIndex);
            generator.Emit(OpCodes.Ldelem_Ref);
            generator.Emit(OpCodes.Stloc, mappingBuilder);

            // Create the ColumnContext
            var contextCtorInfo = MemberAccessorBuilder.GetConstructor <ColumnContext>(Type.EmptyTypes);

            generator.Emit(OpCodes.Newobj, contextCtorInfo);

            // Set ColumnContext.RecordContext
            generator.Emit(OpCodes.Dup);
            generator.Emit(OpCodes.Ldarg_1);
            var recordContextSetInfo = MemberAccessorBuilder.GetProperty <ColumnContext, IRecordContext>(x => x.RecordContext);
            var recordContextSetter  = recordContextSetInfo.GetSetMethod();

            generator.Emit(OpCodes.Callvirt, recordContextSetter);

            // Set ColumnContext.PhysicalIndex
            generator.Emit(OpCodes.Dup);
            generator.Emit(OpCodes.Ldloc, mappingBuilder);
            var physicalIndexGetInfo = MemberAccessorBuilder.GetProperty <IMemberMapping, int>(x => x.PhysicalIndex);
            var physicalIndexGetter  = physicalIndexGetInfo.GetGetMethod();
            var physicalIndexSetInfo = MemberAccessorBuilder.GetProperty <ColumnContext, int>(x => x.PhysicalIndex);
            var physicalIndexSetter  = physicalIndexSetInfo.GetSetMethod();

            generator.Emit(OpCodes.Callvirt, physicalIndexGetter);
            generator.Emit(OpCodes.Callvirt, physicalIndexSetter);

            // Set ColumnContext.LogicalIndex
            generator.Emit(OpCodes.Dup);
            generator.Emit(OpCodes.Ldloc, mappingBuilder);
            var logicalIndexGetInfo = MemberAccessorBuilder.GetProperty <IMemberMapping, int>(x => x.LogicalIndex);
            var logicalIndexGetter  = logicalIndexGetInfo.GetGetMethod();
            var logicalIndexSetInfo = MemberAccessorBuilder.GetProperty <ColumnContext, int>(x => x.LogicalIndex);
            var logicalIndexSetter  = logicalIndexSetInfo.GetSetMethod();

            generator.Emit(OpCodes.Callvirt, logicalIndexGetter);
            generator.Emit(OpCodes.Callvirt, logicalIndexSetter);

            generator.Emit(OpCodes.Stloc, contextBuilder);

            // Get the writer
            generator.Emit(OpCodes.Ldloc, mappingBuilder);
            var writerInfo   = MemberAccessorBuilder.GetProperty <IMemberMapping, Action <IColumnContext, object, object[]> >(x => x.Writer);
            var writerGetter = writerInfo.GetGetMethod();

            generator.Emit(OpCodes.Callvirt, writerGetter);

            // Load the parameters
            generator.Emit(OpCodes.Ldloc, contextBuilder);
            generator.Emit(OpCodes.Ldarg_2);
            generator.Emit(OpCodes.Ldarg_3);

            // Invoke the writer
            var invokeInfo = MemberAccessorBuilder.GetMethod <Action <IColumnContext, object, object> >(x => x.Invoke(null, null, null));

            generator.Emit(OpCodes.Callvirt, invokeInfo);
        }