开发者

How to use a configuration file to generate and initialize objects at runtime?

开发者 https://www.devze.com 2023-01-25 18:50 出处:网络
I am currently working on a project where I need to create objects at runtime based on a configuration file.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号