If overrides are not getting called, then is a sign that the runtime seeing 
that that the virtual method takes a different ContainerBuilder type (ie 3.5) 
to the override (4.0 or vice versa) and hence are not seen as compatible.

I just ran this by Nick (who owns Autofac and is down the hall from me) and we 
both agree that you should just load 4.0 version and not attempt to load the 
3.5 version. This should just work and given that they have the same name and 
key, you won't even need to add any binding redirects.

From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com] On 
Behalf Of Matt Siebert
Sent: Sunday, September 18, 2011 11:28 PM
To: ozDotNet
Subject: Assembly binding woes

Hi all,

I have some assembly binding weirdness happening that I don't fully understand. 
 I have some theories but I'd like to understand it a bit better.

I have a solution with two primary entry points:

1.  A .NET 4.0 WPF application

2.  A .NET 3.5 class library that is loaded as a plugin for a 3rd party 
application

Both of these assemblies have a dependency on Autofac, but the .NET 3.5 class 
library uses Autofac for .NET 3.5 while the .NET 4.0 WPF app uses Autofac for 
.NET 4.0.

Obviously, when sending build output to the same folder one Autofac.dll 
overwrites the other so I've added post-build commands to move Autofac to 
relevant sub-folders ("NET35" and "NET40").

For the WPF app I've added an app.config file with a <probing 
privatePath="NET40" /> element which correctly resolves the dependency.

For the .NET 3.5 DLL it's a little trickier.  I can't add a <probing /> element 
since it would need to go in the 3rd party host app's config file, and the path 
would be outside the host's appbase path.  Instead, my DLL provides an 
AssemblyResolve event handler that finds and loads the DLL.

This all works fine.

The plugin DLL described so far, let's call it "Lib1.dll", implements a type, 
say "DerivedType", that is inherited from BaseType in Lib2.dll.  DerivedType 
overrides a method with a ContainerBuilder parameter so it can add 
registrations to the container.  The sequence of events is as follows:

1.  Host app loads Lib1.dll and calls DerivedType.Startup
2.  DerivedType.Startup calls BaseType.Startup
3.  BaseType subscribes to AssemblyResolve and calls SomeMethod that directly 
uses a ContainerBuilder
4.  The AssemblyResolve handler finds and loads Autofac.dll
5.  BaseType.SomeMethod executes and calls SomeVirtualMethod(ContainerBuilder 
builder)

DerivedType in Lib1.dll overrides SomeVirtualMethod but this doesn't get 
called, however, BaseType.SomeVirtualMethod does execute.

This seems consistent with the dependency being loaded into the LoadFrom 
context and therefore not being used to resolve dependencies of Load context 
assemblies, but the code is using Assembly.Load(), not LoadFrom().

I'm not sure if I've explained this very well, but hopefully somebody can shed 
some light on why this is happening?

Cheers.

Reply via email to