We are having several reports in fixed length record format. We are using FileHelpers for transforming them to delimited record format.
As there are serveral reports we thought of describing the fixed and delimited models and pass to
FileTransformEngine<TSource, TDestination>();
As to make it DRY can we do something like
Transform<TInput, TOutput>()
{
var engine = new FileTransformEngine<TInput, TOutput>();
engine.TransformFileFast(...);
}
I'm new to C# and generics and I'm not sure where to start.
Can anyone can give me some guidance, whether this is possible, as all models are already created they are available at compile time I think.
The documentation for filehelpers shows how to read a fixed file and write a delimited file - so it should be pretty easy to wrap calls to both in your own FileTransformEngine
public class FileTransformEngine<T>
{
public void TransformFileFast(string inputFile, string outputFile)
{
var readEngine = new FixedFileEngine<T>();
T[] records = readEngine.ReadFile(inputFile);
var writeEngine = new FileHelperEngine<T>();
writeEngine.WriteFile(outputFile,records);
}
}
For this to work, your class will need the attributes for both reading and writing. eg
[FixedLengthRecord()]
[DelimitedRecord("|")]
public class MyRecord
{
[FieldFixedLength(5)] // for reading
[FieldConverter(ConverterKind.Decimal, ".")] // for writing
public decimal Foo{get; set; }
}
Then you would use
var engine = new FileTransformEngine<MyRecord>();
engine.TransformFileFast("from/input.txt","to/output.csv");
If you want different types for input and output you could have the class take two types (an input and an output) along with a predicate for transforming one to the other.
public class FileTransformEngine<TInput, TOutput>
{
public void TransformFileFast(string inputFile, string outputFile,
Func<TInput,TOutput> transformer)
{
var readEngine = new FixedFileEngine<TInput>();
TInput[] records = readEngine.ReadFile(inputFile);
IEnumerable<TOutput> outputRecords = records.Select(transformer);
var writeEngine = new FileHelperEngine<TOutput>();
writeEngine.WriteFile(outputFile,outputRecords );
}
}
This would then be called with your two types
var engine = new FileTransformEngine<MyInputRecord, MyOutputRecord>();
engine.TransformFileFast("from/input.txt","to/output.csv", input => {
//transform input to output.
return new MyOutputRecord();
});