Assembly.Load problems

  • Thread starter Thread starter Razzie
  • Start date Start date
R

Razzie

Hey all,

I'm working on this project where I'm dynamically loading an assembly.
Basically what I want is that I can just replace my old dll file with a new
one without having to do anything else.
So to test this, I did the following: I temporarily tested it by saving my
dll file in C:\, so let's say I have C:\dynamic.dll.

I have created a winforms application with a simple button that calls the
method with Assembly.Load, which you can see here (notice a lot of debug
statement to try and find the problem):

public MyClass getClass(Domain domain)
{
AssemblyName assemblyName = new AssemblyName();
Assembly classAssembly = null;
try
{
assemblyName.CodeBase = @"C:\dynamic.dll";
System.Diagnostics.Debug.WriteLine("Codebase for dynamic dll set to: "
+ assemblyName.CodeBase);
classAssembly = Assembly.Load(assemblyName);
System.Diagnostics.Debug.WriteLine("Loaded dynamic.dll, returning
instance...");
return (MyClass)classAssembly .CreateInstance("MyClass2", false,
System.Reflection.BindingFlags.CreateInstance, null, null, null, new
Object[]{domain});
}
catch(Exception ex) {
System.Diagnostics.Debug.WriteLine("Exception: " + ex.Message); }
finally {
classAssembly = null; assemblyName =
null;System.Diagnostics.Debug.WriteLine("Cleaning up"); }
return null;
}

So, now comes the problem. When I test this the first time, all is well. All
debug statements are printed and my output furthermore shows ''test.exe':
Loaded 'c:\dynamic.dll', Symbols loaded.' to show it actually loaded the
assembly.

However when I rename my dynamic.dll to bogus.dll and click the button again
(without closing the application) it won't throw an exception 'dynamic.dll
not found' or something, which I was expecting. It does show all debug
statements again, but nothing else. I first thought it was still in memory
or something, therefor I added the try-catch-finally block in my getClass
method and set my objects to null (but as I was expecting, that didn't
help).

So, is there more to this then meets the eye? Can I / Do I have to unload
the assembly somehow? Why doesn't it give the error when renaming my dll so
it shouldn't be found?

Thanks! Regards,

Razzie
 
Hey Razzie,

Once you've loaded an assembly to the AppDomain, you cannot unload the
assembly - you have to unload the entire domain.
Therefore, if you need to reload an assembly 'on the fly', you have to use a
dedicated AppDomain. I have gone through all this hell while working on
X-Unity, so if you are stuck with some problem - post it here and hopefully
I notice your message and reply :-)
 
'This hell'? Lol that sounds like it may be too much work for my project!
Anyway, I'll sure take a look at it as soon as I can. Thanks!

Dmitriy Lapshin said:
Hey Razzie,

Once you've loaded an assembly to the AppDomain, you cannot unload the
assembly - you have to unload the entire domain.
Therefore, if you need to reload an assembly 'on the fly', you have to use
a dedicated AppDomain. I have gone through all this hell while working on
X-Unity, so if you are stuck with some problem - post it here and
hopefully I notice your message and reply :-)

--
Sincerely,
Dmitriy Lapshin [C# / .NET MVP]
Bring the power of unit testing to the VS .NET IDE today!
http://www.x-unity.net/teststudio.aspx

Razzie said:
Hey all,

I'm working on this project where I'm dynamically loading an assembly.
Basically what I want is that I can just replace my old dll file with a
new one without having to do anything else.
So to test this, I did the following: I temporarily tested it by saving
my dll file in C:\, so let's say I have C:\dynamic.dll.

I have created a winforms application with a simple button that calls the
method with Assembly.Load, which you can see here (notice a lot of debug
statement to try and find the problem):

public MyClass getClass(Domain domain)
{
AssemblyName assemblyName = new AssemblyName();
Assembly classAssembly = null;
try
{
assemblyName.CodeBase = @"C:\dynamic.dll";
System.Diagnostics.Debug.WriteLine("Codebase for dynamic dll set to:
" + assemblyName.CodeBase);
classAssembly = Assembly.Load(assemblyName);
System.Diagnostics.Debug.WriteLine("Loaded dynamic.dll, returning
instance...");
return (MyClass)classAssembly .CreateInstance("MyClass2", false,
System.Reflection.BindingFlags.CreateInstance, null, null, null, new
Object[]{domain});
}
catch(Exception ex) {
System.Diagnostics.Debug.WriteLine("Exception: " + ex.Message); }
finally {
classAssembly = null; assemblyName =
null;System.Diagnostics.Debug.WriteLine("Cleaning up"); }
return null;
}

So, now comes the problem. When I test this the first time, all is well.
All debug statements are printed and my output furthermore shows
''test.exe': Loaded 'c:\dynamic.dll', Symbols loaded.' to show it
actually loaded the assembly.

However when I rename my dynamic.dll to bogus.dll and click the button
again (without closing the application) it won't throw an exception
'dynamic.dll not found' or something, which I was expecting. It does show
all debug statements again, but nothing else. I first thought it was
still in memory or something, therefor I added the try-catch-finally
block in my getClass method and set my objects to null (but as I was
expecting, that didn't help).

So, is there more to this then meets the eye? Can I / Do I have to unload
the assembly somehow? Why doesn't it give the error when renaming my dll
so it shouldn't be found?

Thanks! Regards,

Razzie
 
Back
Top