I am writing a program that will have an interface similar to Windows Explorer. In this explorer view, there can be objects of various types, but each of the objects will implement the same interface so they can be treated the same way by the explorer and other parts of the program that will be acting on them. So let's say I have the interface:
public interface IMyObject
{
IMyObject Parent { get; }
string DisplayName { get; }
bool IsParent { get; }
}
For obvious reasons I don't want just anything in my app setting these properties. They should all be set through the constructor of the object. So an object would look like:
public class MyFileObject : IMyObject
{
public IMyObject Parent { get; protected set; }
public string DisplayName { get; protected set; }
bool IsParent { get; protected set; }
public MyFileObject(IMyObject parent, string displayName)
{
Parent = parent;
DisplayName = displayName;
IsParent = false;
}
}
At some point in the processing, these objects are serialized to an XML file and saved to disk. The type of the object is saved as an XML attribute. In order to keep from duplicating a bunch of code, I first thought of creating an object factory that could create these objects from the supplied XML. However, since I don't know what type of object I have until the XML is parsed, I can't just do "new MyFileObject(...)" in the factory. I can use reflection to create the type of object from the XML, but that's slow. And then I have the problem of setting the protected properties. Again, reflection, again, slow.
So my question is, how best can I create these objects with the supplied XML and hopefully without having to make all of my properties get/set? I am using Castle Windsor and have looked briefly at its factory implementation, but can't figure out a way to make it work in this case.
Edit: I realized much later yesterday that I hadn't given you the full picture. Where the issue comes in is that sometimes I'm having to create the objects from the Xml and other times I'm having to create them "on the fly" as they're being found on the machine and added to the parent. I was trying to come up with a factory that would provide a standard means of creating the objects from either source. Richard Naud's answer still looks like it will be the best for what I'm doing. I don't really understand the IL portion, but the Linq Expresssions look promising.
Here's 2 possibilities which give good performances.
Use IL emit to construct your objects: http://ayende.com/blog/3167/creating-objects-perf-implications. This would require to create and compile a constructor delegate, within your factory, for each of your concrete type, then using the
type
attribute of your XML (see example below) to choose which one to invoke.Use compiled lambda expressions: http://rogeralsing.com/2008/02/28/linq-expressions-creating-objects/. Again here, one compiled expression by concrete type and invoking the appropriate one based on the type name.
On a side note, you must think about the Parent property when you'll serialize. As it is now, the Parent property will be saved to XML once for each of its child, maybe not the best approach.
Alternatively you could use a collection of children and serialize it as nested objects. This would allow you to add children in the collection without having to pass any of your IMyObject implementation as constructor argument, and if the Parent property is a requirement, when adding or removing child from it, simply set the Parent to the required value.
Optionally, creating an abstract class implementing the ICollection stuff means you don't have to repeat the exercise in each concrete type.
Serializing the object tree as this:
Without being a very concise response on the object construction, I hope it can help you out.