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


    JointCode.Shuttle 是一个用于进程内 AppDomain 间通信的服务架构(不支持跨进程),它旨在取代运行时库提供的 MarshalByrefObject 的功能。

    本文主要介绍如何通过 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任意域访问

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

  • 相关阅读:
    docker容器的本质
    golang 算法题 : 二维数组搜索值
    golang 算法题 : 两数相加
    golang 开源代理
    golang vue 使用 websocket 的例子
    互联网技术部门该如何管理
    大数据清洗第一天
    本周总结
    信息领域热词分析性能分析
    本周总结
  • 原文地址:https://www.cnblogs.com/johnny-liu/p/7200071.html
Copyright © 2020-2023  润新知