I'm seeking some discussion with this post.
I'm looking at incorporating C# 4.0 Dynamic features into a legacy system. My explicit example is using Rob Connery's Massive in a data layer. But my questions would apply anywhere a dynamic object must interact with an existing, strongly typed business object such that there is a mapping between properties.
I can automate the conversion to and from static (concrete) objects and expando objects with the following two (simplified) methods:
public static object ToConcrete<T>(System.Dynamic.ExpandoObject dynObject)
{
object instance = Activator.CreateInstance<T>();
var dict = dynObject as IDictionary<string, object>;
PropertyInfo[] targetProperties = instance.GetType().GetProperties();
foreach (PropertyInfo property in targetProperties)
{
object propVal;
if (dict.TryGetValue(property.Name, out propVal))
{
property.SetValue(instance, propVal, null);
}
}
return instance;
}
public static System.Dynamic.ExpandoObject ToExpando(object staticObject)
{
System.Dynamic.ExpandoObject expando = new ExpandoObject();
var dict = expando as IDictionary<string, object>;
PropertyInfo[] properties = staticObject.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
dict[property.Name] = property.GetValue(staticObject, null);
}
return expando;
}
But now I have a number of questions.
Does my attempt to span dynamic and non-dynamic in a legacy system represent a misconception on my part? Meaning, am I working against dynamic's intent? Am I setting myself up for problems?
Should my use of dynamics be limited to components that completely contain it with no mapping between dynamic objects and static objects? Meaning, is it bad practice to attempt to mix the two language domains? Am I creating bad architecture? An anti-pattern?
In the case of a component like Massive, if we say it is bad practice to map between ExpandoObject and strongly typed objects, then there is no way I can plug it into my legacy system since it must surface business objects into the legacy code and there is no practical way I can, or should, refactor the objects of a large, legacy code base into dynamic objects. Maybe dynamic can't be realistically added to a legacy .Net code base. Maybe it has to be incorporated from the beginning, or not at all.