Extracting Metadata - Creating Freeform Metadata
(Page 20 of 22 )
Freeform metadata is contained in XML files that contain anything you want to include for generating code. You’ll merge this information into other sections of data. Merging into existing sections is important because you need to access metadata without regard to its source. For example, if you need the caption for a column, you don’t care whether it was entered via an extended property or freeform metadata, and you certainly don’t want to rewrite your code generation templates just because you changed how you entered the captions. Thus, you don’t want to base the structure or organization of your metadata file on where information is coming from because it may change over the project life cycle. You accomplish this by using parallel structures in each metadata file and performing a merge that combines attributes within elements themselves—what I call an intimate merge. The “Merging Metadata” section discusses the mechanics of an intimate merge.
Creating Column Details Because the major purpose of freeform metadata is to merge with other meta-data, its design is rather easy when it's merged into an existing section. Freeform metadata files contain sections that mimic the structure of the metadata section into which you intend to merge it.
For example, the freeform metadata for adding captions, descriptions, and regular expression (regex) validation to database columns looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<dbs:Databases xmlns:dbs="http://kadgen/DatabaseStructure">
<dbs:Database Name="Northwind">
<dbs:Tables>
<dbs:Table Name="Customers">
<dbs:TableColumns>
<dbs:TableColumn Name="CustomerID"
Caption="ID"
RegEx="AlphaNumericPunc">
</dbs:TableColumn>
<dbs:TableColumn Name="CompanyName"
Caption="Company"
Desc="Company Name to appear on shipping labels"
RegEx="AlphaNumericPunc">
</dbs:TableColumn>
This allows a nonambiguous merge into the main DataStructure element and its descendants. Note that you can enter the same information using extended properties. I suggest for the sake of others that you adopt one approach consistently or at least be able to articulate what’s where.
Defining Stored Procedure Intent As shown earlier, the intent of each stored procedure is important in understanding how it’ll be used in building your application. Each business object knows how to select its data from the database, update existing data, insert data for new instances, and delete data if appropriate. Mapping the intent of each stored procedure allows the business or data access objects to know what stored procedure to use for each operation. You can store this information in the procedure name using careful naming or enter it using extended properties. Like the column information, you can alternatively enter it via freeform metadata. If you have a naming system that works on many but not all of your stored procedures, the freeform approach works particularly well in overriding a few exceptions:
<dbs:Databases xmlns:dbs="http://kadgen/DatabaseStructure">
<dbs:Database Name="Northwind">
<dbs:StoredProcs>
<dbs:StoredProc Name="nwd_Customers_Select"
ProcType="Select" />
</dbs:StoredProcs>
</dbs:Databases>
Providing UI Information In addition to being able to build business objects, you’ll also see how to build user interfaces in Chapters 9 and 10. Some aspects of your user interface don’t have a good payback for code generation because there’s a lot of variation and because existing visual tools make manual layout of user interfaces easy. Other user interface elements—including utility forms, prototypes, and supporting elements such as menus—can be created via code generation.
Metadata samples in earlier sections were easy to design because they parallels existing data structures. The following example defines a role-authorized menu structure and is a different scenario because you have free rein in how you design the structure. You want to design metadata looking forward to the code generation process. If you’re designing a menu structure, when you look forward to code generation, you might think, “Ah, I’ll be creating a main menu that will contain nested menu items. Each item may have an authorization role associated with it, and each role has the potential to run a different method when the user clicks the menu item.” Articulating the goal leads to this:
<?xml version="1.0" encoding="UTF-8"?>
<ffu:UIStucture xmlns:dbs="http://kadgen/FreeFormForUI.xsd">
<ffu:WinApplication Name="Main">
<ffu:MainMenu>
<ffu:Menu Name="MainFile" Caption="File">
<ffu:Menu Name="FileOpen" Caption="Open">
<ffu:MenuAllow Role="All" TypeName="" MethodName=”FileOpen”/>
</ffu:Menu>
<ffu:Menu Name="FileNew" Caption="New">
<ffu:MenuAllow Role="Managers" TypeName=”” MethodName="MgrsFileNew"/>
<ffu:MenuAllow Role="Admins" TypeName=”” MethodName="FileNew"/>
</ffu:Menu>
</ffu:Menu>
<ffu:MainMenu>
</ui:WinApplication>
<ui:WebApplication>
</ui:WebAppliation>
</ui:UIStucture>
If you recall earlier discussions about metadata not including dynamic data that might be changed at runtime, you might challenge this example by asking whether the permissions change at runtime. In this particular mythical application, the permissions associated with each role are set in the design with only the members of each role changing at runtime.
NOTE: In Appendix A, I suggest you stick namespaces on only the root node within your XML files. The exception to this rule is when child nodes have a distinct and self-contained purpose. In freeform metadata, each child node beneath the root corresponds to a distinct subset of data, and it’s appropriate to include name-spaces and their prefixes on the child nodes. |
Managing Freeform Metadata Files
Consider how you want to manage your freeform metadata files. You’ll probably want to keep these XML files in a single centralized directory, and you’ll certainly want to keep them under source control.
Two considerations guide how you split up the freeform information into multiple freeform metadata files. You’ll see in the section “Merging Metadata” that the last file merged overrides any previous information if they collide. The order of merging files is important, and you can’t have some parts of a single freeform metadata file merge first and other parts of the same file merge last. Once you’ve split up files on this basis, consider splitting based on who will edit the files if your group has clear roles and different people will be editing different freeform metadata files—this makes it easier to manage source control. You can also split up metadata based on the major metadata header. If you aren’t clear at this point how to split up your freeform metadata files, then you can leave them as one file. The only reason to split it up is to make it easier to manage, and all other things being equal, one file is easier to manage than several files, particularly during maintenance.
CAUTION: From a strict technical perspective, it isn’t difficult to reorganize your freeform metadata files late in the project. From a strategic perspective, I discourage this. Because data from the last file wins on any collisions, you could have one or more very small changes, from a misspelled caption to more serious problems, arise because metadata changed as a result of the merge order changing. Also, it’s important to use source control on these files, and late reorganization makes it difficult to maintain a long-term history.
This is from Code Generation in Microsoft .NET, by Kathleen Dollard (Apress, ISBN 1590591372). Check it out at your favorite bookstore today. Buy this book now. |
Next: Using Skip Attributes >>
More Database Articles
More By Apress Publishing