I asking this mostly to see if there is something that ressembles what I am trying to achive.
My ultimate goal is to serialize an object graph, keeping references, but making all the properties accessible via a Path of sorts.
My first thoughts were something like dictionary and recursively loop through all the objects properties/fields, and if the value is different than the Default one, try and serialize if its a primitive, otherwise keep going till the type can be serialized.
I need to support Types not marked as [Serializable], and to be able to add custom serialization, similiar to how surrugates work in the BinaryFormatter.
Is there a serializer that works remotely like I said?
Or what other caveats can you think of, by this aproach?
Note: The serialization Size is not a big issue nor is the speed that it serializes/deserializes, at least for now.
An example of what I want to to is something like this :
SerializationContext.GetValue["root/Prop/X"] returns me the X value.
This needs to work with .Net 3.5, and it should serialize based on field/property name.
Related
I have a predefined data format, which requires me to have an object like this:
settings:{
settingA:'someValueFromSql',
settingB:'someValueFromAD'
settingC:'someValueFromConfigFile',
settingD:'someValueFromReflection',
settingE:42,
...
}
This settings object is in fact a huge mess of data stitched together from many different sources, but this is how the data is expected by the frontend. I'd like to put the "get/process all data from one source" in a function each, and tape the object together in the end.
So I would have one object
sqlSettings:{
settingA:'someValueFromSql',
settingG:'someOtherValueFromSql',
...
}
returned by function a, and an object
adSettings:{
settingB:'someValueFromAD',
settingV:'someOtherValueFromAD',
...
}
returned by function b, and an object
settings includes adSettings, sqlSettings
where, with at most two simple steps, I can "join together" both objects into a flat third object.
Is this possible with fixed-size objects, without using a generic Dictionary, or am I barking up the wrong tree?
(I'm sure this question was already asked on SO, but I guess I don't find the right words)
It's not possible with a "normal" object, but you can do it with an ExpandoObject and the dynamic keyword. But you need at least .net 4.0
dynamic settings = new ExpandoObject();
//If you try to assign a property that doesn't exist, it is added to the object.
settings.SettingA="sfgd"
Anyway I discourage using this approach. why you don't want to use a IDictionary<string, object> or better a IDictionary<string, MyCustomSettingObject>
--------------------UPDATE---------------------
if the only thing that stops you from using a dictionary is the serialization you can implement the IXmlSerializable Interface and ouput the xml you like:
Proper way to implement IXmlSerializable?
If those partial setting objects have fixed size (meaning fixed number of properties), then you can definitely create a flat object with e.g. only properties to fit all the values in. Then to ease your work, you can try to use Automapper to map the partial objects to the "grouped" object.
http://automapper.codeplex.com/
Otherwise, you will have to stick with the dictionary.
I am building web service in C# for a particular application, I have a XML definition of module. I have created a class called Field that holds the properties of all fields on a module. What I would like to do is create the field objects but name them dynamically then add them to a list of some sort. So when I reference them from the client it would be like this:
Module.Fields.MyDynamicName.FieldProperty
Is this possible to do? and could anyone point me in the right direction on how to do this.
Hope my question makes sense.
Basically you need to design for "deferred design", which means you do not know at compile time what the design is, but you still need to accommodate it.
There are probably a few ways but what I have done in the past is use a dictionary list of Key/Value pairs to store fields. Using serialization (I prefer Json) you can shove just about anything into a string and store it as the Value, then deserialize it when you need it.
I'm attempting to write a generic serializer using protobuf.net v2. However I'm running into some issues which make me wonder if perhaps what I'm doing is impossible. The objects to be serialized are of an indeterminate type to which I don't have access so I'm attempting to walk the object and add its properties to the type model.
var model = TypeModel.Create();
List<string> propertiesToSerialize = new List<string>();
foreach (var property in typeToSerialize.GetProperties())
{
propertiesToSerialize.Add(property.Name);
}
model.AutoAddMissingTypes = true;
model.Add(typeToSerialize, true).Add(propertiesToSerialize.ToArray());
For simple objects which contain only primitives this seems to work just fine. However when working with an object which contains, say, a Dictionary<string,object> I encounter an error telling me that no serializer is registered for Object.
I did look at serializing a Dictionary<string,object> in ProtoBuf-net fails but it seems the suggested solution requires some knowledge and access to the object being serialized.
Any suggestions on how I might proceed?
protobuf-net does not set out to be able to serialize every scenario (especially those dominated by object), in exactly the same way that XmlSerializer and DataContractSerializer have scenarios which they can't model. In particular, the total lack of metadata in the protobuf format (part of why it is very efficient) means that it is only intended to be consumed by code that knows the structure of the data in advance - which is not possible if too much is object.
That said, there is some support via DynamicType=true, but that would not currently be enabled for the dictionary scenario you mention.
In most cases, though, it isn't really the case that the data can be anything; more typically there are a finite number of expected data types. When that is the case, the object problem can be addressed in a cleaner way using a slightly different model (specifically, a non-generic base-type, a generic sub-type, and a few "include" options). As with most serialization, there are scenarios were it may be desirable to have a separate "DTO" model, that looks closer to the serialization output than to your domain model.
A final note: the GetProperties()/Add() approach is not robust, as GetProperties() does not guarantee any particular order to the members; with protobuf-net in the way you show, order is important, as this helps determine the keys to use. Even if the order was fixed (sorting alphabetically, for example), note that adding a member could be a breaking change.
I've done a lot of serialization development lately, mostly for sending objects over sockets, but I've run into an interesting question: Is it possible to send just a few of the properties from an object through a serializer?
My envisioned scenario is this: You have some sort of "state" object for each client, consisting of many properties (strings, ints, bools, etc). When your client first connects, the entire state object is serialized via an Xml or Binary serializer, and sent over the socket, to be recreated on the other side. Now both client and server have identical state objects. Your server then needs to change the state, and does so by simply setting one of the state object's property. The socket (either hooked to the state's events, or part of the state object itself) could synchronize the two states by reserializing the entire object, but it seems like a single "property change" object would do.
Obviously, this could be implemented manually. But it seems like a serializer should be able to serialize just a single property, and apply it like a patch on the other side. Does anyone know if this is possible, or would I have to write the entire thing from scratch?
With XmlSerializer (and protobuf-net, for a binary equivalent, since protobuf-net adopts most of XmlSerializer's patterns) you could do this by having a method:
public bool SouldSerializeFoo() {
return fooIsDirty;
}
public string Foo {get;set;}
for each property Foo - but you'd need to maintain the "what is dirty" manually in your own code (perhaps in the set). Lots of work; I've done a diffing serializer in the past - it was a real PITA, to be honest. I should also note that the [XmlIgnore] public bool FooSpecified {get{...} set{...}} pattern does the same thing, but for what you want, ShouldSerialize* is more appropriate.
As an addition to Marc's answer, here's the MSDN docs on the ShouldSerialize* methods
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.