Add_in Deployment With DLL Dependencies

3110
6
02-06-2014 09:08 AM
PhilipBailey
New Contributor
I have developed two Add-ins for ArcMap using VB.net. Both use the same DLLs dependencies. However, when users have both Add-ins loaded in ArcMap they may differ in the versions of these DLLs that they ship with. So:

Add-in Number 1 ships with dependency # 1 version X
Add-in Number 2 ships with with dependency # 1 version Y

Since ArcMap is a single threaded application, it will only load each specific DLL dependency once, even though each Add-in possesses a separate and different copy of the dependency DLL. Also, there is also no way to control which Add-in gets loaded first and so the result is that I can't rely on which version of dependency #1 is loaded. ArcMap only loads one copy and it's not possible to rely which version it is.

Does anyone know a workaround please? Is there a way to ensure that each Add-in gets it's own copy of the dependency DLLs loaded?

Thanks
0 Kudos
6 Replies
NeilClemmons
Regular Contributor III
Are you setting the version number on the dependent assembly when you compile it?  If you are, then you shouldn't be having any problems.  The .NET runtime resolves dependencies by looking in several places, one of which is the directory where the calling assembly is located.  If you put your dependent assembly there, then it should have no problem finding it and loading it.
0 Kudos
PhilipBailey
New Contributor
Thanks for quick response.

So are you saying that I can bind my add-in DLL assembly to specific versions of the dependencies. Then ArcMap will detect that the different add-ins need different versions of the dependencies and will load them both?

I understand that each Add-in includes its own copy of each dependency and that behind the scenes ArcMap unpacks both the add-in and it's dependencies into a temporary folder in the user profile. So each add-in is in a folder alongside the dependencies.
0 Kudos
NeilClemmons
Regular Contributor III
Yes, but's not something that you do specifically.  It's just how it works.  When you reference an assembly in your project and then compile it, the resulting assembly is dependent on the specific version of the dependent assembly.  When you deploy your assembly, it will look for that specific version of the dependent assembly.  If it cannot find it, then you'll get a runtime exception regardless of the fact that there may be other versions of that same assembly available and/or loaded.  This is how Microsoft solved the "dll hell" problem of old.  You can now have any number of versions on the same machine and each application will use the version under which it was compiled (assuming the dependent assembly is located in one of the places the runtime will look for it).  "Version", of course, is defined as having an actual version number that changes with each release of the assembly (as opposed to just changing some code and recompiling it).

It does, however, present a different issue.  Applications that are currently deployed cannot use a newer version of a dependent assembly without first recompiling the application against the new version of the dependency and redeploying it.  There is a way around this by registering your dependent assemblies in the GAC and using publisher policy assemblies to redirect calls to the older version to the newer version.  Doing this defeats the purpose of creating ArcGIS Addins though as the one of the reasons to do this is to not require admin privileges in order to perform the install.
0 Kudos
PhilipBailey
New Contributor
Neil, thank so you so much for your response... you Rock!

I understand your response but unfortunately this is not how ArcMap seems to be working. Here's my test:

1) I created a new Window class library project in Visual Studio 2010. This library has one class with one method that returns the version number of the executing assembly (i.e. the DLL version number).

2) I then created an ArcMap add-in using Visual Studio. The Add-in has one button. Clicking the button calls the windows class library DLL and calls the "get version number" method and displays it in a message box.

3) I incremented the version number of the windows class library and rebuilt it.

3) Finally, I created another ArcMap add-in using Visual Studio. Again, one button that shows the version number of the windows class library DLL.

Launching ArcMap, adding the add-in buttons to a toolbar and then clicking both buttons shows the same version in both. i.e. ArcMap - I think because it is a single process application - is only loading the shared DLL once (the load order of the add-ins probably determines which version gets loaded).

Note that I tried this experiment twice. Once using two Visual Studio solutions and loading the windows class library project into both,as a "project" reference to each of the add-in projects. When this didn't work, I removed the windows class library projects/references and built the class library separately, copying the DLLs into the add-in projects by hand and then adding them as references from there.

One final note, I have opened the add-in files using 7Zip and sure enough, each add-in is getting the correct windows class DLL. The add-ins are getting different versions.

I would be extremely grateful to anyone with a workaround! My next experiment is to try and get Visual Studio to give the shared DLL a different build file name depending on which add-in it is being used in.
0 Kudos
RichardWatson
Frequent Contributor
Putting shared code in it's own DLL/assembly makes a lot of sense.  For whatever reason, sometimes this pattern does not work.  When that occurs what I do is to simply share the underlying code.  By that I mean that I include the source in multiple projects taking care to only have 1 master copy in source control.  To accomplish that I simply add the source to other projects by adding an existing file as a link:

http://msdn.microsoft.com/en-us/library/9f4t9t92(v=vs.90).aspx

I realize that this isn't what you asked for but perhaps it might solve your problem.
0 Kudos
PhilipBailey
New Contributor
Hi Richard,

That's excellent confirmation. Thank you. I've been using shared source control folders for several years and it works well. I just wanted to revisit whether it's possible to use separate assemblies. I guess not within a single process application.

Thanks for the "linked" project items MSDN tip. I've been using Visual Studio for years and didn't know about that. I will definitely try that approach.

Philip
0 Kudos