< Summary

Information
Class: IceRpc.Extensions.DependencyInjection.ServerServiceCollectionExtensions
Assembly: IceRpc.Extensions.DependencyInjection
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Extensions.DependencyInjection/ServerServiceCollectionExtensions.cs
Tag: 592_20856082467
Line coverage
70%
Covered lines: 40
Uncovered lines: 17
Coverable lines: 57
Total lines: 181
Line coverage: 70.1%
Branch coverage
0%
Covered branches: 0
Total branches: 8
Branch coverage: 0%
Method coverage
71%
Covered methods: 5
Total methods: 7
Method coverage: 71.4%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddIceRpcServer(...)100%210%
AddIceRpcServer(...)100%11100%
AddIceRpcServer(...)100%11100%
AddIceRpcServer(...)100%210%
AddIceRpcServer(...)100%11100%
AddIceRpcServer(...)100%11100%
TryAddIceRpcServerTransport(...)0%13.45856%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Extensions.DependencyInjection/ServerServiceCollectionExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceRpc.Extensions.DependencyInjection.Internal;
 4using IceRpc.Transports;
 5using IceRpc.Transports.Quic;
 6using IceRpc.Transports.Tcp;
 7using Microsoft.Extensions.DependencyInjection;
 8using Microsoft.Extensions.DependencyInjection.Extensions;
 9using Microsoft.Extensions.Logging;
 10using Microsoft.Extensions.Options;
 11using System.Net.Quic;
 12
 13namespace IceRpc.Extensions.DependencyInjection;
 14
 15/// <summary>Provides extension methods for <see cref="IServiceCollection" /> to add a <see cref="Server" />.</summary>
 16public static class ServerServiceCollectionExtensions
 17{
 18    /// <summary>Adds a <see cref="Server" /> with the specified dispatch pipeline to this service collection; you can
 19    /// specify the server's options by injecting an <see cref="IOptions{T}" /> of <see cref="ServerOptions" />.
 20    /// </summary>
 21    /// <param name="services">The service collection to add services to.</param>
 22    /// <param name="dispatcher">The dispatch pipeline.</param>
 23    /// <returns>The service collection.</returns>
 24    /// <example>
 25    /// The following code adds a Server singleton to the service collection.
 26    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 27    /// region="DefaultServer" lang="csharp" />
 28    /// The resulting singleton is a default server: it uses the default server address and the default multiplexed
 29    /// transport (QUIC). If you want to customize this server, add an <see cref="IOptions{T}" /> of
 30    /// <see cref="ServerOptions" /> to your DI container:
 31    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 32    /// region="ServerWithOptions" lang="csharp" />
 33    /// You can also inject a server transport:
 34    /// <list type="bullet">
 35    /// <item><description>an <see cref="IDuplexServerTransport" /> for the ice protocol</description></item>
 36    /// <item><description>an <see cref="IMultiplexedServerTransport" /> for the icerpc protocol</description></item>
 37    /// </list>
 38    ///
 39    /// For example, you can add a Slic over TCP server as follows:
 40    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 41    /// region="ServerWithSlic" lang="csharp" />
 42    /// If you want to customize the options of the default transport (QUIC), you just need to inject
 43    /// an <see cref="IOptions{T}" /> of <see cref="QuicServerTransportOptions" />.
 44    /// </example>
 45    public static IServiceCollection AddIceRpcServer(this IServiceCollection services, IDispatcher dispatcher) =>
 046        services.AddIceRpcServer(optionsName: Options.DefaultName, dispatcher);
 47
 48    /// <summary>Adds a <see cref="Server" /> to this service collection and configures the dispatch pipeline of this
 49    /// server; you can specify the server's options by injecting an <see cref="IOptions{T}" /> of
 50    /// <see cref="ServerOptions" />.
 51    /// </summary>
 52    /// <param name="services">The service collection to add services to.</param>
 53    /// <param name="configure">The action to configure the dispatch pipeline using an
 54    /// <see cref="IDispatcherBuilder" />.</param>
 55    /// <returns>The service collection.</returns>
 56    /// <remarks>The dispatch pipeline built by this method is not registered in the DI container.</remarks>
 57    /// <example>
 58    /// The following code builds a dispatch pipeline and adds a server with this dispatch pipeline to the service
 59    /// collection.
 60    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 61    /// region="ServerWithDispatcherBuilder"
 62    /// lang="csharp" />
 63    /// See also <see cref="AddIceRpcServer(IServiceCollection, IDispatcher)" />.
 64    /// </example>
 65    public static IServiceCollection AddIceRpcServer(
 66        this IServiceCollection services,
 67        Action<IDispatcherBuilder> configure) =>
 268        services.AddIceRpcServer(optionsName: Options.DefaultName, configure);
 69
 70    /// <summary>Adds a <see cref="Server" /> to this service collection; you specify the server's options by injecting
 71    /// an <see cref="IOptions{T}" /> of <see cref="ServerOptions" />.</summary>
 72    /// <param name="services">The service collection to add services to.</param>
 73    /// <returns>The service collection.</returns>
 74    /// <remarks>You need to set a least the dispatcher in the injected options.</remarks>
 75    public static IServiceCollection AddIceRpcServer(this IServiceCollection services) =>
 2376        services.AddIceRpcServer(Options.DefaultName);
 77
 78    /// <summary>Adds a <see cref="Server" /> with the specified dispatch pipeline to this service collection; you can
 79    /// specify the server's options by injecting an <see cref="IOptionsMonitor{T}" /> of <see cref="ServerOptions" />
 80    /// named <paramref name="optionsName" />.</summary>
 81    /// <param name="services">The service collection to add services to.</param>
 82    /// <param name="optionsName">The name of the options instance.</param>
 83    /// <param name="dispatcher">The dispatch pipeline of the server.</param>
 84    /// <returns>The service collection.</returns>
 85    /// <example>
 86    /// A server application may need to host multiple <see cref="Server" /> instances, each with its own options. A
 87    /// typical example is when you want to accept requests from clients over both the icerpc protocol and the ice
 88    /// protocol. This overload allows you to add two (or more) server singletons, each with its own options:
 89    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 90    /// region="ServerWithNamedOptions" lang="csharp" />
 91    /// See also <see cref="AddIceRpcServer(IServiceCollection, IDispatcher)" />.
 92    /// </example>
 93    public static IServiceCollection AddIceRpcServer(
 94        this IServiceCollection services,
 95        string optionsName,
 96        IDispatcher dispatcher)
 097    {
 098        services.AddOptions<ServerOptions>(optionsName).Configure(
 099            options => options.ConnectionOptions.Dispatcher = dispatcher);
 0100        return services.AddIceRpcServer(optionsName);
 0101    }
 102
 103    /// <summary>Adds a <see cref="Server" /> to this service collection and configures the dispatch pipeline of this
 104    /// server; you can specify the server's options by injecting an <see cref="IOptionsMonitor{T}" /> of
 105    /// <see cref="ServerOptions" /> named <paramref name="optionsName" />.</summary>
 106    /// <param name="services">The service collection to add services to.</param>
 107    /// <param name="optionsName">The name of the options instance.</param>
 108    /// <param name="configure">The action to configure the dispatch pipeline using an
 109    /// <see cref="IDispatcherBuilder" />.</param>
 110    /// <returns>The service collection.</returns>
 111    /// <remarks>The dispatch pipeline built by this method is not registered in the DI container.</remarks>
 112    /// <seealso cref="AddIceRpcServer(IServiceCollection, string, IDispatcher)" />
 113    public static IServiceCollection AddIceRpcServer(
 114        this IServiceCollection services,
 115        string optionsName,
 116        Action<IDispatcherBuilder> configure) =>
 10117        services
 10118            .TryAddIceRpcServerTransport()
 10119            .AddSingleton(provider =>
 10120            {
 10121                var dispatcherBuilder = new DispatcherBuilder(provider);
 10122                configure(dispatcherBuilder);
 10123
 10124                ServerOptions options = provider.GetRequiredService<IOptionsMonitor<ServerOptions>>().Get(optionsName);
 10125                options.ConnectionOptions.Dispatcher = dispatcherBuilder.Build();
 10126
 10127                return new Server(
 10128                    options,
 10129                    provider.GetRequiredService<IDuplexServerTransport>(),
 10130                    provider.GetRequiredService<IMultiplexedServerTransport>(),
 10131                    provider.GetService<ILogger<Server>>());
 20132            });
 133
 134    /// <summary>Adds a <see cref="Server" /> to this service collection; you specify the server's options by injecting
 135    /// an <see cref="IOptionsMonitor{T}" /> of <see cref="ServerOptions" /> named <paramref name="optionsName" />.
 136    /// </summary>
 137    /// <param name="services">The service collection to add services to.</param>
 138    /// <param name="optionsName">The name of the options instance.</param>
 139    /// <returns>The service collection.</returns>
 140    /// <remarks>You need to set a least the dispatcher in the injected options.</remarks>
 141    /// <seealso cref="AddIceRpcServer(IServiceCollection, string, IDispatcher)" />
 142    public static IServiceCollection AddIceRpcServer(this IServiceCollection services, string optionsName) =>
 23143        services
 23144            .TryAddIceRpcServerTransport()
 23145            .AddSingleton(provider =>
 43146                new Server(
 43147                    provider.GetRequiredService<IOptionsMonitor<ServerOptions>>().Get(optionsName),
 43148                    provider.GetRequiredService<IDuplexServerTransport>(),
 43149                    provider.GetRequiredService<IMultiplexedServerTransport>(),
 43150                    provider.GetService<ILogger<Server>>()));
 151
 152    private static IServiceCollection TryAddIceRpcServerTransport(this IServiceCollection services)
 33153    {
 154        // The default duplex transport is TCP.
 33155        services
 33156           .AddOptions()
 33157           .TryAddSingleton<IDuplexServerTransport>(
 33158               provider => new TcpServerTransport(
 33159                   provider.GetRequiredService<IOptions<TcpServerTransportOptions>>().Value));
 160
 33161        services
 33162            .TryAddSingleton<IMultiplexedServerTransport>(
 33163                provider =>
 0164                {
 0165                    if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsWindows())
 0166                    {
 0167                        if (QuicListener.IsSupported)
 0168                        {
 0169                            return new QuicServerTransport(
 0170                                provider.GetRequiredService<IOptions<QuicServerTransportOptions>>().Value);
 33171                        }
 0172                        throw new NotSupportedException(
 0173                            "The default QUIC server transport is not available on this system. Please review the Platfo
 33174                    }
 0175                    throw new PlatformNotSupportedException(
 0176                        "The default QUIC server transport is not supported on this platform. You need to register an IM
 33177                });
 178
 33179        return services;
 33180    }
 181}