Reputation: 317
I am serializing a number of different POCO objects which all inherit from a common abstract class - say AbstractBaseClass
, for example. When serializing this class, I use the WriteRecords<dynamic>
method, which accepts pretty much anything and ostensibly uses reflection to write the properties to the CSV.
The issue I have, is that I would like the base class fields to come first in the file. It appears CsvHelper's default behavior is to put them last.
I can see there is a way to instantiate a mapper to index the fields, but it's somewhat prohibitively difficult to do this for each of the many types that inherit from AbstractBaseClass
. I would like to configure this only once, and have it work for anything that inherits from said class. Even better, would be some kind of toggle that can allow me to change the way CsvHelper searches for fields across the inheritance tree.
Upvotes: 1
Views: 1076
Reputation: 9094
You could use a generic method to create your ClassMap
and set the indexes on the properties of the base class to be negative so that they would come before the properties of the inherited class.
public class Program
{
public static void Main(string[] args)
{
var records = new List<Foo> {
new Foo{Id = 1, FirstName = "FirstName1", FooProperty = "Foo1", LastName = "LastName1"},
new Foo{Id = 2, FirstName = "FirstName2", FooProperty = "Foo2", LastName = "LastName2"}
};
var config = GetFooBaseConfiguration(records);
using (var csv = new CsvWriter(Console.Out, config))
{
csv.WriteRecords(records);
}
Console.ReadKey();
}
public static CsvConfiguration GetFooBaseConfiguration<T>(IEnumerable<T> records) where T : FooBase
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
var classMap = new DefaultClassMap<T>();
classMap.AutoMap(CultureInfo.InvariantCulture);
classMap.Map(m => m.FirstName).Index(-1,-2);
classMap.Map(m => m.LastName).Index(-2,-3);
config.RegisterClassMap(classMap);
return config;
}
}
public abstract class FooBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Foo : FooBase
{
public int Id { get; set; }
public string FooProperty { get; set; }
}
Upvotes: 1