XmlObject - Adaptive Object Model |
Better Designs Faster |
XmlObject Resolvers |
Prior to the invention of the IXmlObjectResolver I am not sure that the XmlObject Framework could claim to be adaptive. The resolver is the link between metadata in the XML and metadata in the code. It is used by the operating system to determine what classes will be instantiated when a given application is run. There are likely an infinite number of ways a resolver could be architected. Described here is one solution that has worked well. Don’t let the simplicity of this solution deceive you. It has been used to implement very complex pluggable components. That is, components with functionality discovered at runtime by the mere presence of a new assembly. This is XCopy installation at its finest. So how does this work? First one needs to understand a little about Custom Attributes and Reflection. Custom Attributes are bits of meta-data that the developer can attach to assemblies, classes and methods. This meta-data can then be used by the operating system, at runtime, for the purpose of discovery. Most modern languages have these features available. The XmlObject Framework defines two Custom Attributes. The AssemblyDescriptorAttribute and the ElementDescriptorAttribute. The AssemblyDescriptorAttribute is applied by inserting the following attribute into an assemblies AssemblyInfo.cs file. [assembly: Assembly Descriptor( "cli", "xmlobject.application.cli" )] Look at the AssemblyInfo.cs in the CLI project for an example. Demo Applications\Console\CLI\Properties\AssemblyInfo.cs Because this Assembly contains this attribute we know it will be used to create XML elements that have the prefix cli and that belong to the XML namespace xmlobject.application.cli. Whenever the framework parses and finds an XML element having this prefix and namespace, it will use this Assembly to look up the appropriate Type. This is known as Type resolution and it is described next. Types are resolved in a manner very similar to assemblies. When a developer is creating an XmlElement derived class to handle a specific XML element, he or she will apply an ElementDescriptorAttribute to the class being created. For example the following attribute tells the framework to instantiate a CommandElement when the parser encounters an XML element with the local name command. [ElementDescriptor( "command" )] The developer will create an XmlElement derived class for each element that requires custom business logic and the XML parser will instantiate these objects as replacements for the System.Xml.XmlElement base class it was derived from. |