6

I'm trying to load assemblies in a separate app domain, but am running into a very strange problem. Here's some code:

    public static void LoadAssembly(string assemblyPath)
    {

        string pathToDll = Assembly.GetCallingAssembly().CodeBase;
        AppDomainSetup domainSetup = new AppDomainSetup
        {
            PrivateBinPath = pathToDll
        };

        AppDomain newDomain = AppDomain.CreateDomain("AssemblyLoader",null,domainSetup);


        AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
            pathToDll,
            typeof(AssemblyLoader).FullName);

    }

AssemblyLoader is another class in the same assembly as this one, and it inherits from MarshalByRef, however for some strange reason, I get a cast exception every time I try to run this. I even hardcoded the path to the DLL instead of using GetCallingAssembly().CodeBase yet I keep getting this exception.

I understand it's hard to answer a question like this without actually seeing it and having more information, but maybe someone has run into a similar situation and would know the common "gotchas" and what I should look out for.

EDIT: The reason I don't want to load it directly is because this is just part of the code. The ultimate goal is that this class will have a method that load assemblies, gets their GUID and some other info about them and stores them in a database for a project I'm working on. Therefore, if I load this assembly in a separate app domain, I can load the others there too and then unload the app domain. No point in having all these assemblies loaded for the duration of the app, if I only need that data.

BFree
  • 102,548
  • 21
  • 159
  • 201
  • If the AssemblyLoader class is in the same assembly as this one, why are you trying to load it from newDomain? Why not just instantiate it directly? – Phillip Wells Oct 03 '08 at 16:14
  • 1
    It's a way of indirectly loading plugins. If the loader instance is in the main app-domain, you create a version in a foreign app domain and ask it to load the plugins you're interested in. This prevents your plugins from needing to know if they're able to be handled by a separate app-domain. (i.e. derive from MarshalByRefObject) This keeps design decisions flexible (e.g. Create a plug-in base class that provides all shared functionality for plugins. ) – Jason D Nov 29 '09 at 06:33

4 Answers4

2

(EDIT: after reading the exception given, changing answer completely)

It appears the problem is the CreateInstanceFromAndUnwrap call, which uses the LoadFrom semantics of 'pathToDll'. Suzanne Cook detailed the possible sticking point on her blog where your original AppDomain tries to call Load("SomeAssembly, [...]") as opposed to LoadFrom("pathToDll") when trying to resolve the type in question.

Her advice was to hook the AssemblyResolve event on the current domain to do the correct LoadFrom in order to get the type. A little bit of targetted googling brings up a possible solution to the problem based on Suzanne's suggestion.

user7116
  • 63,008
  • 17
  • 141
  • 172
  • No, here's what it's saying: Unable to cast transparent proxy to type 'CompanyNamespaceTakenOut.AssemblyLoader – BFree Oct 03 '08 at 16:35
0

I don't believe the PrivateBinPath configuration is necessary, beyond that you don't need to use the Path to the DLL, but rather the Assembly's fully qualified name for the first parameter; try:

AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
        typeof(AssemblyLoader).Assembly.FullName,
        typeof(AssemblyLoader).FullName);
TheXenocide
  • 1,060
  • 8
  • 22
  • 1
    Wrong answer. CreateInstanceFromAndUnwrap()'s first parameter is a path and filename, not an assembly name. CreateInstanceAndUnwrap()'s, however, is an assembly name, but that doesn't help the asker because it would just resolve to the same path and filename. – Timwi Oct 16 '09 at 00:52
0

Check out this article.

Using the code in that article I got a cross app-domain object. I abstracted things a bit with generics and have three assemblies. (i.e. 1 defining the interface, 1 defining the plugin implementation, and the main program which tells the generic what to load.) The original articles code is easy to follow.

Jason D
  • 2,303
  • 14
  • 24
0

There's a lot of good information for what you're trying to do here: How to load a .NET assembly for reflection operations and subsequently unload it?

Community
  • 1
  • 1
Joseph Daigle
  • 47,650
  • 10
  • 49
  • 73