When you spend more time in C# than C/AL, and you still tell yourself and the world around you that you are developing for NAV, then this post is for you.
I already wrote a three-article series about “DLL hell” and how to resolve it, and in my last post in the series (http://vjeko.com/sorting-out-the-dll-hell-part-3-the-code) I delivered some code that help you take control of your .NET assemblies.
This time, I am delivering an updated solution, one that solves all the problems others, and myself, have encountered in the meantime.
So, fasten the seatbelt, and let’s embark on another .NET interoperability black belt ride.
First of all – a short disclaimer. On the face of this trick that this post is talking about, you could say “whadda heck, this is the same as the standard database deployment feature” – but you’d be wrong. The difference is huge, and over the next few posts I’ll spend some time to explain in what ways it is different specifically.
I know that at least a few of you have been impatient and asked for code and everything, so I’ve nicely put all this together and published it on GitHub: https://github.com/vjekob/NAV-Assembly-Resolver
So, what do we have there. First is, the Assembly Resolver assembly code. Many of you have asked about the “dll” to put into the Add-ins folder. You can take this C# solution, compile it and you get your assembly that you can put into the Add-ins folder for the development environment. You don’t need it for the service tier (at least not if you are on 2016).
These are the differences from the first version:
Now, if you run NAV 2016, this functionality has zero footprint on your NST, which makes it particularly useful for deployments in Managed Service – you don’t need to deploy anything to the NST, everything is contained in C/AL.
So, how does it work?
First – it checks whether the AssemblyResolver type is available, and if not, then it installs itself:
This “installs itself” does the following:
Then, it rechecks if it can load the assembly:
At this point, if everything is okay, NST will locate the assembly in the Add-ins table, and deploy that assembly from the database and dynamically load it. If something is not okay, you get a message about it, and the codeunit exits.
Everything else is already described.
Now, you may think again: what the heck – he is using database deployment and is providing a feature that’s purported to replace it.
As a matter of fact, yes.
Database deployment is – as I said earlier, and as I will show again – not working correctly. I can’t know for a fact exactly what it does at execution level, but I am sure I’ve been able to pretty accurately figure it out from its behavior, and having worked with .NET since 2000 when it was still in beta, you can take my word for it: it’s doing it all wrong. This little assembly that I provide here takes care of all the wrong in there, and fixes it.
The end result is this:
And the reason why I use database deployment is simple: I want to avoid any kind of deployment of assemblies to the file system. With this little trick (having a self-compilable self-deployable assembly) I take care of that. So, for your live environments, you only need the objects in the application database (which will include the assemblies you upload to the .NET Assembly table) and all of your .NET interop will nicely work, as if assemblies were deployed in the Add-ins folder.
One small limitation in multi-tenant environments is that the InstallResolverAssembly function will only execute successfully when ran from a session of a tenant mounted with “allow application database write” setting.
And last, but not least, this works in Managed Service – I had problems making the version that binds itself during the OnAfterCompanyOpen works, but if you avoid binding from there, and load it afterwards, then this works nice.
Good luck with this, and let me know if it makes your life easier.
The post Dynamically loading assemblies at runtime appeared first on Vjeko.com.