Project Description
A Visual Studio add-in that allows you to graphically design .NET Configuration Sections and automatically generates all the required code and a schema definition (XSD) for them.
Requirements
Microsoft Visual Studio 2008 Standard Edition or better.
Usage
After installation, you have a new Item Type in Visual Studio named "ConfigurationSectionDesigner" (if you want to design the configuration section in an existing project) and a new Project Type named "Configuration Section Project" (if you want to start with a new project). In both cases, you get a number of files:
- ConfigurationSection.csd: the designer itself.
- ConfigurationSectionCode.tt: a text template code generator that generates the C# code for the configuration section.
- ConfigurationSectionSample.tt: generates a sample configuration file.
- ConfigurationSectionSchema.tt: generates the XSD schema representing the configuration section.
The text templates are automatically transformed when you save the designer.
Working with the Designer
If you open the .csd file in Visual Studio, you get a blank design surface onto which you can drag Configuration Sections, Configuration Elements and Configuration Element Collections from the Toolbox. Before you begin, you should right-click the design surface and select Properties, then set the Namespace and Xml Schema Namespace (if you forget, validation errors will point you to these properties).
With all the required configuration classes added, set their properties and add configuration attributes and elements by right-clicking the elements and selecting the proper menu commands.
Attributes are usually simple types (string, int, boolean, ...) that are external, where
Elements are other types defined in the designer, e.g. to make one configuration element contain another configuration element.
Defining Types
When setting the Type property of an Attribute, you get a dropdown that contains a number of pre-initialized types. It is possible to add more types to this dropdown by opening the Configuration Section Explorer window (if it is not visible, go to the View menu, Other Windows, Configuration Section Explorer). You will see a node that contains all the configuration elements (also shown on the design surface), and a node that contains all the type definitions (not shown on the designer). If you right-click the root node, you can add new External Types (e.g. System.String).
You can also define Enumerated Types (enums), for which code is also generated and which are treated specially when the XSD is generated (so you get full IntelliSense on the XML file with all the options of the enumeration).
Defining Custom Child Elements
Each Configuration Element has a propery named "Has Custom Child Elements". This controls some code that is generated and changes the generated XSD to support child configuration elements (XML nodes) that can vary and aren't known at design-time yet.
Suppose you have a logging section and a logger that is instantiated through reflection. That logger instance then parses the inner XML to define its settings.
<logger type="Logging.FileLogger, CustomLoggingAssembly">
<fileOptions filename="c:\log.txt" buffered="true" />
</logger>
So the <fileOptions> tag is only something that the FileLogger class would know about. I might as well plug in another logger type without the <fileOptions> but with <databaseOptions> instead. So the child element is custom
depending on the logger type.
The "Has Custom Child Elements" flag on the Configuration Element does two things to help in this regard:
- It generates an "OnDeserializeUnrecognizedElement" method in the ConfigurationElement class so that a partial class definition can implement the required logic to handle the child XML. You will notice that the generated code does not compile because it calls a "HandleUnrecognizedElement" method that you need to implement (the point where the compilation error occurs contains comments on how to implement that).
- It indicates in the generated XSD for the Configuration Section that the XML node that has the flag set can have any inner content (otherwise the XML with the inner tag would not be valid according to the XSD).