I noticed that FileHelpers Dynamic is not implemented under NET 6.
I have writte a ClassBuilder, that works very well with the existing Delimited/Fixed engive:
The code is here, feel free to use it.
It uses reflection to build the class from a simple list of fields info.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using FileHelpers;
namespace KBFileHelpersDynamic {
public class Field {
public string FieldName;
public Type FieldType;
public int FieldFixedLength;
public QuoteMode QM = QuoteMode.AlwaysQuoted;
public bool Quoted;
}
public static class FileHelpersTypeBuilder {
enum FileType { Delimited, Fixed };
public static Type BuildClassDelimited(List<Field> _fields, string _delim = ";", string _cult = "") {
return BuildClass(FileType.Delimited, _fields, _delim, _cult);
}
public static Type BuildClassFixed(List<Field> _fields, string _cult = "") {
return BuildClass(FileType.Fixed, _fields, _cult);
}
private static Type BuildClass(FileType _filetype, List<Field> _fields, string _delim = ";", string _cult = "") {
TypeBuilder tb = GetTypeBuilder();
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
if(_cult == "")
_cult = System.Globalization.CultureInfo.CurrentCulture.ToString();
// Ignore empty lines
Type[] attrCtorParams = new Type[0];
var attrCtorInfo = typeof(IgnoreEmptyLinesAttribute).GetConstructor(attrCtorParams);
CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[0]);
tb.SetCustomAttribute(attrBuilder);
if(_filetype == FileType.Delimited) {
// Set Type Delimited and delimiter char
attrCtorParams = new Type[] { typeof(string), typeof(string) };
attrCtorInfo = typeof(DelimitedRecordAttribute).GetConstructor(attrCtorParams);
attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { _delim, _cult });
tb.SetCustomAttribute(attrBuilder);
}
else {
// Set Type Fixed record length
attrCtorParams = new Type[] { typeof(FixedMode), typeof(string) };
attrCtorInfo = typeof(FixedLengthRecordAttribute).GetConstructor(attrCtorParams);
attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { FixedMode.ExactLength, _cult });
tb.SetCustomAttribute(attrBuilder);
}
// NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type)
foreach(var field in _fields)
CreateProperty(_filetype, tb, field);
return tb.CreateType();
}
private static TypeBuilder GetTypeBuilder() {
var typeSignature = "MyDynamicType";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
null);
return tb;
}
private static void CreateProperty(FileType _ftype, TypeBuilder tb, Field _field) {
string propertyName = _field.FieldName;
Type propertyType = _field.FieldType;
FieldBuilder fieldBuilder = tb.DefineField(propertyName, propertyType, FieldAttributes.Public);
if(_ftype == FileType.Fixed) {
Type[] attrCtorParams = new Type[] { typeof(int) };
var attrCtorInfo = typeof(FieldFixedLengthAttribute).GetConstructor(attrCtorParams);
var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { _field.FieldFixedLength });
fieldBuilder.SetCustomAttribute(attrBuilder);
}
if(_ftype == FileType.Delimited) {
Type[] attrCtorParams = new Type[0];
var attrCtorInfo = typeof(FieldOptionalAttribute).GetConstructor(attrCtorParams);
var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[0]);
fieldBuilder.SetCustomAttribute(attrBuilder);
}
if(_ftype == FileType.Delimited && _field.Quoted) { // Only if quoted at all
Type[] attrCtorParams = new Type[] { typeof(char), typeof(QuoteMode), typeof(MultilineMode) };
var attrCtorInfo = typeof(FieldQuotedAttribute).GetConstructor(attrCtorParams);
var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { '"', _field.QM, MultilineMode.AllowForBoth });
fieldBuilder.SetCustomAttribute(attrBuilder);
}
}
}
I noticed that FileHelpers Dynamic is not implemented under NET 6. I have writte a ClassBuilder, that works very well with the existing Delimited/Fixed engive: The code is here, feel free to use it. It uses reflection to build the class from a simple list of fields info.
using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using FileHelpers;
namespace KBFileHelpersDynamic { public class Field { public string FieldName; public Type FieldType; public int FieldFixedLength; public QuoteMode QM = QuoteMode.AlwaysQuoted; public bool Quoted; }
}