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任意域訪問)。進程