I'm working on a client-server application where the client is
controlling two devices (aka servers) which both implement the same
interface contract.
We have a set of about 4 assemblies which specify the interfaces and
the data types which flow through the interfaces. Initially, we
thought this would be enough for the client to talk with the server.
In general it is, but when an exception is generated by the server it
fails to de-serialize if its declared in an assembly which doesn't
exist on the client-side. To workaround this, we've put all server
assemblies on the client-side.
All of the assemblies are strong-named and none are in the GAC,
they're all in the local program directory of the client. The client
is running on NT, so GAC-deployment isn't an option.
So, the exact same version that's running on the server has to be in
the client directory for everything to work. This causes a big problem
if we try to run two different versions of server code. Even if all
the interface definitions are the same, some small change in an
implementation DLL causes the version to be different which means we
can only talk to one of the two servers. Furthermore, our current
build process produces different assembly versions for every assembly
on every official build (default 1.0.* assembly version).
Our long-term plan is to move all exception definitions into the
interface DLLs; this eliminates the problem where implementation-side
changes need to affect the client. We would also only increment the
assembly version when the contents of the assembly actually change;
presumably something in our build process would detect this and
manually increment the assembly version. I assume we would have to
increment the assembly version as well if any dependent assemblies had
changed, correct?
There's still a possibility of exceptions being generated by
third-party OEMs. Does this mean I have to have the DLLs which might
contain 3rd party exception definitions in my client directory? Geez,
what a nightmare? Is this what everyone is dealing with?
Is that a good plan?
Next, I'm worried about a scenario where both servers are running
v1.0.0.0 of all interface DLLs, then one of them is upgraded for a
bugfix and that introduces a new exception in one of the interface
DLLs. Now, that interface DLL is v1.1.0.0.
The goal here would be to allow the client to be upgraded with the
v1.1.0.0 of the interface DLL, and the server to be upgraded with the
new interface DLL and all its implementation DLLs. The client would
still be able to communicate with the other server still running
v1.0.0.0.
From my newsgroup reading, there's some way to specify in a config
file that v1.1.0.0 can be loaded in place of v1.0.0.0, right? Is there
any automatic way to ensure that v1.1.0.0 is backwards compatible with
v1.0.0.0, for example verifying that v1.1.0.0 only adds content, does
not remove or modify any?
What I really wish is that .NET would automatically allow me to use a
newer version of the assembly as long as it didn't modify or remove
any existing parts of the original interface.
Is there someway I could use an assembly versioning scheme which
designated whether backwards compatability had been broken, so that I
could automatically detect whether the two servers are running
sufficiently compatible versions to co-exist?
This is so confusing I barely know what questions to ask, if you
understand my problem and have ideas I appreciate your help.
Thanks a ton,
-ken