What is ExpandoObject?
The ExpandoObject
class is an implementation of dynamic object concept that enables the acquisition, definition and calling of members. If you want to define types that have their own semantic dynamic distribution, use DynamicObject
class. If you want to define how dynamic objects participate in the interoperability protocol and manage caching of fast dynamic distribution DLR, create your own implementation of the interface IDynamicMetaObjectProvider
.
- Spacename:
System.Dynamic
- Assembly:
System.Core
(dans System.Core.dll)
- Object hierarchy:
System.Object
System.Dynamic.ExpandoObject
Functioning Context
It is often requested by the customer to import a data file in XML format. It is therefore easier to work in object mode, however, the XML transformation into a pure object might be time for development. ExpandoObject
provides an answer to this problem by providing a serialization mechanism without cumbersome and complex code implementation.
How It Works?
Helper
It is the helper's responsibility to read the XML file and return a collection of objects of type ExpandoObject
.
The XML File
The XML file contains the object collection to be deserialised.
ImportProcessor
This class is responsible for processing and mapping of ExpandoObject
entity objects (POCO).
Do It Yourself (Visual Studio 2015 / C# 4.5)
- Open the solution created in my previous article on Unity: Unity Microsoft 4 / Genericity of the data access layer
- In my library
STPVideoPlayer.DataLayer
, add a new class named helper ExpandoHelper
, this class has the responsibility to read the XML file and to call a processing class to transform data
Note here, the use of the object PluralizationService
which allows using the English culture pluralize names or single out.
var pluralizationService = PluralizationService.CreateService(new CultureInfo("en-US"));
var item = new ExpandoObject();
- To read a file, we will use the method
ExpandoHelper.ReadDocument(xmlFile)
ExpandoHelper : [C#]
public static class ExpandoHelper
{
public static dynamic ReadDocument(string path)
{
XDocument xDoc = null;
if (Path.IsPathRooted(path) == false)
{
path = System.Web.HttpContext.Current.Server.MapPath(path);
}
xDoc = XDocument.Load(path);
dynamic root = new ExpandoObject();
Parse(root, xDoc.Elements().First());
return root;
}
public static void Parse(dynamic parent, XElement node)
{
var pluralizationService = PluralizationService.CreateService(new CultureInfo("en-US"));
var item = new ExpandoObject();
string name = pluralizationService.Singularize(node.Name.LocalName);
name = name.EndsWith("s") ? name.TrimEnd('s') : name;
if (node.Elements(XName.Get(name)).Count() > 0)
{
var list = new List<dynamic>();
foreach (XElement child in node.Elements(XName.Get(name)))
{
Parse(list, child);
}
AddProperty(parent, node.Name.ToString(), list);
}
else
{
foreach (var attribute in node.Attributes())
{
AddProperty(item, attribute.Name.ToString(), attribute.Value);
}
if (node.HasElements)
{
foreach (var element in node.Elements())
{
var list = new List<dynamic>();
string nameItem = pluralizationService.Singularize(element.Name.ToString());
if (element.Elements(nameItem).Count() > 0)
{
foreach (var ch in element.Elements(nameItem))
{
Parse(list, ch);
}
}
else
{
Parse(list, element);
}
AddProperty(item, element.Name.ToString(), list);
}
}
AddProperty(parent, name, item);
}
}
private static void AddProperty(dynamic parent, string name, object value)
{
if (parent is List<dynamic>)
{
(parent as List<dynamic>).Add(value);
}
else
{
(parent as IDictionary<string, object>)[name] = value;
}
}
}