使用 JointCode.Shuttle 訪問任意 AppDomain 的服務

JointCode.Shuttle 是一個用於進程內 AppDomain 間通訊的服務架構(不支持跨進程),它旨在取代運行時庫提供的 MarshalByrefObject 的功能。git

本文主要介紹如何經過 JointCode.Shuttle 訪問任意 AppDomain 的服務。github

當咱們要進行跨 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。固然,咱們也能夠經過一些變通辦法來實現雙向通訊,好比像下面這樣:ui

    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();
        }
    }

 

儘管能夠變通實現雙向通訊,但諸如此類的辦法老是顯得不那麼天然。更爲重要的是,這是雙向通訊,通訊雙方互相持有對方,所以咱們能夠這樣達到目的。spa

但若是咱們想要與之通訊的對象根本不在咱們掌控之中(即不持有其引用)呢?code

好比說,咱們在一個  AppDomain A 中建立了另外兩個 AppDomain B 和 C,如今若是 AppDomain B 要訪問 AppDomain C,又當如何呢?對象

JointCode.Shuttle 天生就可以解決這種問題。blog

咱們爲此寫了一個示例。如下是該示例輸出的部分截圖:繼承

ShuttleDomain任意域訪問

若是您對示例源碼感興趣,請移步前往 此處 下載(示例名稱:ShuttleDomain任意域訪問)。進程

相關文章
相關標籤/搜索