WebServicesProxy - DLL's cached in different locations server side??

WebServicesProxy - DLL's cached in different locations server side??

Old forum URL: forums.lhotka.net/forums/t/6200.aspx


rsbaker0 posted on Monday, January 19, 2009

I have something of a chicken-versus-egg problem that I thought I had solved by putting the name of the needed assembly into my config file as a setting and then dynamically loading it if needed.

At first I tried leaving the assembly .DLL name unqualified, and when that didn't work I pre-pended it with the same directory as the currently executing assembly. After all, they are all in the same BIN directory in my web service virtual directory, right?

Well, it appears that ASP.NET has cached the files elsewhere and each .DLL from my BIN directory has been put into an individual directory. Here is the error message I get:

Could not load file or assembly 'file:///c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\webservicename\75827fe6\6415201f\assembly\dl3\0b280d47\273ca2cd_6c7ac901\APPDATA.DLL'

Has anyone run into anything like this before? How can you dynamically resolve an assembly on the server side of the data portal if ASP.NET is running things from wherever it chooses?

(I'm executing a CommandBase derived command and need something from another dynamically loaded assembly, if you are curious. All is well when the application starts normally, but if IIS is bounced, then the other assembly may no longer be loaded when the command is executed)

EDIT: Here is some more detail. It turns out I can load a type in the assembly by it's fully qualified name to force the same assembly to load. It seems weird, but is this the "right" way to do this? I could just put the type name in the config file rather than the assembly name.

tmg4340 replied on Monday, January 19, 2009

ASP.NET isn't exactly running things from "wherever it chooses".  But this is a feature of ASP.NET called shadow-copying.  It's done to allow you to update the website without having to stop IIS.  ASP.NET copies the site's assemblies into temp directories under the "Temporary ASP.NET Files" directory and then monitors for changes to the files, at which point they are re-loaded so the new changes take effect on the next request.  The temp directories should be part of the AppDomain's probe, so this is all supposed to be transparent to you.

Having said that, I am not sure you'll be able to get this to consistently work in ASP.NET.  Aside from the directory issue you've run into (and there isn't any way around it that I know of), .NET's reflection capabilities from an ASP.NET site are pretty limited by default.  So even if you could find the assembly, you may not have the permissions to create an instance of your object and execute it.  And on top of all this, since the DLL you're referencing isn't explicitly referenced by the project, ASP.NET may not track it appropriately.

How are you loading your assembly?

- Scott

rsbaker0 replied on Monday, January 19, 2009

tmg4340:

...

Having said that, I am not sure you'll be able to get this to consistently work in ASP.NET.  Aside from the directory issue you've run into (and there isn't any way around it that I know of), .NET's reflection capabilities from an ASP.NET site are pretty limited by default.  So even if you could find the assembly, you may not have the permissions to create an instance of your object and execute it.  And on top of all this, since the DLL you're referencing isn't explicitly referenced by the project, ASP.NET may not track it appropriately.

How are you loading your assembly?

- Scott

Thanks, that is helpful information.

Well, I'm an admitted newbie to .NET's assembly management, so I naively tried to construct what I thought was the correct location and used Assembly.LoadFrom().

I also tried LoadWithPartialName(), but I still had the full file name (not directory) so that didn't work.

Interestingly, I found out I can load a Type from the assembly given it's name and I can access the assembly that way.

You mentioned the AppDomain, so does this mean that I could just somehow search the AppDomain for the assembly?

 

RockfordLhotka replied on Monday, January 19, 2009

It is true that loading assemblies in ASP.NET can be challenging.

Your best bet is to use Type.GetType() to load the type - that'll automatically pick up the type from any assembly in the \bin directory (or shadow directory, or whatever is current).

In other words, try to avoid manually loading assemblies, and just let the type loader do the work for you.

In general, due to security limitations, you'll only be able to get at assemblies from the \bin directory anyway, so this technique is probably best.

rsbaker0 replied on Monday, January 19, 2009

OK, I'll go the Type route. And thanks for the quick reply...

Copyright (c) Marimer LLC