Are you developing .NET assemblies intended to be used from C/AL? If so, then you must have realized that keeping proper track of them and managing them on the server (or client, in case you still do that) is not a simple affair.
Assemblies in .NET are identified through their fully qualified name, and that’s how NAV tells one assembly from another, as well. Fully qualified name contains the assembly name, version, public key token, and culture information. A good practice in .NET development is that when you update assembly’s functionality, you also version that assembly up, essentially resulting in a completely new assembly, which doesn’t have the same fully qualified name as the older version did.
However, this kind of change is a breaking change. In .NET, it’s not all that breaking – you simply reference the new version and this applies to whole project. Or whole solution, depending on how you configure the MSBuild behavior.
But in NAV, it’s a completely different story. Versioning an assembly up is a very breaking change. In NAV, we cannot simply replace a reference once, and then have it apply to the whole database. Unfortunately, we have to update a reference on every single variable, and if you ever had to do it, chances are you don’t keep any happy memories about this experience.
That’s why NAV developers, when working in .NET, prefer not versioning up. And that’s wrong.
There are no absolutely authoritative rules around when exactly should you version your assembly up (or maybe there are, and I am just unaware of them because I am lazy to look them up and I am writing this post offline on a plane), but a good practice is to version up any time that you introduce a compile-time breaking change. For example, when you change signatures of existing methods, or remove existing types or members, it’s a good idea to version up. Your existing code won’t compile anyway, so by versioning up you clearly indicate that there is something new about the existing assembly, and that it must now be addressed with changes in the code.
Another good practice is to version up on any change after the assembly has seen some production runtime out there. At this moment on, it would be very confusing to keep the same version number and release a hotfix that modifies the behavior of the assembly without compromising the compile-time behavior. At this point, you should version up and deploy the new set of NAV objects as well.
I frequently version up. Any time a version goes from development to staging, I version up so that when stuff is released, and there was change in .NET layer, it’ll be a new version. And you can imagine, I write a lot of .NET stuff, so I have tons of DotNet variables all over the place – how do I change them?
Easy. I remove all instances of the up-versioned assembly from the NST and GAC, deploy the new version, and then compile the NAV application to get a list of objects that fail to compile due to missing assembly. Of course, you must do it on a clean, stable build. Then, I export the non-compiled objects as a text file, and then do a search-replace. Then I import the objects back, recompile, and at this stage I am usually good to go (unless I accidentally referenced up something I shouldn’t have).
It typically takes five minutes, and I am pretty sure it can be automated by PowerShell.
Now, one more practice that I’d like give my thoughts about is maintaining the assemblies in the Add-ins folder. My opinion is that GAC is not the right place to install assemblies. Assemblies belong to Add-ins folder, or to database (in 2016, or 2013+ if you are using my assembly resolution trick), but not to GAC. GAC is okayish with development, but not for production. Yes, it’s easier to redeploy to GAC, than to Add-ins, because redeploying to Add-ins would require you to stop the service tier. But remember – you don’t need to stop. You’ll only be updating the NST when you are versioning up, and at that point, you may want to actually create a folder for new version, that also includes the version number in the folder name. That way, you never have to stop the NST, and you can deploy new version without a hassle.
One thing that you should definitely not do – and I’ve seen people do it – is rename assemblies from .dll into something like .old. This is especially dangerous if you don’t version up your assemblies. You may think that this way you have a backup of the older assembly when you deploy the new one, but it won’t be that simple.
When NST is resolving assemblies from the Add-ins folder, it’s not looking only for the .dll files – it’s opening all the files and first figuring out if the file is an assembly or not, regardless of the extension. Renaming your assembly from .dll into something else won’t exclude it from being loaded at the point when NST is trying to figure out which .dll file hosts which assembly. Once I’ve seen this in production, and it has taken half the team half a day to figure out that the reason why NAV was still running the old version of something, even though the old dll was clearly not there, and there clearly way new dll in the folder, and yet, NAV was stubbornly loading the old version.
Save yourselves from those troubles. Version assemblies up, store them in version-based subfolders, and update references using text files, and you will forget about most of assembly deployment and maintenance headaches you had earlier.