A C# .NET application talks to an external component by calling a known API and marshalling interop structures from the component's response.
This is already implemented and working well. However, once versioning comes into the equation, things get a bit more complicated: as the component will evolve over time thus requiring interop structures be kept in-sync. The application must still be able to talk to components on older versions, so that it has to pick the right interop structs at run-time for a given version of the component.
I've been throwing this problem around in my head for a couple days and haven't come up with anything I'm particularly happy about. Google hasn't been much help, either, so I thought I'd try writing this up and posting it here in an effort to get some feedback. This is what I have so far.
Package all versions of the structs in a library, have a registry and decide at runtime which structs to use
Here, every new version of the structs is compiled into the new version of the .NET application, and some kind of registry is responsible for mapping API versions to interop struct versions in the library.
Class/struct naming becomes an issue, since Class1
would now have to be called Class1_v1_1
or some other way to disambiguate based on the name (either that, or use the same name and put them in a separate namespace).
Load versions of the interop structures from a versioned DLL
Here, every version of the interop structs would be compiled into an individual DLL and loaded dynamically based on the API version. A mapping would still need to be created between API version and DLL name.
The naming problem disappears, but certainly there are a lot more moving pieces for deployment and consequently things that can go wrong at runtime.
As I said, I'm not happy with either one and feel that there's a much obvious/cleaner/elegant solution which is escaping me. I can't imagine that I'm the first person who's had to support changing versions of a dependent component, so is there some known pattern which can provide some guidance for scenarios such as this?
Thanks in advance for any feedback &/or possible alternatives!