/// <summary> /// Writes the header record from the given members. /// </summary> /// <param name="type">The type of the record.</param> public virtual void WriteHeader(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (!context.WriterConfiguration.HasHeaderRecord) { throw new WriterException(context, "Configuration.HasHeaderRecord is false. This will need to be enabled to write the header."); } if (context.HasHeaderBeenWritten) { throw new WriterException(context, "The header record has already been written. You can't write it more than once."); } if (context.HasRecordBeenWritten) { throw new WriterException(context, "Records have already been written. You can't write the header after writing records has started."); } if (type == typeof(object)) { return; } if (context.WriterConfiguration.Maps[type] == null) { context.WriterConfiguration.Maps.Add(context.WriterConfiguration.AutoMap(type)); } var members = new MemberMapCollection(); members.AddMembers(context.WriterConfiguration.Maps[type]); foreach (var member in members) { if (CanWrite(member)) { if (member.Data.IndexEnd >= member.Data.Index) { var count = member.Data.IndexEnd - member.Data.Index + 1; for (var i = 1; i <= count; i++) { WriteField(member.Data.Names.FirstOrDefault() + i); } } else { WriteField(member.Data.Names.FirstOrDefault()); } } } context.HasHeaderBeenWritten = true; }
/// <inheritdoc/> public virtual void WriteHeader(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (type == typeof(object)) { return; } if (context.Maps[type] == null) { context.Maps.Add(context.AutoMap(type)); } var members = new MemberMapCollection(); members.AddMembers(context.Maps[type]); var headerRecord = new List <string>(); foreach (var member in members) { if (CanWrite(member)) { if (member.Data.IndexEnd >= member.Data.Index) { var count = member.Data.IndexEnd - member.Data.Index + 1; for (var i = 1; i <= count; i++) { var header = member.Data.Names.FirstOrDefault() + i; WriteField(header); headerRecord.Add(header); } } else { var header = member.Data.Names.FirstOrDefault(); WriteField(header); headerRecord.Add(header); } } } HeaderRecord = headerRecord.ToArray(); hasHeaderBeenWritten = true; }
/// <summary> /// Creates a <see cref="Delegate"/> of type <see cref="Action{T}"/> /// that will write the given record using the current writer row. /// </summary> /// <typeparam name="T">The record type.</typeparam> /// <param name="record">The record.</param> protected override Action <T> CreateWriteDelegate <T>(T record) { var type = Writer.GetTypeForRecord(record); if (Writer.Context.WriterConfiguration.Maps[type] == null) { Writer.Context.WriterConfiguration.Maps.Add(Writer.Context.WriterConfiguration.AutoMap(type)); } var recordParameter = Expression.Parameter(typeof(T), "record"); var recordParameterConverted = Expression.Convert(recordParameter, type); // Get a list of all the members so they will // be sorted properly. var members = new MemberMapCollection(); members.AddMembers(Writer.Context.WriterConfiguration.Maps[type]); if (members.Count == 0) { throw new WriterException(Writer.Context, $"No properties are mapped for type '{type.FullName}'."); } var delegates = new List <Action <T> >(); foreach (var memberMap in members) { if (memberMap.Data.WritingConvertExpression != null) { // The user is providing the expression to do the conversion. Expression exp = Expression.Invoke(memberMap.Data.WritingConvertExpression, recordParameterConverted); exp = Expression.Call(Expression.Constant(Writer), nameof(Writer.WriteConvertedField), null, exp); delegates.Add(Expression.Lambda <Action <T> >(exp, recordParameter).Compile()); continue; } if (!Writer.CanWrite(memberMap)) { continue; } Expression fieldExpression; if (memberMap.Data.IsConstantSet) { if (memberMap.Data.Constant == null) { fieldExpression = Expression.Constant(string.Empty); } else { fieldExpression = Expression.Constant(memberMap.Data.Constant); var typeConverterExpression = Expression.Constant(Writer.Configuration.TypeConverterCache.GetConverter(memberMap.Data.Constant.GetType())); var method = typeof(ITypeConverter).GetMethod(nameof(ITypeConverter.ConvertToString)); fieldExpression = Expression.Convert(fieldExpression, typeof(object)); fieldExpression = Expression.Call(typeConverterExpression, method, fieldExpression, Expression.Constant(Writer), Expression.Constant(memberMap.Data)); } } else { if (memberMap.Data.TypeConverter == null) { // Skip if the type isn't convertible. continue; } fieldExpression = ExpressionManager.CreateGetMemberExpression(recordParameterConverted, Writer.Context.WriterConfiguration.Maps[type], memberMap); var typeConverterExpression = Expression.Constant(memberMap.Data.TypeConverter); memberMap.Data.TypeConverterOptions = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = Writer.Context.WriterConfiguration.CultureInfo }, Writer.Context.WriterConfiguration.TypeConverterOptionsCache.GetOptions(memberMap.Data.Member.MemberType()), memberMap.Data.TypeConverterOptions); var method = typeof(ITypeConverter).GetMethod(nameof(ITypeConverter.ConvertToString)); fieldExpression = Expression.Convert(fieldExpression, typeof(object)); fieldExpression = Expression.Call(typeConverterExpression, method, fieldExpression, Expression.Constant(Writer), Expression.Constant(memberMap.Data)); if (type.GetTypeInfo().IsClass) { var areEqualExpression = Expression.Equal(recordParameterConverted, Expression.Constant(null)); fieldExpression = Expression.Condition(areEqualExpression, Expression.Constant(string.Empty), fieldExpression); } } var writeFieldMethodCall = Expression.Call(Expression.Constant(Writer), nameof(Writer.WriteConvertedField), null, fieldExpression); delegates.Add(Expression.Lambda <Action <T> >(writeFieldMethodCall, recordParameter).Compile()); } var action = CombineDelegates(delegates); return(action); }