使用 JointCode.Shuttle 访问任意 AppDomain 的服务

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 JointCode.Shuttle 访问任意 AppDomain 的服务相关的知识,希望对你有一定的参考价值。

JointCode.Shuttle 是一个用于进程内 AppDomain 间通信的服务架构(不支持跨进程)。

本文主要介绍如何通过 JointCode.Shuttle 访问任意 AppDomain 的服务。

当我们要进行跨 AppDomain 调用时,一般我们会让需要跨 AppDomain 操作的类(服务类)继承自 MarshalByrefObject,接着在调用 AppDomain(父 AppDomain)中创建目标 AppDomain(子 AppDomain),然后直接通过子 AppDomain  的引用创建所需的服务对象,并调用服务对象的相关方法。代码就像这样:

 1 namespace JoitCode.Shuttle.SimpleSample
 2 {
 3     public class MyService : MarshalByRefObject
 4     {
 5         public void Do() { }
 6     }
 7 
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             // 在默认 AppDomain 中创建一个子 AppDomain
13             var serviceDomain = AppDomain.CreateDomain("ServiceDomain", null, null);
14             
15             var myService = (MyService)serviceDomain.CreateInstanceAndUnwrap
16                 (typeof(MyService).Assembly.FullName, 
17                  "JoitCode.Shuttle.SimpleSample.MyService");
18 
19             myService.Do();
20 
21             Console.Read();
22         }
23     }
24 }

显然,通过这种方式,我们没有办法直接从子 AppDomain 中访问父 AppDomain。当然,我们也可以通过一些变通办法来实现双向通信,比如像下面这样:

    public class MarshalByRefCrossAccess1 : MarshalByRefObject
    {
        public void Run()
        {
            Console.Write("Now, we are running in AppDomain [{0}]!", AppDomain.CurrentDomain.FriendlyName);
            Console.WriteLine();
        }
    }

    public class MarshalByRefCrossAccess2 : MarshalByRefObject
    {
        public void Run(MarshalByRefCrossAccess1 arg)
        {
            Console.WriteLine("Currently, we are running in AppDomain [{0}]: ", AppDomain.CurrentDomain.FriendlyName);
            arg.Run();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var remoteDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, null);
            var access2 = (MarshalByRefCrossAccess2)remoteDomain.CreateInstanceAndUnwrap
                (typeof(MarshalByRefCrossAccess2).Assembly.FullName, typeof(MarshalByRefCrossAccess2).FullName);
            var access1 = new MarshalByRefCrossAccess1();
            access2.Run(access1);

            Console.Read();
        }
    }

 

尽管可以变通实现双向通信,但诸如此类的办法总是显得不那么自然。更为重要的是,这是双向通信,通信双方互相持有对方,因此我们可以这样达到目的。

但如果我们想要与之通信的对象根本不在我们掌控之中(即不持有其引用)呢?

比如说,我们在一个  AppDomain A 中创建了另外两个 AppDomain B 和 C,现在如果 AppDomain B 要访问 AppDomain C,又当如何呢?

JointCode.Shuttle 天生就能够解决这种问题。

我们为此写了一个示例。以下是该示例输出的部分截图:

技术分享

如果您对示例源码感兴趣,请单击 此处 下载(示例名称:ShuttleDomain任意域访问)。

 

以上是关于使用 JointCode.Shuttle 访问任意 AppDomain 的服务的主要内容,如果未能解决你的问题,请参考以下文章

使用 JointCode.Shuttle 进行跨 AppDomain 通信的一个简单示例

使用 JointCode.Shuttle 动态注册 / 注销服务

使用 JointCode.Shuttle 管理远程服务对象的生命期

jenkins 未授权访问-任意命令执行

如何通过任意 erb 文件访问任意视图助手的方法?

小5聊本地IP地址设置为任意域名访问