Question Referencing/managing/code for different versions of the same external assemblies

Ignatius_J

Member
Joined
Aug 11, 2011
Messages
5
Programming Experience
Beginner
Hi all!

Programming level:
Beginner. (Please have this in mind if my problem is a real newbie question, thanks :smile:)

IDE:

Visual Studio 2008 Professional

Situation:

In a VB.NET (3.5) Windows Forms application that, among other things, creates Microsoft SQL Server Integration Services (SSIS) Packages, we want to be able to support the creation of packages both for SQL Server 2005 and 2008. To create packages compatible with SQL Server 2005, functionality from external Microsoft assemblies with the specific version of 9.0.242.0 are needed, and to create packages compatible with SQL Server 2008 the same assemblies need to be referenced, but with another version number, 10.0.0.0. There does not, unfortunately, seem to be backwards compatibility in that SQL-2005 packages could be created using functionality in the newer 10.0.0.0-assemblies.

Today, we have a very inefficient way of handling this. For each new release of the app, we have to:
  • Build two different versions of the app, one “2005-compatible .exe” and one “2008-compatible .exe”, by:
    • Manually add/remove the specific 2005/2008-references at project level (properties).
    • Comment/uncomment respective code that is not common between the two versions of the same assemblies.
  • At installation time of the application, figure out if the machine runs SQL Server 2005 or 2008 and then install the corresponding build/version of the app.
  • We do not ship or install any assemblies with our application but instead rely/pre-requisite on that the machine on which we install our software has either the 2005 or 2008 assemblies installed in its GAC (depending on whether SQL Server 2005 or 2008 is installed there).
Questions:
I have learned that with a few tricks it is possible to reference and use identically named assemblies with different version-numbers in the very same project. But even then if we manage to do this, since the client machine always will only have only one set of the assemblies installed in its GAC (9.0.242.0 or 10.0.0.0 versions depending on which SQL Server version it has installed), and we need to reference both sets in the project to have "full support" for both 2005 and 2008, how can we avoid potential “missing dll-messages” when the client runs the app? We do not feel very excited about having to ship/install 2005-assemblies on a 2008-server and vice-versa, that would never be used by the application, even if this would constitute a solution to the above problem.

Needed
:
I am sorry if this is a really basic question for which there is a simple solution. But since I'm relatively new to software development in .NET, any guidance on a better way of handling the above situation is very much appreciated.

Thankful for any help!
Martin
 
Then I guess that that's your issue. That is saying that only the version that you actually referenced will be accepted. By setting it to False, you're saying that any version of that assembly will be accepted.
 
Thanks for your suggestion, but I am not 100% sure the Specific Version property solves the issue though (but I might be wrong).

The problem is that several names of classes/interfaces in the assemblies we use, differ between the two versions. And to be able to support creating packages compatible with both versions of SQL Server Integration Services, we need to have two "flavours" of code covering the differences.

To be more clear, let me give a real example: The assembly "Microsoft.SqlServer.DTSPipelineWrap.dll" contains an interface called IDTSComponentmetaData. In the 9.0.242.0/2005 version of the assembly this interface's name ends with "90" and in the 10.0.0.0/2008 version the name ends with "100". Thus, in our "2005-code" we do the following:
VB.NET:
Dim varSource As Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSComponentMetaData[COLOR=#ff0000][B]90[/B][/COLOR]
And in our corresponding "2008-code" we do:
VB.NET:
Dim varSource As Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSComponentMetaData[COLOR=#ff0000][B]100[/B][/COLOR]

Today in our current process, those two current lines of code are never enabled at the same time though, since it is always only one version of this assembly referenced in the project at any given time. (Trying to reference the same assembly with a different version number gives an error).

The challenge is how to be able to enable the both lines of code above at the same time and build the application successfully. I believe that to be able to do this we must, in some way, be able to reference both different versions of the Microsoft.SqlServer.DTSPipelineWrap.dll?

The second challenge I see is, even if we succeed with referencing both versions in some way, the machine on which the application is installed will always only have one version of the assemblies installed. How can we prevent "missing-dll errors" in the application on a 2005 machine which comes from the fact that our "2008 code" refers to "objects" unique for the 2008 version of the referenced assembly, IDTSComponentMetaData100, for example, which is non-existing in the corresponding 2005 version of the same assembly?

As it is today we have to add/remove references and comment/decomment respective flavours of the code above and then build two different versions of our application, one supporting creation of 2005 SSIS-packages, and one supporting creation of 2008 SSIS-packages. This is a really awkward way of working and I am looking for a way of handling this that enable us to support creation of both 2005 and 2008 SSIS packages from within one, single application.

Many thanks,
Martin
 
'Specific Version' is only used during build. The version used when compiled must be present for the app to work later.

The only way I'm aware of to do what you ask is to dynamically load the assembly at runtime and use reflection to interact with it. Depending on the amount and complexity of the code one option could be to create two class library projects that each reference the specific version, bundle both with the app and dynamically load one of them (to get a simpler reflection interface).
 
Thanks JohnH, that was the answer I was a bit afraid of actually. I have already investigated a bit in the concept with reflection and late binding. The problem is that the resulting code when using those methods becomes very complex and "bulky" and this adds to the already hard-to-work-with SSIS assemblies. Things that take two lines of code to do "normally" tend to require 6-7 lines of code using reflection and late binding...

I did not want to mention this in my first post because I wanted to be open for all suggestions, but perhaps what you suggest really is the only solution and that the added code complexity that comes with it is the price one has to pay to get the kind of flexibility I am after. :uncomfortableness:

Thanks
Martin
 
The problem is that the resulting code when using those methods becomes very complex and "bulky" and this adds to the already hard-to-work-with SSIS assemblies. Things that take two lines of code to do "normally" tend to require 6-7 lines of code using reflection and late binding...
Yes, but as mentioned, if you can wrap this in two libraries with just one or a few methods to call, perhaps with some parameters, it can become quite manageable to reflect only that. In such a scenario you could even use a third common library containing only your interfaces, and do it mostly without reflection.
 
'Specific Version' is only used during build. The version used when compiled must be present for the app to work later.
Good to know. Never actually tested or investigated that and now I don't have to.
 
Yes, but as mentioned, if you can wrap this in two libraries with just one or a few methods to call, perhaps with some parameters, it can become quite manageable to reflect only that. In such a scenario you could even use a third common library containing only your interfaces, and do it mostly without reflection.

Yes, thanks for this tip. It's just that our code for building a complete SSIS-package is quite extensive with many objects, methods, properties and parameters involved. So, unfortunately, it will never be "just a few methods to call". But hopefully soon in the future someone here will get time and motivation to re-write it with reflection/late binding as per your suggestion. In the meantime, I guess we'll stick with how we do it today :smile:

In any case, thanks for your input.

Martin
 
Back
Top