The magic behind the mapping files

If your mapping schema is completely correct, some magic happens behind the scenes. Now, before it does, make sure that evrything is mapped appropriately, that all members of your classes have been mapped or explicitly excluded from the schema. There should be no red question marks present. Also, all the classes should be bound to actual CLR types. As opposed to the PDC bits this build now has normal names for the classes, not necessarily the fully qualified names of the types. When a class is unbound to a type, it will show a red squiggly mark (just like from the spell checking in Word). Simply right-click it and choose Bind Class from the context menu. Then give the FQN of the CLR type.

Try this: close the Mapping Editor and open your msd file with the XML editor. You will find no trace of the bound classes you just made. Clicking on Show All Files will reveal an msdx file behind the msd file. It’s an XML file that looks something like this:

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<osi:Root generateWith=”Default.xslgeneratedClassName=””
    <osi:TypeBinding referenceName=”Customer”
        fullName=”Northwind.Customer” />
    <osi:TypeBinding referenceName=”Order”
        fullName=”Northwind.Order” />

In this file the bound classes and any excluded members are administered.

If the magic has happened, you should also find a Visual Basic (or C#) file below/behind the msdx file. This file contains generated code. Essentially it contains a class derived from ObjectSpace that will automatically load the mapping files from embedded resources. This is why the mapping file is marked as an Embedded Resource in your project. Furthermore the derived ObjectSpace class will have helper functions to create strongly typed ObjectReader classes. This last feature is not fully implemented yet. In newer builds you will probably find methods such as GetCustomerReader and the likes.

The ObjectSpace derived class is a facade class and named after the mapping file by default. If your mapping file is called the facade class will be NorthwindMapping_msd_Facade. You can use this facade instead of the regular ObjectSpace class. The purpose of this class is twofold. First of all, it has to return a mapping file when provided with an URI for the schema. On the other hand it has to provide the correct Type references for the normal names of classes (as described at the beginning of this blog entry).

BTW, you can customize the name of the facade class by modifying the msdx file. Just specify your desired class name in the generatedClassName attribute of the root. I was unable to find a way to do this with the editor.

Inside the facade class a private nested Resolver type is declared. This Resolver derives from XmlUrlResolver and implements the ITypeLoader interface. It also holds a private Hashtable that contains the name-value pairs for the normal names and type information. The ITypeLoader interface has just one method called LoadType and it will return the type from the Hashtable given the normal name. The override of the XmlUrlResolver class called GetEntity returns a stream for the filename of the mapping file. The stream is a manifest resource stream. In summary, using the facade class instead of the regular ObjectSpace will spare you the loading of the ObjectMapping and give you strong typed helper methods (in later builds).

The code is generated with the use of XSL Transformations. The accompanying files for the process are located in C:Program FilesMicrosoft Visual Studio 8Common7IDEMappingToolCodeTemplatesObjectSpacesFacadeLayer for a default installation of VS2005. There are two files, TemplateOptions.xml and Default.xsl. The latter was already mentioned in the msdx file in the generateWith attribute of the root element. During the transformation XCode is generated which can be turned into VB or C# code by the CodeDom. The TemplateOptions.xml file contains some project settings for the generated code.

There seems to be a tiny problem with the code that is generated. The embedded mapping file is stored under it’s filename. However, the generated code tries to retrieve this resource with a prefixed period (.). When you try to construct a new facade object like so:

Dim con As New SqlConnection(connstring)
Dim facade As New NorthwindMapping_msd_Facade(con)

you will get a FileNotFoundException. This exception occurs, because the embedded resource is not found. The file will then be loaded from the full filepath, which is the Bin (or bindebug for C#) folder, where the mapping file is not located unless you copy it to that location. To fix this you could alter the default.xsl file or the generated code (locate the GetManifestResourceStream call and remove “.” + in that line of code). Remember that the code is potentially regenerated after every alteration to the mapping file. After that you should be able to play around with the facade.

Right now, the facade provides not that much improvement over the ObjectSpace class, but then again, the full functionality is not implemented yet. I suspect that we can see some improvements in future build of OS, that will make this facade very worthwhile.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s