Deserialize obj which assembly is not loaded

Arokh

Centurion
Joined
Apr 11, 2006
Messages
124
Hi,
In my program I dynamically create an instance of a class (from an external dll),
which is responsible storing and loading data with serialization.

The serialization is working fine, but the deserialization doesn't work,
since the assembly where the class is located is not loaded.
(At least that is what the error message tells me:
Unable to find assembly 'AT_Memory, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.)

How can I fix this without referencing the assemblies at design time?

If needed, I'll try to make a short code example.
 
The originating assembly needs to be loaded in memory to deserialize an object, which means if it isn't referenced at design time it must be loaded dynamically, probably using the Assembly.LoadFile() method.
 
I'm using Assembly.LoadFile() to dynamically create the instance of the class I want to use.
But it is still throwing the errors.

I've managed to shorten the code quite a bit,
but to much to post it in the thread.

I've attached a solution which shows the problem I'm having.
Start it and it immediately throws the error.
 

Attachments

Last edited:
OK after some experimenting and googling,
I've got it to work:

After loading the assembly with
asm = Assembly.LoadFrom(dllPath);
the event AssemblyResolve is called in AppDomain.CurrentDomain.

The handler for it:
[CSharp]static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
return Assembly.LoadFrom(dllPath);
}[/CSharp]

Through I think it is a bit odd, that it works that way.
Is there a more elegant way?

Using Assembly.LoadFrom(dllPath); twice doesn't seem right.
 
If you don't pre-load the assembly before the CurrentDomain.AssemblyResolve event, will an exception be thrown? If so, what if you simply store a reference to the DLL and then in the CurrentDomain.AssemblyResolve event return the cached reference to the loaded assembly, rather that calling Assembly.LoadFrom() again. Either way, I doubt the assembly is being loaded more than once. I would hope that the second time around it would return a reference to the already-loaded assembly.
 
Sorry for replying so late.
(I don't know if I understood you correctly)

Since I need to create an instance of a class from the (not yet loaded) assembly,
the "pre-loading" of it comes with it.

I can't store the reference since those DLLs will be plugins which the user can write for my application.
 
When you load the plug-in DLL you should be able to store a reference to the loaded Assembly object, which you should then be able to return later within the CurrentDomain_AssemblyResolve() method. (This wouldn't entail referencing the assembly at design-time.) In other words,
Code:
Assembly pluginAssembly;

[COLOR="Blue"]public void[/COLOR] LoadSomePlugin(){
    pluginAssembly = Assembly.LoadFrom(someFilename);
    [COLOR="Green"]// Create objects, do whatever[/COLOR]

[COLOR="Blue"]static [/COLOR]Assembly CurrentDomain_AssemblyResolve([COLOR="Blue"]object [/COLOR]sender, ResolveEventArgs args) {
    [COLOR="Blue"]return [/COLOR]pluginAssembly;
}
 
Jep works nicely, at least it looks much better than loading it twice.

I'm still a bit puzzled as to why the event AssemblyResolve is fired to begin with.
It looks random to me because at first the event was fired for most of the assemblies I load,
now it fires three times for one module.

OK I guess I understand why three times (three modules want an instance of a class from that loaded assembly),
but there is alot more loading going on.
So why doesn't the event fire for the other ones?
 
Back
Top