Ah, the benefits of open source. Today I decided to take off the gloves and dig into the Linq2Xsd project that we’ve been using at work. For a long time it’s served our purpose well unmodified, but as the schema grows in complexity it looks like it’s time to dig into the code.
My main problem is that our very (un)thoughtful contractors are generating multiple xsd schemas based on the same few basic files. Linq2Xsd doesn’t handle this elegantly, and will give me a string of validation errors when I try to generate them together, similar to
"c:\path\filename.xsd(##,##): error TX0001: The complexType 'AccountType' has already been declared.'
So what we’ve been doing is generating multiple code files for the multiple target schemas. This works to a degree, but since our base schemas have global types, rather than neatly namespaced types, we can forget about trying to put more than one generated code file in the same project. Forget about even referencing them from the same project! The global namespaces collide bigtime and cause me major headaches.
Error 18 The type 'SchemaType' exists in both 'c:\path\binary.dll' and 'c:\path\binary2.dll'
Bummer. So, I’ve got to do one of two things.
- Get the code generator to make these classes internal, and write a public wrapper for each that *isn’t* global.
- Get the code generator to wrap these classes in a namespace, so they won’t clash globally.
Option two sounds sweeter, and less manual. But how in the hell can I pull this off? I’ve never worked with or even seen code generation before. Opening up the source for Linq2Xsd is almost like reading COM code. Ack.
Even better, after a peek at the code though, I’ve realized that I can use the Linq to xsd config to handle this.
<?xml version="1.0" encoding="utf-8" ?> <Configuration xmlns="http://www.microsoft.com/xml/schema/linq"> <Namespaces> <Namespace Schema="http://www.Schema1" Clr="My.Schema1"/> <Namespace Schema="http://www.Schema2" Clr="My.Schema2"/> <Namespace Schema="" Clr="My"/> </Namespaces> </Configuration>
Then I just run the app and pass the config into the command line…
LinqToXsd.exe MySchema.xsd /config:Linq2Xsd.config
and… works like a charm! My global namespaces will now be encased in a neat “My” namespace.
To think we’ve been fighting with this namespace issue for 2 years. Phew!