I'm currently working on project for the .NET Compact Framework which uses DotNetZip for reading ZIP-files. The project is split into two parts. One platform-independent library which should be available for both, a CF project and a desktop project. This common library contains the code for extracting ZIP-files. The problem is that there are two different DLLs of the DotNetZip library, one for .NET CF and one for the .NET Desktop Framework. It's not possible to use the CF version of the library on a Desktop Framework and vice versa but they share the same interface.
How do I organize my projects in Visual Studio to be able to use the common zip-code and dynamically load the appropriate DLL (which then is used by the zip-code)? It should also be possible to execute the CF application on a PC so is there a way to choose the DLL at runtime?
UPDATE:
A technically unsupported but working solution is to p/Invoke LoadLibrary and specifically load the correct DLL early in the process. All managed and p/Invoke'd libraries are loaded "as needed". The CLR will load them for you when you invoke a method that depends on one of the types in that assembly (note: this is the "unsupported" part; this is not documented and may change in a future CLR version).
The approach works because if an assembly is loaded via LoadLibrary
, it's "found" by the CLR loader and the runtime will not attempt to load it again. We used this trick on CF to pre-load assemblies before doing much memory allocation to avoid out-of-memory situations.
So, you should be able to do:
public static void Main()
{
LoadCorrectDLLs();
// .NET will ensure DotNetZip is loaded at this point.
MethodInThisAssembly();
}
public static void MethodInThisAssembly()
{
// Since MethodInThisAssembly uses DotNetZip,
// its assembly will get loaded immediately before this method is called.
IDotNetZipInterface x = null;
...
}
public static void LoadCorrectDLLs()
{
// p/Invoke LoadLibrary to load the correct version of DotNetZip.
}
Note that the following will not work:
public static void Main()
{
LoadCorrectDLLs();
// This line would force DotNetZip to get loaded before Main() is called
IDotNetZipInterface x = null;
}
Old answer; works on desktop framework only:
One trick is to place them in directories that won't be found during DLL loading (e.g., different subdirectories of your executable's directory) and handle AppDomain.AssemblyResove. David Morton has a decent write-up on his blog.