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>))); }
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); }