How could I write to a file a dynamic object using FileHelpers? - c#

I'm actually pursuing a way to create csv file which records could vary on type and order. They are defined by the user on both ways and I'm actually handling their types safely.
I loved using FileHelpers library in order to read/write files on C# since it's fast, reliable and trustable, so I was wondering how could I perform this export operation using it, and reviewing questions like this one the evil part comes when needing to populate the class with the desired values, so I could write the file. All the related questions are focusing on reading registries and I need to write them.
Am I right thinking that I might need to use Reflection so I could roam this new type and its properties or is there any way to "add a record" specifying the value while creating the fields?
This FileHelpers way was an option and of course the second one was doing this manually, but I was curious if there is an easier way.
var builder = new DelimitedClassBuilder("DynamicDocument", ";");
builder.AddField("Date", typeof(DateTime));
var dynamicType = builder.CreateRecordClass();
//...

Using the class builders is the best way to do this with FileHelpers. You do need to keep a copy of the type that is created so it can be used by your generic classes.
Just remember, that you must do all the work before calling CreateRecordClass() as that then generates the type.
Here is a link to another S/O question with a whole bunch of code that shows how to do it: FileHelpers.Dynamic.ClassBuilder.CreateRecordClass Error
Now, if you are working purely with properly formatted files, you can let FileHelpers do all that work for you as long as they are always properly delimited and you handle any type conversion based on the column name.

Related

Using Omu.ValueInjecter to map peroperties of different types

We are currently in the process of upgrading one of the parts of our system. We are wanting to run both parts of the system at the same time so we can test that its working correctly.
To Achieve this we are using Omu.ValueInjecter.Map method to convert the old type to the new one. Many of the objects are the same they are just in a different namespace. and Mapper.Map is having difficulty dealing with this. I read on the git page that you can use Mapper.Default map to change the default behaviour of same name, same type using the following code.
Mapper.DefaultMap = (src, resType, tag) =>
{
var res = Activator.CreateInstance(resType);
res.InjectFrom(src);
return res;
};
But this isn't working and I can't find any more information on it to find out how to fix it.
As a temporary fix we have used a json converter to serialize and deserialize the object but it is messy and slow and we want to use Mapper.Map to tidy it up.
the docs in there may not be perfect;
Mapper.Defaultmap is used when you call Mapper.Map for types that don't have a mapping created using Mapper.AddMap
so for similar types (just different namespace) you don't need to do anything, and types that are different you need to call Mapper.AddMap

Multi Mapping Enum at runtime

Due to the question here is marked as duplicated, so here I repeat the question and make more explanation about the question. Hope someone can give some suggestions.
=======================================
As described in the question, here is a enum:
public enum MyEnum { One, Two, Three}
is going to be parsed based on mutl strings.For example, below strings are all going to be parsed as MyEnum.Two:
"Two", "TWO", "Second", "2"
The reason that I can't leverage the description attributes or a mapping dictionary directly is that the mapping strings come from an external xml file. The mapping will change after a period of time and so that It's not possible just adding the description attribute with the above declared enum.
For example, the mappings above was build one month ago and now there are some extra items required as below and these new items will be just add to the xml file:
"2nd", "The Second one"
Furthermore, I use a self developed script engine to parse above and other similar needs (that's why I don't use a simple mapping function) :
Object x = engine.Execute( /*some script codes defined in external xml*/ );
if (ReturnType.IsEnum && Enum.IsDefined(ReturnType, x)) //ReturnType is defined in external xml file
return Enum.Parse(ReturnType, x.ToString());
else if (ReturnType.IsEnum)
{
// Hope I can handle Extra mapping here
}
else
return Convert.ChangeType(x, ReturnType);
It seems very strange to just pass-in a mapping table to the above codes because it was designed for generic script executing purpose. So I think #xanatos (in the prevous 'duplicated' question) gave a way to resolve this issue, but the mapping (via customized attributes) should be generated at runtime. Attributes seems a meta data and can't be changed after compilation, however, I found some posts say that I can use TypeDescriptor to add attributes at runtime, is it possible? and How?
The fact that the data comes from an external file whose contents change, makes this an ETL/integration problem. In such cases you have to put a cleanup/normalization step before actually parsing the data.
In such cases, the typical solution is to create lookup tables that map inputs to recognized outputs and replace the input with the lookup values before parsing. In fact, ETL tools like SQL Server's Integration Services include Lookup transformations for exactly this purpose.
Once you replace your incoming data with the lookup data, you can parse it using
Enum.TryParse (String, Boolean) or
Enum.TryParse(String, Boolean, TEnum). Both methods allow you to parse the input in a case-insensitive manner and parse both values or names.

Building a string representation of an object using a "mask" or user supplied Format String

I'm not really sure what tags should be on this sort of question so feel free to give me some suggestions if you think some others are more suited.
I have a dynamic object with an unknown number or properties on it, it's from a sort of dynamic self describing data model that lets the user build the data model at runtime. However because all of the fields holding relevant information to the user are in dynamic properties, it's difficult to determine what should be the human readable identifier, so it's left up to the administrator. (Don't think it matters but this is an ASP.NET MVC3 Application). To help during debugging I had started decorating some classes with DebuggerDisplayAttribute to make it easier to debug. This allow me to do things like
[DebuggerDisplay(#"\{Description = {Description}}")]
public class Group
to get a better picture of what a specific instance of an object is. And this sort of setup would be perfect but I can't seem to find the implementation of this flexibility. This is especially useful on my dynamic objects because the string value of the DebuggerDisplayAttribute is resolved by the .NET framework and I have implementations of TryGetMember on my base object class to handle the dynamic aspect. But this only makes it easier for development. So I've added a field on what part of my object is still strongly typed and called it Title, and I'd like to let the administer set the implementation using their own format, so to speak. So for example they might build out a very simplistic rental tracking system to show rentals and they might specify a format string along the lines of
"{MovieTitle} (Due: {DueDate})"
I would like that when they save the record to add some logic to first update the Title property by resolving the format string to substitute each place holder with the value of the appropriate property on the dynamic object. So this might resolve to a title of
"Inception (Due: May 21, 2011)", or a more realistic scenario of a format string of
"{LastName}, {FirstName}"
I don't want the user to have to update the title of a record when they change the first name field or the last name field. I fully realize this will likely use reflection but I'm hoping some one out there can give me some pointers or even a working example to handle complex format strings that could be a mix if literal text and placeholders.
I've not had much luck looking for an implementation on the net that will do what I want since I'm not really sure what keywords would give me the most relevant search results?
You need two things:
1) A syntax for formatting strings
You have already described a syntax where variables are surrounded by bracers, and if you want to use that you need to build a parser that can parse that. Perhaps you also want to add ways to specify say a date or a number format.
2) Rules for resolving variables
If there is a single context object you can use reflection and match variable names to properties but if your object model is more complex you can add conventions for searching say a hierarchy of objects.
If you are planning to base your model objects on dynamic chances are that you will find the Clay library on CodePlex interesting.

design using a readonly class in c#

Small design question here. I'm trying to develop a calculation app in C#. I have a class, let's call it InputRecord, which holds 100s of fields (multi dimensional arrays) This InputRecordclass will be used in a number of CalculationEngines. Each CalculcationEngine can make changes to a number of fields in the InputRecord. These changes are steps needed for it's calculation.
Now I don't want the local changes made to the InputRecord to be used in other CalculcationEngine's classes.
The first solution that comes to mind is using a struct: these are value types. However I'd like to use inheritance: each CalculationEngine needs a few fields only relevant to that engine: it's has it's own InputRecord, based on BaseInputRecord.
Can anyone point me to a design that will help me accomplish this?
If you really have a lot of data, using structs or common cloning techniques may not be very space-efficient (e.g. it would use much memory).
Sounds like a design where you need to have a "master store" and a "diff store", just analogous to a RDBMS you have data files and transactions.
Basically, you need to keep a list of the changes performed per calculation engine, and use the master values for items which aren't affected by any changes.
The elegant solution would be to not change the inputrecord. That would allow sharing (and parallel processing).
If that is not an option you will have to Clone the data. Give each derived class a constructor that takes the base Input as a parameter.
You can declare a Clone() method on your BaseInputRecord, then pass a copy to each CalculationEngine.

How to design to prompt users for new values for properties of deserialized objects?

Right now, I'm currently serializing a class like this:
class Session
{
String setting1;
String setting2;
...etc... (other member variables)
List<SessionAction> actionsPerformed;
}
Where SessionAction is an interface that just has one method. All implementations of the SessionAction interface have various properties describing what that specific SessionAction does.
Currently, I serialize this to a file which can be loaded again using the default .Net binary serializer. Now, I want to serialize this to a template. This template will just be the List of SessionActions serialized to a file, but upon loading it back into memory at another time, I want some properties of these SessionActions to require input from the user (which I plan to dynamically generate GUI controls on the fly depending on the property type). Right now, I'm stuck on determining the best way to do this.
Is there some way I could flag some properties so that upon using reflection, I could determine which properties need input from user? Or what are my other options? Feel free to leave comments if anything isn't clear.
For info, I don't recommend using BinaryFormatter for anything that you are storing long-term; it is very brittle between versions. It is fine for short-lived messages where you know the same version will be used for serialization and deserialization.
I would recommend any of: XmlSerializer, DataContractSerializer (3.0), or for fast binary, protobuf-net; all of these are contract-based, so much more version tolerant.
Re the question; you could use things like Nullable<T> for value-types, and null for strings etc - and ask for input for those that are null? There are other routes involving things like the ShouldSerialize* pattern, but this might upset the serialization APIs.
If you know from start what properties will have that SessionAction, you must implement IDeserializationCallback and put to those props the attribute [NonSerialized]. When you implement the OnDeserialization method you get the new values from the user.

Categories