Поделиться через


Deploying .Net Assemblies with native dependencies

I know there are a few articles and posts out there concerning deploying .Net assemblies and how to service them once they are out in the field, but I have not seen one that offers a method of deploying SDK type assemblies with native dependencies, meaning just DLL's with vendors developing against them.  If you know of any send them my way.  Some background:

1.  Keep all assemblies in the local application directory, private assemblies

Basically the vendor would have to deploy 3rd party SDK DLL's with their app.  This would make it very difficult to service the DLL's once it's in the field as there could be countless private assemblies sitting on the same machine in different folders, remind anyone of CRT redist issues?  This would also put the burden on vendors to keep the private 3rd party DLL's up-to-date by continuously updating their application when the update needs to be done by the SDK vendor.

2.  GAC all your DLL's

This is a good alternative.  This is how the .Net framework works; each .Net assembly used in the CLR is GAC'ed so no one have to re-deploy the runtime DLL's once the client has the framework installed.  Servicing is easy, they can have publisher policies to redirect binding to newer versions of the DLL's, this would be the ideal situation, or the app vendor can use app.config files to redirect binding to newer versions.  But what about native dll dependencies?

GAC Phobia 
https://blogs.msdn.com/alanshi/archive/2004/03/28/100765.aspx

3.  What if you have native dependencies?

In this scenario, you can create a multifile assembly, meaning .Net netmodules.  This way your native assembly will be linked into the managed code so when you install the assembly into the GAC all the modules and the native DLL's will be copied into the GAC under it's own directory so minimizing probing issues.  Servicing of native DLL's would be easy as you can rebuild and redeploy the new .Net assembly and redirect with publisher policy or app.config files.  The other alternative is to wrap the native DLL's into it's own .Net assembly.  This way you can keep the managed assembly separate from the native code and servicing can be more modular.

There are a couple of issues with this, first the native DLL is platform specific.  Meaning when you build a native DLL it's either x86 or x64 and .Net builds with "AnyCPU" configuration as default which is processor agnostic.  So when you link in a native DLL, you will get this al.exe error AL1070, so building with /platform:x86 for all netmodules is required.  The other problem is DLL bloat.  This would load all the code modules into the process even if it's not being used.  So some perf hit here if perf is relevant.  Also when servicing this assembly a rebuild of the modules are required.  This is different from GAC'ing all DLL's above is because the probing path for native dependency will be the standard probing path of the application so the native DLL would have to sit in the app's directory or maybe system32 which is not a good location.  This method resolves the issue with servicing native DLL's that has .Net dependencies. 

csc.exe /target:module GACDLL.cs /addmodule:nongac.netmodule /platform:x86     :building the netmodule with x86 as targeted platform

al.exe /keyf:key.snk /link:nativedll.dll gacdll.netmodule /target:lib /out:test.dll /platform:x86     :linking in native dll targeting the whole dll as x86