I don’t have many months worth of experience with software migrations as a dedicated profession, per se, but I have been doing them on and off for well over a decade in some technical capacity - mostly as a software developer or architect. The one thing that has struck me as, perhaps, the most perplexing aspect of migration, at least at the micro level, is when you come across 3rd-party components that have a solid .Net version available but their interface has changed in a destructive fashion from their latest COM version.
Typically, I think of interface changes as being either destructive or non-destructive. Newly 'dot-net-ized' components that merely have namespace changes or changes to the names of their methods or properties as being 'linear' - essentially one-to-one. While at the same time, the component may offer additional method signatures, new methods or functionality entirely. I consider this to be 'expansive' or 'progressive'. The newly release versions may indicate that certain members are being deprecated but that support still exists for the time being. In all cases, these are non-destructive.
On the other hand, destructive mutations are ones where support for particular functionality is dropped entirely, either by a non-backwards-compatible offering of method signatures and/or the removal methods or properties entirely. Perhaps a term like 'abandonment' or 'orphaned' works well. Or worse yet, destructive mutations can encompass changes where the re-architecting of an application becomes necessary because objects in the application’s architecture are shifted around in the models hierarchy or object responsibility. I refer to this as 'mutinous' or 'violent'. Some of the ADODB examples are destructive in this way. I like to think of this type of destructive.
I often think back to my initiation in object model programming and I have never been able to forget the expression, 'commitment'. The idea was that the public interface of component was a sort of commitment to the applications that consume them and especially a commitment to the developers that implant them into their applications. The publishers of these components were never ever supposed to falter on this commitment. At least, that’s what I thought while this couldn’t be further from reality.
In the past few weeks, I’ve seen lots of destructive component evolutions. The examples that I’ve come across include Crystal Reports and Microsoft’s ADODB. And while I say a lot, I am referring to more than one or two, - where there’s a lot of pondering and little evidence in so far as what to do with certain VB6 calls when porting over to C#. What surprises me the most though is how really lacking migration assistance is from COM to .Net versions of these components! While I can appreciate the need to deprecate features and methods from time to time as a way to 'evolve' the application but why not at least provide some backward compatibility or hints as to what to do with the deprecated members.
While it's wonderful that developers have considerably more control and ease in handling binary data in .Net, it is frustrating when a method with one argument, like AppendChunk() from ADODB, mutates into a half-dozen lines. It just doesn’t feel like evolution.
VB6, simple:
1: recordsetObject1("binaryData").AppendChunk recordsetObject2("binaryData")
C#, not so simple:
1: byte[] chunk1 = (byte[])recordsetObject1["binaryData"];
2: byte[] chunk2 = (byte[])recordsetObject2["binaryData"];
3: byte[] chunkFinal = new byte[chunk1.Length + chunk2.Length];
4: System.Buffer.BlockCopy(chunk1, 0, chunkFinal, 0, chunk1.Length);
5: System.Buffer.BlockCopy(chunk2, 0, chunkFinal, chunk1.Length+1, chunk2.Length);
6: recordsetObject1["binaryData"] = chunkFinal;
Certainly, I could have reduced the migration solution by 2 lines. Yuck!
1: byte[] chunkFinal = new byte[((byte[])recordsetObject1["binaryData"]).Length +
((byte[])recordsetObject2["binaryData"]).Length];
2: System.Buffer.BlockCopy(((byte[])recordsetObject1["binaryData"]), 0, chunkFinal, 0,
((byte[])recordsetObject1["binaryData"]).Length);
3: System.Buffer.BlockCopy(((byte[])recordsetObject2["binaryData"]), 0, chunkFinal,
((byte[])recordsetObject1["binaryData"]).Length+1, ((byte[])recordsetObject2["binaryData"]).Length);
4: recordsetObject1["binaryData"] = chunkFinal;
As it turns out, Microsoft did a twisted thing with this AppendChunk() function. According to the MSDN website, the first AppendChunk call on a Field object writes data to the field, overwriting any existing data and subsequent AppendChunk calls add to existing data. Ugh!
Other ADODB examples include the property ADODBRecordSet.CursorType and method ADODBRecordSet.Open( ) - where they dropped the signature with CursorTypeEnum, property ADODBConnection.IsolationLevel( ) and property ADODBConnection.Mode( ).
Changes like these last three are particularly manageable because the developer can perform the same tasks just fine. While I don’t like to have to type more than necessary (when it comes to coding, I’m quite lazy!) , this type of destructive migration challenge I can live. It’s solvable and we get past them quickly. What drives me nuts are the violent changes to 3rd party components!
So Crystal Reports has had quite an impressive following since the early 90’s. With the marriage of IT and Enterprise Reporting, the demand grew and grew. Let’s see - Crystal Services is acquired by Holistic Systems is bought by Seagate Software which is quickly rebranded to Crystal Decisions bought by Business Objects and folded into SAP, alas - in 2007. Is it any wonder that the component(s) has undergone mutinous changes?
The latest COM version of Crystal Decisions supports a number of Report Viewer events, such as DownloadFinished( ). Where did it go in the latest .Net version? Who knows! Oh, the funny thing here is that the .Net Crystal Decisions report still uses the COM-based AxWebBrowser component. We’ll just let that go. To be fair to SAP, even Microsoft has been slow to replace that component. Anyhow, I don’t blame SAP for tossing a bunch of that component out. It’s quite bloated. In fact, it’s kind of funny. In my experiences, predominantly in the Web arena, I’ve never had a need for Crystal Reports. After having worked with it - well, let’s just say I’m surprised it doesn’t offer a different licensing model.
That’s a topic for another time.