1

I think I've determined that even though I'm loading assemblies in a MarshalByRefObject in a new AppDomain that the assemblies are also getting loaded into the parent domain.

Here's my Assembly structure (arrows indicate dependency):

MainAssembly -> CommonInterfaceAssembly <- ExtensionAssembly

In the parent AppDomain I'm doing this:

var loader = (ExtensionLoader)extDomain.CreateInstanceAndUnwrap (Assembly.GetExecutingAssembly().FullName, "ExtensionLoader");
loader.loadExtensions (this);

and the Loader class is:

class ExtensionLoader : MarshalByRefObject
{
    public List<IExtension> loadExtensions (ExtensionMgr mgr)
    {
        // Delegate to Addins to return the list of extensions
        AddinManager.Initialize ();
        AddinManager.Registry.Update ();
        AddinManager.GetExtensionObjects<IExtension> ();

        var extensions = new List<IExtension> (AddinManager.GetExtensionObjects<IExtension> ());
        foreach (var ext in extensions) {
            ext.Initialize (mgr);
        }
        return extensions;
    }
}

I don't know if it's relevant to the question, but I am using Mono.Addins to load the extensions in the new AppDomain so I've left that code in. From what I can tell though things work fine up to the point where I invoke the Initialize method on each of the extensions.

So I have ran this scenario with the ExtensionAssembly in the same directory as the main executable and in a separate 'extensions' directory. What's curious to me is that when I invoke ext.Initialize either the ExtensionAssembly gets loaded in the parent AppDomain (if it exists in the same directory), or I get the below stack trace if not. Any ideas why?

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x001f0] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs:247 

Exception rethrown at [1]: 
 ---> System.IO.FileNotFoundException: Could not load file or assembly 'Extensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Extensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  at System.AppDomain.Load (System.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) [0x00047] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System/AppDomain.cs:785 
  at System.AppDomain.Load (System.String assemblyString) [0x00000] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System/AppDomain.cs:762 
kenen
  • 397
  • 1
  • 3
  • 14
  • I don't understand, you are trying to load an assembly in a different domain and invoke code in it from its parent? – IanNorton Feb 19 '12 at 07:09
  • @IanNorton Yup. I'm basically trying to create a plugin framework where the parent appdomain can load/unload/change plugins at runtime. – kenen Feb 19 '12 at 09:10
  • How about having the remote domain export it's 'load an assembly' method via remoting? then calling that? – IanNorton Feb 19 '12 at 12:29
  • @IanNorton I'm not sure I understand. That is what I thought I was doing with ExtensionLoader. It's MarshalByRefObject and running in the remote domain. – kenen Feb 19 '12 at 18:35
  • What does the Initialize method do? –  Feb 21 '12 at 22:28
  • a) Are you sure that the Initialize call triggers the assembly load? b) Please show the full call stack of the exception. c) What does the Initialize method do? d) What if you call an empty Initialize method? – usr Feb 22 '12 at 00:01
  • I think I've found the problem.. a) Yup. I've printed out the loaded assemblies in each appdomain before and after the call to Initialize. c) Among other things local to the extension being loaded it attempts to register an event listener on ExtensionMgr. d) An empty Initialize method does not load the Extensions assembly in the parent app domain. So my problem I think is in b) That subscribing to events requires both app domains to have 'type information at both the client and server' (http://stackoverflow.com/a/1390654/852070). So I'll need to come up with a manual observer pattern I guess. – kenen Feb 24 '12 at 19:28

0 Answers0