Shadow-copied assemblies and dynamic assembly loading

B

Barry Kelly

I'm designing an application framework which will, amongst other things,
live in an assembly hosted in the ASP.NET worker process, servicing
webservice requests.

Here's the scenario:

APPFX is our application framework assembly. It has no life of its own -
it's designed to provide components that are glued together by another, main
application assembly - let us call it APP. Thus, APP uses APPFX, and APP is
registered with ASP.NET as a handler (<httpHandlers> in web.config). This
means that ASP.NET shadow-copies APP and APPFX to different directories and
loads them up.

Now, APP isn't very interesting on its own - it's designed to load up an
application description from XML metadata, and from instructions in that XML
load up an arbitrary number of other assemblies, say PART_1..PART_N.

Here's the problem: there's a conflict between two different usage
scenarios:

1) APP uses PART_x.
-------------------
If APP uses PART_x, then ASP.NET will shadow-copy PART_x to some directory
and load it up. It will be already existing in the AppDomain. APPFX should
interpret a request for something PART_x as a request for something in the
in-memory PART_x.

2) PART_y is only mentioned in XML metadata.
--------------------------------------------
PART_y is not in the AppDomain, so APPFX needs to interpret a request to
PART_y as a request to load PART_y into the current AppDomain.

Questions:
----------

* If APPFX is to go down the ASP.NET route of shadow-copying, what strategy
should it use?

* How can APPFX hook into ASP.NET's shadow-copying algorithm?

* What method should APPFX use to determine if ASP.NET has already
shadow-copied and loaded the assembly (given that the XML metadata only has
the base name (e.g. 'part_z.dll') of the assembly)?

Currently the code is using the brutal hack of recursively searching for the
shadow-copied assembly in the root of the BIN directory of the shared web
folder.

Bear in mind that all these assemblies are currently in development at a
fairly early R&D prototype stage with no strong names.

-- Barry Kelly
Avaeon Solutions
 
S

Scott Allen

* If APPFX is to go down the ASP.NET route of shadow-copying, what strategy
should it use?

If APPFX is in the same application domain as the ASP.NET application
(and it sounds like it is), then APPFX doesn't need to do anything
special to use Shadow Copy. Shadow Copy is configured at the appdomain
level, and the ASP.NET runtime already has enabled ShadowCopy for any
assembly coming out of the bin subdirectory.
* How can APPFX hook into ASP.NET's shadow-copying algorithm?

Just by being in the same app domain. Assembly.LoadFile will use
shadow copy if so configured by the appdomain.
* What method should APPFX use to determine if ASP.NET has already
shadow-copied and loaded the assembly (given that the XML metadata only has
the base name (e.g. 'part_z.dll') of the assembly)?

There are all sorts of interesting details you can discover if you
look at the properties and methods of the AppDomain class.

AppDomain.CurrentDomain will give you a reference to the current
application domain your code lives in.
AppDomain.CurrentDomain.GetAssemblies() will give you an array of
loaded assemblies to iterate through, I'm sure you could inspect the
names and determine if a given assembly is loaded or not.

There are also some events you might be interested in, like
AssemblyLoad, and here is a high level overview of what an appdomain
is: http://odetocode.com/Articles/305.aspx

HTH,
 
B

Barry Kelly

Scott Allen said:
* If APPFX is to go down the ASP.NET route of shadow-copying, what
strategy
should it use?

If APPFX is in the same application domain as the ASP.NET application
(and it sounds like it is), then APPFX doesn't need to do anything
special to use Shadow Copy. [...]
* How can APPFX hook into ASP.NET's shadow-copying algorithm?

Just by being in the same app domain. Assembly.LoadFile will use
shadow copy if so configured by the appdomain.

Assembly.LoadFile expects a path. If you give it the path to the assembly
PART_x, two copies of PART_x end up in the AppDomain, one shadow-copied
version and one on the original path. The C# code
'typeof(PART_x.SomeTypeInPartX)' will return different objects of
incompatible type (i.e. not mutually assignable).
There are all sorts of interesting details you can discover if you
look at the properties and methods of the AppDomain class.

Sure. I've tried just about all of them. An interesting class of overloads
isn't a runner because of the requirement for a strong name, though.

-- Barry Kelly
Avaeon Solutions
 
S

Scott Allen

Sorry for the typo:

Assembly.LoadFrom will shadow copy an assembly.

Assembly.LoadFile will not.

Are you loading assemblies in the bin directory? The runtime will load
those automatically.

I'm also not sure what you are seeing with the typeof operator - it
determines what to do at compile time and not during execution.

--
Scott
http://www.OdeToCode.com/blogs/scott/

Scott Allen said:
* If APPFX is to go down the ASP.NET route of shadow-copying, what
strategy
should it use?

If APPFX is in the same application domain as the ASP.NET application
(and it sounds like it is), then APPFX doesn't need to do anything
special to use Shadow Copy. [...]
* How can APPFX hook into ASP.NET's shadow-copying algorithm?

Just by being in the same app domain. Assembly.LoadFile will use
shadow copy if so configured by the appdomain.

Assembly.LoadFile expects a path. If you give it the path to the assembly
PART_x, two copies of PART_x end up in the AppDomain, one shadow-copied
version and one on the original path. The C# code
'typeof(PART_x.SomeTypeInPartX)' will return different objects of
incompatible type (i.e. not mutually assignable).
There are all sorts of interesting details you can discover if you
look at the properties and methods of the AppDomain class.

Sure. I've tried just about all of them. An interesting class of overloads
isn't a runner because of the requirement for a strong name, though.

-- Barry Kelly
Avaeon Solutions
 
B

Barry Kelly

Scott Allen said:
Sorry for the typo:

Assembly.LoadFrom will shadow copy an assembly.
Assembly.LoadFile will not.

I'll step through the problem again, and try to tie it down to a simple case
of where it fails.
Are you loading assemblies in the bin directory? The runtime will load
those automatically.

It loads some assemblies, but not all of them.
I'm also not sure what you are seeing with the typeof operator - it
determines what to do at compile time and not during execution.

It returns an instance of an object. When called from two different
assemblies which both import a third assembly, on a type declared in the
third assembly, where the third assembly may (or may not) be loaded
dynamically by the first two assemblies, it returns different instances and
the types aren't compatible with one another.

I think that's accurate; it's been a fortnight or so since I saw the
problem. As I said, I'll try to track it down again.

-- Barry Kelly
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top