Scenario
I have a use case where I need do decompose
an hierarchical object tree
into a set of its constituent objects. Later on, I will also need to recompose
those objects back into their original form.
Goals
My goals are as follows.
- Determine the
fastest
and mostprocessor
and/ormemory efficient
ways todecompose/recompose
the objects. (This code will process millions of objects so saving even a few ticks is useful.) - Locate any existing
libraries
orexamples
which may facilitate thisdecomposition/recomposition
scenario or which may demonstrate how others have done something similar. - Compile a list of
strategies
,methods
, andtechniques
fordecomposing
anobject hierarchy
(in.NET 4.5+
,.NET Core
) into its elementary objects andrecomposing
those elementary objects back into an hierarchy. (Note: There is no such thing as too many ideas, too many techniques, or too many examples here.)
'Givens' / Requirements
- This functionality will be implemented in
.NET Core 1.x
and above. Backwards compatibility with.NET 4.5+
would be a plus. - The structure of the
object tree
is not necessarily known in advance.- The
decomposition component
must be able to work with any provided object tree.
- The
- The
object hierarchy
may be many layers deep.- The
decomposition
will run recursively until it reaches the lowest level of theobject tree
. Most objects (except as described below) will bedecomposed
. Arrays
andcollections
may optionally be kept intact rather than beingdecomposed
. This will vary from usage to usage. I would say that generally,Arrays
,Dictionaries
,simple lists
(e.g.lists of strings
) will generally not bedecomposed
.Complex lists
(e.g.lists of objects
will likelydecompose
.)
- The
Recomposition
of object hierarchies may be full or partial.- During
recomposition
, other objects may be inserted into the object hierarchy (or existing objects may be replaced) to make completely new types of objects.
Potentially Important Issues Not Yet Considered
I am still at an early stage in analyzing how to accomplish this object. (Frankly, I feel like I am flying blind here.) There are probably many important factors I have not considered. These include:
- Any potential impact of self-referencing
classes
. - Implications or impact of other potential element or object types.
Resources I am Currently Reviewing
I have a reasonable idea of generally how to accomplish the decomposition and recomposition through reflection. However, I am not confident that I know how to do it well, do it efficiently, or do it in a way that properly handles every issue.
Here is a list of some of the resources I am reviewing now.
XmlSerializer
- from .NET reference source http://ift.tt/2rgcoxyNewtonsoftJson
- http://ift.tt/1bCBZrvMessagePack-Csharp
- for .NET Core - extremely efficient. http://ift.tt/2lMsoFpProtobuf.net
http://ift.tt/1vafO3F
Demo Class / Object Hierarchy
I have created a very simple for-demonstration-purposes-only class hierarchy
which represents the types of elements I would expect to find in the object hierarchies which we will process.
These include:
ValueType
- (e.g. integer) PropertyString
- PropertyDateTime
- PropertyCustom Class
- PropertyDictionary
- CollectionLists
- CollectionArray
- Field
There is a single base class which generates an Id
of type Guid
on the parent and all children.
public class EntityBase
{
public EntityBase()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
The root object
in the demo hierarchy is of type Person
. It contains various general properties of type string
, int
, and DateTime
just as one would find in most any class. It also contains List
and Dictionary
collection classes
, as an array
, and a reference to single custom object.
public class Person : EntityBase
{
public Person()
{
Phones = new List<Phone>();
Addresses = new List<Address>();
Passwords = new Dictionary<string, string>();
FavoriteFood = new FoodPreference();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Weight { get; set; }
public DateTime DateOfBirth { get; set; }
public FoodPreference FavoriteFood {get; set;}
public string[] Dogs = { "Shayna", "Sport" };
public Dictionary<string, string> Passwords { get; set; }
public ICollection<Phone> Phones { get; set; }
public ICollection<Address> Addresses { get; set; }
}
There is a collection
of phone numbers.
public class Phone : EntityBase
{
public string PhoneNumber { get; set; }
}
There is a collection
of postal addresses.
public class Address : EntityBase
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
There is a custom class
with some detail on a favorite food.
public class FoodPreference : EntityBase
{
public string FoodCategory { get; set; }
public string FoodName { get; set; }
}
Just to put it all together, here is a sample method which populates the heirarchy with dummy data
.
public static Person BuildPerson()
{
return new Person
{
FirstName = "Anthony",
LastName = "Gatlin",
Weight = 154, // I wish. :)
DateOfBirth = DateTime.Parse("01/01/1970"),
Phones = new List<Phone>
{
new Phone {PhoneNumber = "601-555-1212"},
new Phone {PhoneNumber = "601-555-1213"}
},
Addresses = new List<Address>
{
new Address {StreetAddress = "111 Country Rd", City = "Heidelberg", State = "MS", PostalCode = "39349"}
},
Passwords = new Dictionary<string, string>
{
{"google","googlepass" },
{"skype","skypepass" },
{"facebook","facebookpass" }
}
};
}
The sample object hierarchy can be retrieved from http://ift.tt/2rfSKl3.
Output From Sample Data
Following is a simple JSON dump
of sample data
generated for this hierarchy.
{ "Dogs": [ "Shayna", "Sport" ], "FirstName": "Anthony", "LastName": "Gatlin", "Weight": 154, "DateOfBirth": "1970-01-01T00:00:00", "FavoriteFood": { "FoodCategory": "Baked Goods", "FoodName": "Chocolate Cake", "Id": "0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5" }, "Passwords": { "google": "googlepass", "skype": "skypepass", "facebook": "facebookpass" }, "Phones": [ { "PhoneNumber": "601-555-1212", "Id": "57bdfdcb-4232-40e4-aab8-4c6387029257" }, { "PhoneNumber": "601-555-1213", "Id": "b591afc3-6e91-4030-ad26-00beefceca43" } ], "Addresses": [ { "StreetAddress": "111 Country Rd", "City": "Heidelberg", "State": "MS", "PostalCode": "39349", "Id": "94cc5e37-db96-44b7-869a-818968d99ddd" } ], "Id": "629ae27e-17aa-49ad-823a-2cd2ebf0cb66" }
Expected Result
Once the objects have been decomposed
from the object hierarchy
, I will end up storing some sort of simple hierarchy
which will allow me to recompose
the objects.
Given the following Id
Guids
...
629ae27e-17aa-49ad-823a-2cd2ebf0cb66
// Person Id0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5
// FavoriteFood57bdfdcb-4232-40e4-aab8-4c6387029257
// Phone1 Idb591afc3-6e91-4030-ad26-00beefceca43
// Phone2 Id94cc5e37-db96-44b7-869a-818968d99ddd
// Address Id
we may end up with a very simple JSON Hierarchy
like so.
{
"Person":{
"Id":"629ae27e-17aa-49ad-823a-2cd2ebf0cb66", "FavoriteFood":{
"Id":"0c516c4d-ff64-4b8d-bb44-b430aa8d3ce5" }, "Phone":[
{
"Id":"57bdfdcb-4232-40e4-aab8-4c6387029257" }, {
"Id":"b591afc3-6e91-4030-ad26-00beefceca43" } ], "Address":[
{
"Id":"94cc5e37-db96-44b7-869a-818968d99ddd" } ] } }
Each object with dependencies
will have its own one-level
dependency tree
.
The above format is just an example, and I am completely open to (read desperately seeking) ideas on better ways to do this.
Each of the elementary objects will actually be serialized to JSON
or MsgPack
. We will be able to fully
or partially reassemble
the objects from the hierarchy when required.
Thank You!
I am really looking for any guidance, recommendations, advice, ideas, tips, examples, code snippets, libraries, or anything else you can offer that will help me to accomplish this task efficiently.
Thank you so very much, in advance, for your help! It is extremely appreciated.
Aucun commentaire:
Enregistrer un commentaire