A development team I work with distributes a .NET assembly (implemented in MC++) that in turn depends on native DLLs. This assembly is consumed by a few teams that develop servers that perform some business that depends on this assembly. These applicative teams now wish to run their applications in a single process by creating several appdomains. The catch is that the various applications depend on different versions of this same assembly, and thus on different versions of the native DLLs. From initial tests we performed we know that the first appdomain to call our assembly will get its version of the native DLLs loaded. When the second appdomain loads our assembly (but a different version), it will load the second version of the managed assembly, but will use the native DLLs already loaded for the first appdomain (which may not be compatible with the assembly loaded by the second appdomain). Is there any way around this? For example, can I create a multi file assembly referencing the native DLLs, so that each appdoain gets its own version? If yes – how? If not, any other ideas?
> The catch is that the various applications depend on different > versions of this same assembly, and thus on different versions of the > native DLLs.
Sorry, but you will not succeed this way.
An unmanaged module knowns nothing about AppDomains. The boundaries or unmanaged Code still is at process-level, regardless if there are loaded managed modules or if the Process has been started by an managed exe.
With LoadLibrary / GetProcAddress (eg. by providing different names for each version), it may be possible, but I won't recommend it to you.
You may use different processes instead of AppDomains.
Thank you for the quick reply. You confirmed our suspicion. We actually use the LoadLibrary approach for a few DLLs, and this works because those DLLs have a very limited C style API - it would not work with what I have at hand here. The architecture suggesting the use of a single process hosting multiple AppDomains is meant to address load balancing issues, and better utilization of resources. I have no control over this decision. My backup plan is to deliver several sets of native DLLs - renamed according to the appropriate client applications - I will create them by copying – so they are exactly identiicle. Then I will build several versions of my assembly, by linking with a different set of renamed DLLs. Thus the client will be able to use multiple versions of the same native DLL, as each assembly will link with a version of the native DLL with a different name.
To illustrate:
Assuming we are working on version 1.1 I build NativeDLL.dll (V 1.1). I copy the result so I have NativeDLLForAppA.dll (V 1.1) and NativeDLLForAppB.dll (V 1.1).
Then I build MyAssembly.dll that links with NativeDLLForAppA.dll, and another MyAssembly.dll that links with NativeDLLForAppB.dll.
This is done per version.
Now Assume I have released V1.1 and V1.2. And both versions are to be consumed in different AppDomains in the same process. The assemblies will not be a problem – as the code is managed – the exact reference will be loaded. The native DLLs will not be a problem, as each app uses an assembly that links with a distinct (renamed) set of DLLs.
Not very nice – but should do the trick in lack of a better solution.
> > The catch is that the various applications depend on different > > versions of this same assembly, and thus on different versions of the > > native DLLs.
> Sorry, but you will not succeed this way.
> An unmanaged module knowns nothing about AppDomains. The boundaries or > unmanaged Code still is at process-level, regardless if there are loaded > managed modules or if the Process has been started by an managed exe.
> With LoadLibrary / GetProcAddress (eg. by providing different names for each > version), it may be possible, but I won't recommend it to you.
> You may use different processes instead of AppDomains.
> My backup plan is to deliver several sets of native DLLs - renamed according > to the appropriate client applications - I will create them by copying – so > they are exactly identiicle. Then I will build several versions of my > assembly, by linking with a different set of renamed DLLs. Thus the client > will be able to use multiple versions of the same native DLL, as each > assembly will link with a version of the native DLL with a different name.
If the dlls are identical, then you should be able to re-use the same copy across ADs. If they are not identical, then adding the version number in the name of the file makes sense.
You also want to make sure that your native dlls do not depend on any process-global resources, or else your native dlls may conflict with each other.
>> My backup plan is to deliver several sets of native DLLs - renamed >> according >> to the appropriate client applications - I will create them by copying – >> so >> they are exactly identiicle. Then I will build several versions of my >> assembly, by linking with a different set of renamed DLLs. Thus the >> client >> will be able to use multiple versions of the same native DLL, as each >> assembly will link with a version of the native DLL with a different >> name.
> If the dlls are identical, then you should be able to re-use the same > copy across ADs. If they are not identical, then adding the version > number in the name of the file makes sense.
> You also want to make sure that your native dlls do not depend on any > process-global resources, or else your native dlls may conflict with > each other.
And if the DLLs import another DLL that uses global data, you'll still end up with data sharing across app-domains no matter what you do (short of recompiling all dependencies with /clr and app-domain awareness).
> thanks -- rich
> __________ Information from ESET NOD32 Antivirus, version of virus > signature database 4512 (20091015) __________
> The message was checked by ESET NOD32 Antivirus.
>> My backup plan is to deliver several sets of native DLLs - renamed >> according >> to the appropriate client applications - I will create them by copying – >> so >> they are exactly identiicle. Then I will build several versions of my >> assembly, by linking with a different set of renamed DLLs. Thus the >> client >> will be able to use multiple versions of the same native DLL, as each >> assembly will link with a version of the native DLL with a different >> name.
> If the dlls are identical, then you should be able to re-use the same > copy across ADs. If they are not identical, then adding the version > number in the name of the file makes sense.
> You also want to make sure that your native dlls do not depend on any > process-global resources, or else your native dlls may conflict with > each other.
oh gee, you already said what I did.... I was thinking of your statement in terms of named kernel objects, but those are session-global, not process-global.
> thanks -- rich
> __________ Information from ESET NOD32 Antivirus, version of virus > signature database 4512 (20091015) __________
> The message was checked by ESET NOD32 Antivirus.