简体   繁体   中英

Can .NET AppDomains do this?

I've spent hours reading up about AppDomains, but I'm not sure they work quite like I'm hoping.

If I have two classes, generic Foo<T> in AppDomain #1, Bar in AppDomain #2:

App Domain #1 is the application. App Domain #2 is something like a plugin, and can be loaded and unloaded dynamically.

AppDomain #2 wants to create Foo<Bar> and use it. Foo<T> uses lots of classes in AppDomain #1 internally.

I don't want AppDomain #2 using object foo with reflection, I want it to use Foo<Bar> foo, with all the static typing and compiled speed that goes with it. Can this be done considering that AppDomain #1, containing Foo<T>, is never unloaded?

If so, does any remoting take place here when using Foo<Bar>?

When I unload AppDomain #2, the type Foo<Bar> is destroyed?

edit SO stripped all my <>, added them back manually.

You are mixing types and objects in your question which makes it hard to answer. Code in an AD has no trouble using types that are also used in other ADs, it simply loads the assembly. But an AD has its own garbage collected heap, you cannot directly reference objects that live in another AD. They need to be serialized across the AD boundary. Yes, Remoting across an IpcChannel will do so.

If you want to access objects cross app domains these objects need to inherit from MarshalByRefObject; in such scenario you'll end up with a proxy to the real object. This way it's safe to unload the application domain (if you try to call through the proxy an exception will be thrown).

I guess that what you are trying to accomplish is something like:

using System;
using System.Reflection;

namespace TestAppDomain
{
class Program
{
    static void Main(string[] args)
    {
        AppDomain pluginsAppDomain = AppDomain.CreateDomain("Plugins");

        Foo foo = new Foo();
        pluginsAppDomain.SetData("Foo", foo);

        Bar bar= (Bar) pluginsAppDomain.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly().FullName, typeof (Bar).FullName);
        bar.UseIt();

        AppDomain.Unload(pluginsAppDomain);
        foo.SaySomething();
    }
}

class Bar : MarshalByRefObject
{
    public void UseIt()
    {
        Console.WriteLine("Current AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName);
        Foo foo = (Foo) AppDomain.CurrentDomain.GetData("Foo");
        foo.SaySomething();
    }
}

class Foo : MarshalByRefObject
{
    public void SaySomething()
    {
        Console.WriteLine("Something from AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName);
    }
}
}

If your types are defined in different assemblies (which is likely) you'll probably define an interface (in a common assembly) and make the types implement this interface.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM