开发者

Can .NET AppDomains do this?

开发者 https://www.devze.com 2023-01-02 06:30 出处:网络
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:

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 conside开发者_Go百科ring 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号