views:

434

answers:

2

My ASP.NET application utilises a "Modules" system by using Type.GetType() on a fully-qualified string reference, and instantiating an object of that type, as you do.

However, recently it has been throwing exceptions at not being able to find the types - but only occasionally. I haven't been able to replicate at will, but it usually happens after a simple change to something non-bin-related like a Master Page or ASCX markup. It doesn't sort itself until I rebuild the site or restart IIS. Making a change to the web.config does not fix it.

Adding an explicit reference to the assembly in the web.config rather than making hoping it gets found sitting in the bin directory reduces the occurrence of the issue, but does not prevent it from happening entirely. Somehow, something somewhere is thinking it's a good idea to remove my assembly.

I've debugged into where it fails to find the type and right enough, despite being there on the previous page load, the assembly seems to disappear out of the Thread.GetDomain().GetAssemblies(). Clearly, I can't risk this happening when the application is live so I manually called Assembly.LoadAssembly() on the DLL I knew it needed just to see if it would be worth creating a method that would try to locate the assembly. This didn't work either, as it then threw the following error when I tried to use the class:

[A]xxx.Modules.CustomCaseStudy cannot be cast to [B]xxx.Modules.CustomCaseStudy. Type A originates from 'xxx.Modules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location 'C:\Development\xxx\xxx.Web\bin\xxx.Modules.dll'. Type B originates from 'xxx.Modules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\fff474e0\8c6aec7e\assembly\dl3\325b4335\009dbd67_b2fbc901\xxx.Modules.DLL'.

All the while, the required DLL is sitting in the bin folder, waiting - nay, begging to be used, not to mention the explicit reference in the web.config.

Any information in tracking down the culprit, or even as a last resort how to load that assembly into the "Default" context would be greatly appreciated!

A: 
  1. Thread.GetDomain().GetAssemblies() does not return all of the assembly's in your "bin" folder. It only returns the assemblies that have been used so far. This isn't what you want. You always need to call Assembly.LoadAssembly().

  2. If you want to dynamically load your classes then you shouldn't use strongly typed references to them in your other code. That's why you are gettng the "cannot be cast" exception. One way around this is to define an interface that all of your modules implement. Then whenever you dynamically load one of your "module" classes, return it as an instance of this interface. Something like...

public IModule GetModule( string className )
{
     // Load the assembly
     // Find the type
     // Call CreateInstance
     // Cast the return value as "IModule" and return it
}
David
Thanks David, but my issue isn't loading the assembly; the site will work fine for ages, and then some assemblies will be unloaded and not reinstated.
tags2k
+1  A: 

After having added the line:

<add assembly="*"/>

to the web.config and used the site for over two weeks, I haven't run into this problem again. I want it to load everything in the bin anyway, so it's not as dirty a brute-force solution as it may look!

tags2k