Serializing "Adapted" Objects to XML (or, "Just Bar Damn It!!")
My company, long ago, developed a Role/Task-based authentication service that has since been converted to a .NET Web Service. This service, I'll call it IMS, is basically used by any application we design, and personally, I think it's overused. When it was developed, there really wasn't anything that similar available - at least to my knowledge - and it made sense for us to have our own product that we could stand by and support. This was all before I worked for them; that's not to say I would/could do it better.
However, I'm here now and I seem to know how to gum things up real good. So, I got this crazy idea (not out of the ordinary). I'm writing this application and I can just see that IMS isn't going to be around for ever. It very well could be replaced by AzMan or some other third-party security service that is already in place at a client that they are not willing to give up. So what do I do, attempting to be the pragmatist? I design for it. I try to decouple my application from IMS, creating IUser, IRole, and ITask interfaces, creating ADAPTER classes around the existing IMS classes so that, should we switch providers, my application isn't coupled to IMS. Score one for the developer!
Here's where I ran into a world of hurt: IMS expects XML when doing any CRUD operations on its data. No problem, we have objects! We'll just serialize them using the XmlSerializer, decorating the IMS objects appropriately. Oh, if only it were that easy!! See, when there's an object hierarchy, the XmlSerializer expects the base class, in this case the IMS objects, to be decorated with XmlInclude attributes for each type that extends it. The interesting thing to note is that when I ran my tests, the error message in the exception thrown by the XmlSerializer says:
The type Namespace.Foo was not expected. Use the XmlInclude or SoapInclude attributes to specify types that are not known statically.
That one I don't get. It's absolutely right, I don't know all the types that may or may not derive from any given object at compile time. I tried slapping an XmlInclude attribute on my Adapter class; no luck. The only thing I did have luck with was comparing the Type specified in the XmlSerializer to the Type of the instance to be serialized and, if the instance is a subclass of the original Type specified, I create a new XmlSerializer specifying the subclass' Type. But that defeats the purpose!! It seems ridiculous to me that I have to specify all the types that could've subclassed the object I'm asking the serializer to give me. I honestly just want that piece, no more, no less. I typically write this kind of thing off saying "Microsoft probably had a good reason for doing it this way" but that just doesn't put my mind at easy. If I say "give me the Foo part of Bar" that's what I want damn it, not the whole Bar!! You shouldn't need to know anything about Foo, ya foo' !!! (sorry, couldn't resist...)
Obviously, if I create an instance of the IMS object, assign it the values from the adpated IMS object, serializing the IMS object itself works fine, but that seems like replacing the carpet when soda's spilled on it because steam-cleaning would be too easy...