| | | 1 | | // Copyright (c) ZeroC, Inc. |
| | | 2 | | |
| | | 3 | | using IceRpc.Transports; |
| | | 4 | | using IceRpc.Transports.Quic; |
| | | 5 | | using IceRpc.Transports.Tcp; |
| | | 6 | | using Microsoft.Extensions.DependencyInjection; |
| | | 7 | | using Microsoft.Extensions.DependencyInjection.Extensions; |
| | | 8 | | using Microsoft.Extensions.Logging; |
| | | 9 | | using Microsoft.Extensions.Options; |
| | | 10 | | |
| | | 11 | | namespace IceRpc.Extensions.DependencyInjection; |
| | | 12 | | |
| | | 13 | | /// <summary>Provides extension methods for <see cref="IServiceCollection" /> to add a client connection.</summary> |
| | | 14 | | public static class ClientConnectionServiceCollectionExtensions |
| | | 15 | | { |
| | | 16 | | /// <summary>Adds a <see cref="ClientConnection" /> singleton that connects to the specified server address to this |
| | | 17 | | /// service collection; this singleton is also registered as the <see cref="IInvoker" /> singleton.</summary> |
| | | 18 | | /// <param name="services">The service collection to add services to.</param> |
| | | 19 | | /// <param name="serverAddress">The server address of the client connection.</param> |
| | | 20 | | /// <returns>The service collection.</returns> |
| | | 21 | | /// <remarks>This method sets <see cref="ClientConnectionOptions.ServerAddress" /> in the client connection options |
| | | 22 | | /// provided by the <see cref="IOptions{T}" /> of <see cref="ClientConnectionOptions" />; the client connection uses |
| | | 23 | | /// all the other options from these injected options. If your application connects to multiple servers, call |
| | | 24 | | /// <see cref="ConnectionCacheServiceCollectionExtensions.AddIceRpcConnectionCache(IServiceCollection)" /> |
| | | 25 | | /// instead.</remarks> |
| | | 26 | | /// <seealso cref="AddIceRpcClientConnection(IServiceCollection)" /> |
| | | 27 | | public static IServiceCollection AddIceRpcClientConnection( |
| | | 28 | | this IServiceCollection services, |
| | | 29 | | ServerAddress serverAddress) |
| | 1 | 30 | | { |
| | 2 | 31 | | services.AddOptions<ClientConnectionOptions>().Configure(options => options.ServerAddress = serverAddress); |
| | 1 | 32 | | return services.AddIceRpcClientConnection(); |
| | 1 | 33 | | } |
| | | 34 | | |
| | | 35 | | /// <summary>Adds a <see cref="ClientConnection" /> singleton that connects to the specified server address URI to |
| | | 36 | | /// this service collection; this singleton is also registered as the <see cref="IInvoker" /> singleton.</summary> |
| | | 37 | | /// <param name="services">The service collection to add services to.</param> |
| | | 38 | | /// <param name="serverAddressUri">The server address URI of the client connection.</param> |
| | | 39 | | /// <returns>The service collection.</returns> |
| | | 40 | | /// <remarks>If your application connects to multiple servers, call |
| | | 41 | | /// <see cref="ConnectionCacheServiceCollectionExtensions.AddIceRpcConnectionCache(IServiceCollection)" /> |
| | | 42 | | /// instead.</remarks> |
| | | 43 | | /// <seealso cref="AddIceRpcClientConnection(IServiceCollection, ServerAddress)" /> |
| | | 44 | | public static IServiceCollection AddIceRpcClientConnection(this IServiceCollection services, Uri serverAddressUri) = |
| | 1 | 45 | | services.AddIceRpcClientConnection(new ServerAddress(serverAddressUri)); |
| | | 46 | | |
| | | 47 | | /// <summary>Adds a <see cref="ClientConnection" /> singleton to this service collection; this singleton is also |
| | | 48 | | /// registered as the <see cref="IInvoker" /> singleton.</summary> |
| | | 49 | | /// <param name="services">The service collection to add services to.</param> |
| | | 50 | | /// <returns>The service collection.</returns> |
| | | 51 | | /// <remarks>This method uses the client connection options provided by the <see cref="IOptions{T}" /> of |
| | | 52 | | /// <see cref="ClientConnectionOptions" />. If your application connects to multiple servers, call |
| | | 53 | | /// <see cref="ConnectionCacheServiceCollectionExtensions.AddIceRpcConnectionCache(IServiceCollection)" /> |
| | | 54 | | /// instead.</remarks> |
| | | 55 | | /// <example> |
| | | 56 | | /// The following code adds a ClientConnection singleton to the service collection. |
| | | 57 | | /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcClientConnectionExamp |
| | | 58 | | /// region="ClientConnectionWithOptions" lang="csharp" /> |
| | | 59 | | /// You can also inject a client transport: |
| | | 60 | | /// <list type="bullet"> |
| | | 61 | | /// <item><description>an <see cref="IDuplexClientTransport" /> for the ice protocol</description></item> |
| | | 62 | | /// <item><description>an <see cref="IMultiplexedClientTransport" /> for the icerpc protocol</description></item> |
| | | 63 | | /// </list> |
| | | 64 | | /// For example, you can add a Slic over TCP client connection as follows: |
| | | 65 | | /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcClientConnectionExamp |
| | | 66 | | /// region="ClientConnectionWithSlic" lang="csharp" /> |
| | | 67 | | /// If you want to customize the options of the default multiplexed transport (QUIC), you just need to inject an |
| | | 68 | | /// <see cref="IOptions{T}" /> of <see cref="QuicClientTransportOptions" />. |
| | | 69 | | /// </example> |
| | | 70 | | public static IServiceCollection AddIceRpcClientConnection(this IServiceCollection services) => |
| | 26 | 71 | | services |
| | 26 | 72 | | .TryAddIceRpcClientTransport() |
| | 26 | 73 | | .AddSingleton(provider => |
| | 26 | 74 | | new ClientConnection( |
| | 26 | 75 | | provider.GetRequiredService<IOptions<ClientConnectionOptions>>().Value, |
| | 26 | 76 | | provider.GetRequiredService<IDuplexClientTransport>(), |
| | 26 | 77 | | provider.GetRequiredService<IMultiplexedClientTransport>(), |
| | 26 | 78 | | provider.GetService<ILogger<ClientConnection>>())) |
| | 28 | 79 | | .AddSingleton<IInvoker>(provider => provider.GetRequiredService<ClientConnection>()); |
| | | 80 | | |
| | | 81 | | internal static IServiceCollection TryAddIceRpcClientTransport(this IServiceCollection services) |
| | 30 | 82 | | { |
| | | 83 | | // The default duplex transport is TCP. |
| | 30 | 84 | | services |
| | 30 | 85 | | .AddOptions() |
| | 30 | 86 | | .TryAddSingleton<IDuplexClientTransport>( |
| | 30 | 87 | | provider => new TcpClientTransport( |
| | 30 | 88 | | provider.GetRequiredService<IOptions<TcpClientTransportOptions>>().Value)); |
| | | 89 | | |
| | 30 | 90 | | services |
| | 30 | 91 | | .TryAddSingleton<IMultiplexedClientTransport>( |
| | 30 | 92 | | provider => |
| | 0 | 93 | | { |
| | 0 | 94 | | if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsWindows()) |
| | 0 | 95 | | { |
| | 30 | 96 | | // This works even when QUIC is not available. |
| | 0 | 97 | | return new QuicClientTransport( |
| | 0 | 98 | | provider.GetRequiredService<IOptions<QuicClientTransportOptions>>().Value); |
| | 30 | 99 | | } |
| | 0 | 100 | | throw new PlatformNotSupportedException( |
| | 0 | 101 | | "The default QUIC client transport is not supported on this platform. You need to register an IM |
| | 30 | 102 | | }); |
| | | 103 | | |
| | 30 | 104 | | return services; |
| | 30 | 105 | | } |
| | | 106 | | } |