### Serve DocFX Documentation Locally Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Executes the DocFX build process and starts a local web server to host the generated documentation for previewing changes. ```Command Line dotnet docfx --serve ``` -------------------------------- ### Updating Yarn and VS Code SDKs (PowerShell) Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Commands to update the Yarn version to 'berry' and install/update the Yarn SDKs specifically for VS Code, useful for maintaining Zero Install mode. These commands are typically executed in a PowerShell environment. ```ps1 yarn set version berry yarn dlx @yarnpkg/sdks vscode ``` -------------------------------- ### Consuming VersionInfoService from VS Code in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/docs/npm.md Illustrates how to consume a specific brokered service (VersionInfoService) from VS Code using the Live Share API. It includes defining the service descriptor, getting a remote service broker, requesting the service proxy, calling its method, and properly disposing of the proxy. ```TypeScript import * as isb from '@microsoft/servicehub-framework'; import * as vsls from 'vsls'; const VersionInfoService = new isb.ServiceJsonRpcDescriptor( isb.ServiceMoniker.create('Microsoft.VisualStudio.Shell.VersionInfoService', '1.0'), isb.Formatters.Utf8, isb.MessageDelimiters.HttpLikeHeaders); interface IVersionInfoService { GetVersionInformationAsync(cancellationToken?: vscode.CancellationToken): Promise; } interface VersionInformation { visualStudioVersion: string; liveShareVersion: string; } const ls = await vsls.getApi(); const serviceBroker = await ls.services.getRemoteServiceBroker(); const proxy = await serviceBroker?.getProxy(VersionInfoService); try { if (proxy) { const versionInfo = await proxy.GetVersionInformationAsync(); console.log(`VS version: ${versionInfo.visualStudioVersion}`); } } finally { proxy?.dispose(); } ``` -------------------------------- ### Implementing Server Class Using Marshalable Object Proxy in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/src/servicebroker-npm/doc/marshalable_objects.md Provides an example implementation of the `Server` class, showing how to receive a marshaled object proxy (`calc`), call a method on it (`calc.add`), and explicitly dispose of the proxy using the `IDisposable` interface to release resources. ```TypeScript class Server { doSomeMath(calc: ICalculator & IDisposable): Promise { const sum = await calc.add(2, 3) calc.dispose() return sum // 5 } } ``` -------------------------------- ### Build DocFX Documentation Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Runs the DocFX build process to generate the documentation site. Can be used to update the site while the local server is running or as a standalone build step. ```Command Line dotnet docfx ``` -------------------------------- ### Defining and Using a Brokered Service in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/docs/npm.md This snippet demonstrates the complete lifecycle of a simple brokered service within a single file. It defines the service interface and implementation, sets up a GlobalBrokeredServiceContainer, registers the service descriptor, provides a factory to create service instances, and finally obtains a proxy to the service via a service broker to invoke its method. It uses test framework constructs like 'beforeAll' and 'it' for context. ```typescript import assert from 'assert'; import CancellationToken from 'cancellationtoken'; import { Formatters, MessageDelimiters, ServiceJsonRpcDescriptor, ServiceMoniker, ServiceRpcDescriptor, GlobalBrokeredServiceContainer, ServiceAudience, ServiceRegistration } from '@microsoft/servicehub-framework'; interface IService { readonly moniker: ServiceMoniker; readonly descriptor: ServiceRpcDescriptor; readonly registration: ServiceRegistration; } class Services { static calculator: Readonly = Services.defineLocal('calc'); private static defineLocal( name: string, version?: string ): Readonly { const moniker = { name, version }; const descriptor = new ServiceJsonRpcDescriptor( moniker, Formatters.MessagePack, MessageDelimiters.BigEndianInt32LengthHeader ); const registration = new ServiceRegistration( ServiceAudience.local, false ); return Object.freeze({ moniker, descriptor, registration }); } } interface ICalculator { add( a: number, b: number, cancellationToken?: CancellationToken ): Promise; } class Calculator implements ICalculator { public add( a: number, b: number, cancellationToken?: CancellationToken ): Promise { return Promise.resolve(a + b); } } let container: GlobalBrokeredServiceContainer; beforeAll(function () { container = new GlobalBrokeredServiceContainer(); container.register([Services.calculator]); container.profferServiceFactory( Services.calculator.descriptor, (mk, options, sb, ct) => Promise.resolve(new Calculator()) ); }); it('self-contained sample', async function () { const sb = container.getFullAccessServiceBroker(); const calc = await sb.getProxy(Services.calculator.descriptor); assert(calc); const sum = await calc.add(3, 5); assert(sum === 8); }); ``` -------------------------------- ### Testing Typescript Code (Yarn/Shell) Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Command to execute tests for the Typescript code using the Yarn package manager. ```shell yarn test ``` -------------------------------- ### Building Typescript Code (Yarn/Shell) Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Command to build the Typescript code within the repository using the Yarn package manager. ```shell yarn build ``` -------------------------------- ### Packing Typescript Code (PowerShell) Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Script used to package the built Typescript code. This is a PowerShell script. ```ps1 pack.ps1 ``` -------------------------------- ### Consuming a Brokered Service Proxy (TypeScript) Source: https://github.com/microsoft/vs-servicehub/blob/main/src/servicebroker-npm/README.md Demonstrates how to obtain a proxy for a brokered service using an IServiceBroker instance and a service descriptor, invoke a method on the proxy, and ensure the proxy is disposed of properly using a try...finally block. ```typescript const proxy = await serviceBroker.getProxy(CalculatorDescriptor); try { if (proxy) { const sum = await proxy.add(3, 5); assert(sum == 8); } } finally { proxy?.dispose(); } ``` -------------------------------- ### Configuring Yarn for Azure DevOps NPM Registry (YAML) Source: https://github.com/microsoft/vs-servicehub/blob/main/CONTRIBUTING.md Configures Yarn's .yarnrc.yml file to authenticate with a private Azure DevOps NPM registry using a Personal Access Token (PAT). Replace 'PAT' with your actual token from the 'azure-public' AzDO account. ```yaml npmRegistries: //pkgs.dev.azure.com/azure-public/vside/_packaging/msft_consumption/npm/registry/: npmAuthIdent: devdiv:PAT npmAlwaysAuth: true ``` -------------------------------- ### Managing Proxy Lifetime with IServiceBroker - C# Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB002.md This snippet presents an alternative solution for scenarios where the proxy lifetime needs to extend beyond a single async method. It demonstrates using IServiceBroker instead of ServiceBrokerClient and managing the proxy's lifetime manually, including implementing IDisposable for proper cleanup. ```C# class Foo : IDisposable { IServiceBroker serviceBroker; IMyService? proxy; async Task DoSomethingAsync() { if (proxy is null) { proxy = await serviceBroker.GetProxyAsync(someDescriptor); } if (proxy is object) { // use proxy here } } public void Dispose() => (proxy as IDisposable)?.Dispose(); } ``` -------------------------------- ### Exporting Brokered Service with Interface - C# Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB003.md This code demonstrates the correct implementation of a type annotated with `[ExportBrokeredService]` by implementing the `IExportedBrokeredService` interface, resolving the ISB003 diagnostic. It includes the required `Descriptor` property and `InitializeAsync` method. ```C# [ExportBrokeredService("name", "1.0")] class Foo : IExportedBrokeredService { ServiceRpcDescriptor IExportedBrokeredService.Descriptor { get; } = new ServiceJsonRpcDescriptor( new ServiceMoniker("CallBackService", new Version(0, 1)), ServiceJsonRpcDescriptor.Formatters.UTF8, ServiceJsonRpcDescriptor.MessageDelimiters.HttpLikeHeaders); Task IExportedBrokeredService.InitializeAsync(CancellationToken cancellationToken) => Task.CompletedTask; } ``` -------------------------------- ### Using ServiceBrokerClient Rental within Async Method - C# Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB002.md This snippet shows the recommended solution for using ServiceBrokerClient.Rental. The rental is acquired and disposed of within the async method using a using statement, ensuring proper lifetime management and adherence to the ISB002 rule. ```C# class Foo { ServiceBrokerClient serviceBrokerClient; async Task DoSomethingAsync() { using (var proxyRental = await serviceBrokerClient.GetProxyAsync(someDescriptor)) { if (proxyRental.Proxy is object) { // use proxyRental.Proxy here } } } } ``` -------------------------------- ### Consuming a Brokered Service (Calculator) in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/docs/npm.md Demonstrates how to obtain a proxy for a brokered service using an IServiceBroker instance. It shows calling a method on the proxy and emphasizes the importance of checking for a null result and disposing the proxy to prevent resource leaks. ```TypeScript const proxy = await serviceBroker.getProxy(CalculatorDescriptor); try { if (proxy) { const sum = await proxy.add(3, 5); assert(sum == 8); } } finally { proxy?.dispose(); } ``` -------------------------------- ### Compliant: Dispose proxy using 'using' block (local variable, interface implements IDisposable) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB001.md This C# code snippet demonstrates the correct way to dispose of a proxy stored in a local variable when the interface `IMyService` implements `IDisposable`. A `using` block ensures that the proxy's `Dispose` method is called automatically when the block is exited, even if exceptions occur. ```C# using (IMyService client = await serviceBroker.GetProxyAsync(someDescriptor)) { if (client is object) { await client.FooAsync(); } } ``` -------------------------------- ### Storing ServiceBrokerClient Rental in Field (Flagged) - C# Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB002.md This snippet demonstrates a pattern that is flagged by the analyzer. It shows acquiring a proxy rental from ServiceBrokerClient.GetProxyAsync and storing it in a field, which violates the recommended practice of disposing rentals within the async method where they are acquired. ```C# class Foo { ServiceBrokerClient serviceBrokerClient; ServiceBrokerClient.Rental proxyRental; async Task DoSomethingAsync() { proxyRental = await serviceBrokerClient.GetProxyAsync(someDescriptor); } } ``` -------------------------------- ### Compliant: Dispose proxy using 'using' block (local variable, interface does not implement IDisposable) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB001.md This C# code snippet shows how to correctly dispose of a proxy stored in a local variable when the interface `IMyService` does NOT implement `IDisposable`. The proxy instance itself implements `IDisposable`, so it is cast to `IDisposable` within the `using` block to ensure proper disposal. ```C# IMyService client = await serviceBroker.GetProxyAsync(someDescriptor); using (client as IDisposable) { if (client is object) { await client.FooAsync(); } } ``` -------------------------------- ### Exporting Brokered Service without Interface - C# Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB003.md This code demonstrates a type annotated with `[ExportBrokeredService]` that does not implement the required `IExportedBrokeredService` interface, which violates the ISB003 rule and generates a diagnostic. ```C# [ExportBrokeredService("name", "1.0")] class Foo { } ``` -------------------------------- ### Fixing ISB004 Rule - Implementing Optional Interface (C#) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB004.md This C# code snippet shows one way to fix the ISB004 violation. The Foo class is modified to implement the IBar interface, satisfying the requirement that all listed optional interfaces must be implemented. ```C# [ExportBrokeredService("name", "1.0", typeof(IBar))] class Foo : IExportedBrokeredService, IFoo, IBar { } ``` -------------------------------- ### Non-compliant: Acquire and use proxy without disposing (local variable) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB001.md This C# code snippet demonstrates a common pattern that violates the ISB001 rule. A proxy is obtained using `serviceBroker.GetProxyAsync` and used, but it is not explicitly disposed of before the local variable goes out of scope. This will be flagged by the analyzer. ```C# IMyService client = await serviceBroker.GetProxyAsync(someDescriptor); if (client is object) { await client.FooAsync(); } ``` -------------------------------- ### Violating ISB004 Rule - Missing Interface Implementation (C#) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB004.md This C# code snippet demonstrates a violation of the ISB004 rule. The Foo class is annotated with [ExportBrokeredService] and lists IBar as an optional interface, but the class does not implement IBar, which triggers the analyzer diagnostic. ```C# [ExportBrokeredService("name", "1.0", typeof(IBar))] // IBar isn't actually implemented by the Foo class. class Foo : IExportedBrokeredService, IFoo { } ``` -------------------------------- ### Compliant: Dispose proxy stored in member Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB001.md This C# code snippet demonstrates the correct approach for disposing of a proxy stored in a class member. The existing proxy is disposed of before a new one is assigned, and the member is also disposed of in the class's `Dispose` method to handle the case where the object itself is disposed. ```C# class MyClass : IDisposable { IMyService client; async Task DoSomethingAsync() { (this.client as IDisposable)?.Dispose(); this.client = await serviceBroker.GetProxyAsync(someDescriptor); if (this.client is object) { await this.client.FooAsync(); } } public void Dispose() { (this.client as IDisposable)?.Dispose(); } } ``` -------------------------------- ### Non-compliant: Acquire and store proxy in member without disposing Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB001.md This C# code snippet shows another non-compliant pattern where a proxy is acquired and stored in a class member (`this.client`). The proxy is used but not disposed of before potential reassignment or when the containing object is disposed. This requires disposal logic in the class's Dispose method and before reassigning the member. ```C# class MyClass { IMyService client; async Task DoSomethingAsync() { this.client = await serviceBroker.GetProxyAsync(someDescriptor); if (this.client is object) { await this.client.FooAsync(); } } } ``` -------------------------------- ### Fixing ISB004 Rule - Removing Optional Interface (C#) Source: https://github.com/microsoft/vs-servicehub/blob/main/docfx/analyzers/ISB004.md This C# code snippet shows an alternative way to fix the ISB004 violation. The IBar interface is removed from the list of optional interfaces in the [ExportBrokeredService] attribute, resolving the diagnostic without requiring the class to implement IBar. ```C# [ExportBrokeredService("name", "1.0")] class Foo : IExportedBrokeredService, IFoo { } ``` -------------------------------- ### Defining Server Interface Accepting Marshalable Object in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/src/servicebroker-npm/doc/marshalable_objects.md Defines a TypeScript interface for a server method (`doSomeMath`) that accepts an argument typed as `ICalculator`. This demonstrates how to use type safety when expecting a marshaled object proxy on the receiving side of an RPC connection. ```TypeScript interface IServer { doSomeMath(calc: ICalculator): Promise } ``` -------------------------------- ### Implementing RpcMarshalable Interface in TypeScript Source: https://github.com/microsoft/vs-servicehub/blob/main/src/servicebroker-npm/doc/marshalable_objects.md Demonstrates how to define an interface and a class that implements the `RpcMarshalable` interface, making instances of the class eligible for marshaling across a JSON-RPC connection instead of being serialized by value. The `_jsonRpcMarshalableLifetime` property is set to 'explicit' to indicate manual disposal. ```TypeScript interface ICalculator { add(a: number, b: number): Promise | number } class Calculator implements ICalculator, RpcMarshalable { readonly _jsonRpcMarshalableLifetime: MarshaledObjectLifetime = 'explicit' add(a: number, b: number) { return a + b } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.