Let me tell you right away if you need to read this post at all. If you never wrote a single .NET class library intended to be used as a .NET interoperability assembly from C/AL, or if you never ever deployed a .dll file into the Add-ins folder of either Service or RoleTailored Client, then you probably don’t want to read this post.
Good, since you are still reading it means that you either deployed your own or somebody else’s .NET stuff into NAV’s client or server’s Add-ins folders. If you ever did so, you probably did not enjoy the experience too much. If you did enjoy the experience, maybe you should not read any further either.
Even better! Since you are still here it means that you didn’t enjoy deploying assemblies. Let me break some good news – all your problems are now gone! And I am not talking NAV 2016, I am talking NAV 2013 and anything newer.
There are several problems with deploying assemblies.
First, if the assembly is in use, you must close the client, or the restart the service tier. That’s not always possible because people might just be needing the server at that very moment.
Second, if you use client-side assemblies, you have to make sure they are available on every single machine. This is easier said than done. Server can take care of it as long as it’s NAV 2015 or newer, but it does not do an overly good job at this. The assembly is copied once, and if you need to redeploy you must either version it up (which is a double-edged sword during development) or you need to dig through user’s file system to locate and delete assemblies to trigger redeployment. You can also use ClickOnce deployments, but you have to play around with configuration and you will experience pain when it comes to properly versioning.
Third, if you don’t version your assemblies – it’s gonna be a mess during development when you change things. If you do version your assemblies – it’s still gonna be a mess during development. Redeploying assemblies and making sure all of them are present exactly where they need to be present will cost you time.
And last, but not least – when moving your application to another server, you must redeploy the assemblies, again making sure everything is deployed properly.
To make it worse, the more assemblies you have to handle, the more fun you’ll have juggling around with them.
Now, you may say: I don’t care, because in NAV 2016 there is automatic deployment of any kind of assemblies from the database to both client and server. This solves the problem, because assemblies are stored in the database and are deployed to whomever needs them, whenever.
Well, there are three problems with this database assembly deployment.
First, it only works under NAV 2016. If you are still running anything older, and chances are you are, then this new feature won’t help you.
And third – and here I’ll have to be brutally blunt – even when Microsoft fixes the current bugs with this feature, the whole Add-in table and deployment features are just terribly badly designed.
So, let me hang around this latest claim for a bit.
When control add-ins were introduced, back in 2009 SP1, whoever designed the feature wasn’t thinking much of possible consequences of expansion of NAV stack to their design decisions. Namely – the problem is add-in identification.
To identify a control add-in, you need two pieces of information Control Add-in Name, and public key token. Control Add-in Name comes from the ControlAddInExport attribute of the class you are exposing, and public key token comes from the assembly strong name signature.
There is an immediate problem – the (Client) Add-in table also has the version field. This field is a part of the key, but it’s not the part of the control add-in identification in the Development Environment. If you have two assemblies with the same name and public key token, just with different version number, how can you tell which one will be picked by the client? I can’t.
But still, we could live with this, using a single version at a time can go long way. Not the best solution, but works.
Again – for client add-ins it comes from the ControlAddInExport attribute, and it’s easy. But what to do with .NET assemblies? Documentation says you must name your control add-in exactly as the assembly is named. Good, but what about culture? Yes, we can argue whether or not having culture-specific assemblies for general purpose, but hey – it’s sometimes not you who decides.
In any case, any identification which ignores the .NET way of identifying .NET assemblies – and that is through fully qualified assembly name – is just wrong. Why reinventing a wheel, and then come up with a bad wheel, when .NET already has built-in way of uniquely identifying assemblies?
Okay – now that I have laid out the problem, is there a solution for automatically deploying .NET interoperability assemblies? Yes, of course there is. I wouldn’t be writing this long post if there weren’t one.
So, stay tuned for the next post, in which I’ll explain how you can pull some .NET magic to enable simple and powerful management of external .NET assemblies on which your solution might depend.