共用方式為


由仲介提供的服務要點

仲介服務是透過 IServiceBroker 取得的服務,並且會以 RPC 相容的介面公開,讓服務及其用戶端可以存在於不同的 AppDomains、進程,甚至跨電腦(例如在 Live Share 的情況下)。 代理服務可能由主 Visual Studio 程序或其一些輔助程序提供,並且可以透過 Visual Studio 擴充功能來使用這些程序。

更多(非中介)Visual Studio 服務可透過IServiceProvider介面取得,如在使用和提供服務中所述。 這類服務通常只能在主要 Visual Studio 程式中使用,但公開的功能集比代理服務更大。

在 Live Share 客體上執行的 Visual Studio 擴充功能,可藉由存取 Live Share 主機所提供之這些服務的子集來提供其他功能。 授權檢查會透過 Live Share 連線套用,以降低行為不良的 Live Share 來賓危害 Live Share 主機安全性的風險。 選擇透過 Live Share 公開其服務的代理服務作者應該小心實作授權檢查,如 如何提供代理服務中所述。

服務仲介

Visual Studio 有一個全域 IServiceBroker,類似於公開其他服務的 ,且可從 GlobalProvider 中擷取。 它也可以透過MEF來取得。

特定 Visual Studio 功能可能會提供其他更具上下文特定的服務代理程式,這些功能希望將其與全域的服務代理程式合併,提供額外的服務(或可能隱藏某些服務)。

IServiceBroker是一个(刻意设置的)黑箱,允许客户端获取服务,这些服务可能位于本机、另一个程序中,或在另一部计算机上。 服務中介可能是由一或多個其他中介聚合而成,並套用策略。

根據 Visual Studio 過程所在的內容,此全域服務代理是一個由變更中的其它服務代理組成的集合。 進程內的內容變更可能會變更可能啟動的一組代理服務。 例如,當載入一個解決方案時,可能會有一項與該使用中解決方案特別相關的服務變得可用。 同一項服務也可在 [開啟資料夾] 檢視中取得,儘管有不同的備份實作。 服務實作中的變更對該服務的客戶端而言是透明的,因為兩個實作都必須履行相同的合約,但客戶端必須在此上下文變更中重新查詢服務(他們將透過AvailabilityChanged收到通知),以取得新的實例。

Service Broker 通常用來取得服務的 Proxy。 也就是說,用戶端不直接接收服務對象的參考,而是接收存根,該存根會將所有方法呼叫轉送回服務,並將結果或例外狀況轉送回用戶端。 它也可能會將服務所引發的事件轉送至用戶端。 在某些情況下,服務可能會支援或要求用戶端提供「目標對象」,以便該服務能夠叫用方法來回呼用戶端。

仲介服務容器

服務必須提供至 IBrokeredServiceContainer,以確保能夠從全域 IServiceBroker 取得。 此服務容器不僅負責向服務代理公開服務工廠,還負責控制哪些用戶端可以存取服務,並在服務存取權變動時通知這些用戶端。

代理服務的組成

代理服務包含下列元素:

  • 宣告服務功能的介面,並做為服務與其客戶端之間的合約。
  • 該介面的實作。
  • ServiceMoniker 指派一個名稱和版本給服務。
  • ServiceRpcDescriptor,結合ServiceMoniker與在必要時處理 RPC 的行為。
  • 用來提供服務處理站的程序代碼
  • 服務註冊

服務介面

這可能是標準 .NET 介面(通常以 C# 撰寫)。 若要允許代理服務客戶端和服務存在於不同的進程中,並透過 RPC 進行通訊,此介面必須遵守服務將使用之 所 ServiceRpcDescriptor 指定的限制。 這些限制通常包括不允許屬性和索引器,而且大部分或所有方法都會傳回 Task 或其他異步相容的傳回型別。

代理服務名稱和描述

啟用服務需要知道其識別名稱。 因為 Moniker 包含在服務的描述元中,用戶端通常只能處理 ServiceRpcDescriptor。 描述項會新增在代理服務與其客戶端之間設定 RPC 連接所需的行為,或當需要串行化往返 Stream的 RPC 呼叫時。

Visual Studio 建議針對代理服務使用 ServiceJsonRpcDescriptor 衍生類型,以在用戶端和服務需要 RPC 進行通訊時,利用 StreamJsonRpc 函式庫。 StreamJsonRpc 會在服務介面上套用某些限制,如 這裡所述

描述元很少需要直接使用。 相反地,通常會從 VisualStudioServices 或提供服務的程式庫取得,然後用作 GetProxyAsync 的參數。

ServiceMonikerServiceJsonRpcDescriptor 類別都是不可變的,因此可以安全地共用為static readonly欄位或屬性。 任何其他 ServiceRpcDescriptor衍生類型都應該是不可變的。

ServiceMoniker可串行化 。 ServiceJsonRpcDescriptor無法串行化。

服務對象

每個中介服務都會以從 ServiceAudience選擇的旗標進行註冊。 這些旗標用來控制代理服務將向哪些用戶端及透過哪些連線公開。

典型的選擇是 ServiceAudience.Local,它會將服務公開至 Visual Studio 會話內的任何本機進程。 使用此設定時,服務一律會在本機啟動,即使 Live Shared 會話處於作用中狀態也一樣。

當新增 ServiceAudience.LiveShareGuest 旗幟時,請求代理服務的 Live Share 來賓會透過與 Live Share 主機的遠端連線,取得該代理服務的代理介面。

ServiceAudience 定義之旗標的任何組合都是合法的。 LiveShareGuest旗標可以設定而不設定Local旗標,例如向 Live Share 來賓公開代理服務(來自 Live Share 主機),而且永遠不會在本機使用(用戶端和服務位於相同進程中)。

RemoteExclusiveClientRemoteExclusiveServer 旗標已被取代。

當用戶端要求代理服務時,無需知道該服務的內容或服務將在哪裡啟動。 不過,讓服務記錄此值,以及讓取用服務的開發者瞭解服務可能被啟用的位置,對於預期該服務在各種情況下可能提供的數據類型,以及何時服務可以使用,這是非常有用的。

代理客戶端的組成

當用戶端要求代理服務時,若服務無法使用,將返回 null;若服務在啟用時失敗,將擲回 ServiceActivationFailedException;若服務可用,則會取得一個服務的 代理。 不論仲介服務是在與用戶端相同的行程中啟動,還是在不同的行程中啟動,都會使用代理程式。 此 Proxy 有助於協調本機和遠端服務案例之間的使用模式,讓用戶端不需要知道服務所在的位置。