I am currently working on a project in which, a while back, I had to write a utility application to extract snippets of HTML from specified nodes in an incoming XML file, and transform that HTML in a number of different ways. A full explanation of this utility application is beyond the scope of this post. However, relevant to this post, the application needed to handle an incoming XML file whose format was not constant from one run of the application to the next, but was limited to one of several specific formats. I therefore defined the following simple interface:
The intended purpose of the single method in this interface was, as you might guess, to get the HTML snippets from the incoming XML file. I then defined a separate class for each possible XML file format, implementing the interface in each class. For example, one of the formats contained full HTML documents in a specified node. I appropriately named this class ‘FullHtmlRepository’. The following is the code for this class:Since I didn’t know the format of the incoming XML file before a given run, I didn’t know which class to instantiate prior to the run. I thus needed to generate the correct class dynamically at the beginning of a specific run. This is where the CreateInstance method came into play. Recall from the opening paragraph that I had decided to use the overload with the CreateInstance( Type ) signature. ‘Type’, of course, is the class to be instantiated. This is the method that I used to instantiate the appropriate class:

Here I took advantage of the Type.GetType( string ) static method, which converts a string that describes a type into a Type variable. I obtained that description from the application’s app.config file:

Now this is perhaps not the best way of getting the description. An application intended for production might, for example, ask the user to specify which format to process during a given run (pick from a listbox) and then validate the input file against the appropriate schema. But, remember, regardless of how sophisticated you might think this application was, it was a utility, throw-away application. Quick and dirty – within reason – was the modus operandi.
Let’s examine the string presented in the value attribute of the above ‘add’ node. Note that it really consists of two comma-delimited strings. The first string is the fully-qualified name (namespace plus class name) of the class to be instantiated. The second string is the name of the assembly that contains the code for that class. So, it really doesn’t matter what the source of the class description string is, as long as it contains these two elements … and as long as they exist, of course.
Going back to the GetRepository method, note that the return statement first creates an instance of the FullHtmlRepository class, and then casts that instance to an IRepository type so that it can be used in a class-agnostic manner elsewhere in the application.
That’s it. Elementary, my dear Watson!
NOTE: If one of the above images is too small for you to view properly, just double-click it. Then, when you are done viewing the image, click on the navigate-back arrow on your browser.


No comments:
Post a Comment