How to use a configuration file to generate and initialize objects at runtime?
I am currently working on a project where I need to create objects at runtime based on a configuration file.
Project example
Here is a simplified example of the project I am working on.
Every object created must implement a specific interface, let it be called the IObjectInterface
for the example purpose :
public interface IObjectInterface
{
void DoSomething();
}
Let's assume that I have several classes that implement开发者_如何学Go this interface, each having a specific implementation, and multiple other properties relevant to the specific type :
public class SimpleObject : IObjectInterface
{
public void DoSomething()
{
Console.WriteLine("SimpleObject did something");
}
}
public class ComplexObject : IObjectInterface
{
public string ObjectName { get; set; }
public void DoSomething()
{
Console.WriteLine("The ComplexObject named {0} did something", this.ObjectName);
}
}
public class VeryComplexObject : IObjectInterface
{
public string ObjectName { get; set; }
public bool CanDoSomething { get; set; }
public void DoSomething()
{
if (this.CanDoSomething)
{
Console.WriteLine("The ComplexObject named {0} did something", this.ObjectName);
}
else
{
Console.WriteLine("The ComplexObject named {0} tried to do something, but was not allowed to", this.ObjectName);
}
}
}
I need to be able to create a IObjectInterface
object corresponding to a specific Id using the ObjectBuilder class :
public class ObjectBuilder
{
IObjectInterface BuildObject(string objectId)
{
// Build object here based on provided Id
}
}
What I am looking for is a way to specify, in a configuration file, the correct implementation of IObjectInterface
that should be created, and the parameter values associated to the specific type.
The ideal configuration file should look like this :
<objects>
<object id="Simple">
<objectInterface type="SimpleObject" />
</object>
<object id="Complex">
<objectInterface type="ComplexObject">
<ObjectName value="MyObject" />
</objectInterface>
</object>
</objects>
I think I should be able to manage the object instantiation part, but I don't really see how I can manage the initialization of the instances with clean code.
- Do you have some leads on how I can implement such a configuration file ?
- How can I easily create the final instances of the needed objects and initialize them with the parameters provided in the configuration file ?
- Are there any frameworks that could help me implementing a solution to my problem ?
Sounds like IOC for me. StructureMap NInject Microsoft Extensibility Framework
You should be able to use assemblyInstance.GetType(string)
to resolve the types (you might need to prefix with the namespace) - after that you have two choices:
1 use Activator.CreateInstance(resolvedType)
to instantiate and reflection over the properties - presumably hard-coding a few PropertyType
approaches for parsing string
, int
, etc
but that sounds like work
2 change the format of the config file such that the inner xml block is compatible with XmlSerializer
- then you can just grab the inner xml and run it through
var ser = new XmlSerializer(resolvedType);
var obj = (IObjectInterface) ser.Deserialize(...);
(using either the subtree (ReadSubTree
) reader if you already have an XmlReader
, or XmlReader.Create(new StringReader(xml))
if you have the xml as a string.
For example xml (thinking of XmlSerializer
) maybe:
<object id="Complex" type="ComplexObject">
<ComplexObject>
<ObjectName>MyObject</ObjectName>
</ComplexObject>
</object>
You may want to use reflection to create an instance of the type provided in the configuration.
I did something very similar in Java, and I wrote up a detailed explanation of the reflection-based approach I took. I don't know C#, but apparently it is similar to Java, so my Java-centric explanation might be useful to you.
You can find the explanation in Part III ("The Config4JMS Case Study") of the "Config4* Practical Usage Guide" manual that is provided with Config4*. However, before reading that, I suggest you read Chapters 2 and 3 of the "Config4* Getting Started Guide" to get an overview of the configuration-file syntax and the programming API. Doing that will make it easier to read the case study.
精彩评论