Thanks for the time you spent on this Mike.
I think we might try the File.Exists approach.
I'll let you know if this works.

Charles.

-----Original Message-----
From: Discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED] On Behalf Of Mike Woodring
Sent: 07 July 2006 16:53
To: [email protected]
Subject: Re: [ADVANCED-DOTNET] Assembly.LoadFrom failing in .NET 2.0

> It seems that the fact that the first Assembly.LoadFrom()
> call failed is
> cached in the current process and any subsequent calls to
> load the same DLL
> automatically fail.
>
> Is this a change in .NET 2.0?

Apparently so, although I can't find it documented anywhere after a cursory
look.  But I can reproduce the same behavior you're seeing with LoadFrom.
Personally, I'd be inclined to call it a bug.  Caching a failure like that
seems pretty unhelpful, although I'd be curious to hear from someone on the
Fusion team if good reasons exist.

> Is there a way around this?

One idea would be to just use File.Exists instead of Assembly.LoadFrom to
determine if you need to generate the assembly.  That way you avoid calling
LoadFrom when you know it's doomed to failure.  This is arguably the
simplest.

Another idea is to leverage the fact that Assembly.Load doesn't exhibit the
same failure-caching behavior that LoadFrom is exhibiting.  This would
involve switching from calling
Assembly.LoadFrom(targetdir\assembly_file_name) to
Assembly.Load(assembly_name).  Assuming that targetdir isn't equal to your
APPBASE, then this will cause Assembly.Load to fail.  But ahead of time, you
can register for the AppDomain.AssemblyResolve event, which will be fired
when Assembly.Load fails.  You can then move your dll generation code to
your event handler.  Something like:

// Somewhere during app initialization.
//
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolutionFailed;

// Where you were previously calling
// Assembly.LoadFrom(targetdir\assembly_file_name), which will
// fail if you haven't yet generated the assembly.
//
Assembly asm = Assembly.Load(simple_assembly_name);

// Then in your AssemblyResolve event handler,
// handle your codegen.
//
Assembly OnAssemblyResolutionFailed(object sender, ResolveEventArgs args)
{
  if( args.Name is a DLL you need to generate )
  {
    Generate DLL and save to hard disk
    return(CompilerResults.CompiledAssembly);
  }

  return(null);
}

I mocked up this 2nd approach, and it works fine, although it's a bit more
obfuscated than just using File.Exists to avoid calling LoadFrom when you
know it's doomed.

-Mike
Bear Canyon Consulting LLC
http://www.bearcanyon.com
http://www.pluralsight.com/mike

===================================
This list is hosted by DevelopMentor(r)  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

________________________________________________________________________
This e-mail has been scanned for all viruses by MessageLabs.
________________________________________________________________________

________________________________________________________________________
This e-mail has been scanned for all viruses by MessageLabs.
________________________________________________________________________

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to