< 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: 1856_27024993493
Line coverage
78%
Covered lines: 45
Uncovered lines: 12
Coverable lines: 57
Total lines: 184
Line coverage: 78.9%
Branch coverage
0%
Covered branches: 0
Total branches: 8
Branch coverage: 0%
Method coverage
85%
Covered methods: 6
Fully covered methods: 5
Total methods: 7
Method coverage: 85.7%
Full method coverage: 71.4%

Metrics

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

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) =>
 2576        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. Each <see cref="Server" /> registered in
 83    /// <paramref name="services" /> must use a unique options name.</param>
 84    /// <param name="dispatcher">The dispatch pipeline of the server.</param>
 85    /// <returns>The service collection.</returns>
 86    /// <example>
 87    /// A server application may need to host multiple <see cref="Server" /> instances, each with its own options. A
 88    /// typical example is when you want to accept requests from clients over both the icerpc protocol and the ice
 89    /// protocol. This overload allows you to add two (or more) server singletons, each with its own options:
 90    /// <code source="../../docfx/examples/IceRpc.Extensions.DependencyInjection.Examples/AddIceRpcServerExamples.cs"
 91    /// region="ServerWithNamedOptions" lang="csharp" />
 92    /// See also <see cref="AddIceRpcServer(IServiceCollection, IDispatcher)" />.
 93    /// </example>
 94    public static IServiceCollection AddIceRpcServer(
 95        this IServiceCollection services,
 96        string optionsName,
 97        IDispatcher dispatcher)
 298    {
 299        services.AddOptions<ServerOptions>(optionsName).Configure(
 4100            options => options.ConnectionOptions.Dispatcher = dispatcher);
 2101        return services.AddIceRpcServer(optionsName);
 2102    }
 103
 104    /// <summary>Adds a <see cref="Server" /> to this service collection and configures the dispatch pipeline of this
 105    /// server; you can specify the server's options by injecting an <see cref="IOptionsMonitor{T}" /> of
 106    /// <see cref="ServerOptions" /> named <paramref name="optionsName" />.</summary>
 107    /// <param name="services">The service collection to add services to.</param>
 108    /// <param name="optionsName">The name of the options instance. Each <see cref="Server" /> registered in
 109    /// <paramref name="services" /> must use a unique options name.</param>
 110    /// <param name="configure">The action to configure the dispatch pipeline using an
 111    /// <see cref="IDispatcherBuilder" />.</param>
 112    /// <returns>The service collection.</returns>
 113    /// <remarks>The dispatch pipeline built by this method is not registered in the DI container.</remarks>
 114    /// <seealso cref="AddIceRpcServer(IServiceCollection, string, IDispatcher)" />
 115    public static IServiceCollection AddIceRpcServer(
 116        this IServiceCollection services,
 117        string optionsName,
 118        Action<IDispatcherBuilder> configure) =>
 10119        services
 10120            .TryAddIceRpcServerTransport()
 10121            .AddSingleton(provider =>
 10122            {
 10123                var dispatcherBuilder = new DispatcherBuilder(provider);
 10124                configure(dispatcherBuilder);
 10125
 10126                ServerOptions options = provider.GetRequiredService<IOptionsMonitor<ServerOptions>>().Get(optionsName);
 10127                options.ConnectionOptions.Dispatcher = dispatcherBuilder.Build();
 10128
 10129                return new Server(
 10130                    options,
 10131                    provider.GetRequiredService<IDuplexServerTransport>(),
 10132                    provider.GetRequiredService<IMultiplexedServerTransport>(),
 10133                    provider.GetService<ILogger<Server>>());
 20134            });
 135
 136    /// <summary>Adds a <see cref="Server" /> to this service collection; you specify the server's options by injecting
 137    /// an <see cref="IOptionsMonitor{T}" /> of <see cref="ServerOptions" /> named <paramref name="optionsName" />.
 138    /// </summary>
 139    /// <param name="services">The service collection to add services to.</param>
 140    /// <param name="optionsName">The name of the options instance. Each <see cref="Server" /> registered in
 141    /// <paramref name="services" /> must use a unique options name.</param>
 142    /// <returns>The service collection.</returns>
 143    /// <remarks>You need to set at least the dispatcher in the injected options.</remarks>
 144    /// <seealso cref="AddIceRpcServer(IServiceCollection, string, IDispatcher)" />
 145    public static IServiceCollection AddIceRpcServer(this IServiceCollection services, string optionsName) =>
 27146        services
 27147            .TryAddIceRpcServerTransport()
 27148            .AddSingleton(provider =>
 51149                new Server(
 51150                    provider.GetRequiredService<IOptionsMonitor<ServerOptions>>().Get(optionsName),
 51151                    provider.GetRequiredService<IDuplexServerTransport>(),
 51152                    provider.GetRequiredService<IMultiplexedServerTransport>(),
 51153                    provider.GetService<ILogger<Server>>()));
 154
 155    private static IServiceCollection TryAddIceRpcServerTransport(this IServiceCollection services)
 37156    {
 157        // The default duplex transport is TCP.
 37158        services
 37159           .AddOptions()
 37160           .TryAddSingleton<IDuplexServerTransport>(
 37161               provider => new TcpServerTransport(
 37162                   provider.GetRequiredService<IOptions<TcpServerTransportOptions>>().Value));
 163
 37164        services
 37165            .TryAddSingleton<IMultiplexedServerTransport>(
 37166                provider =>
 0167                {
 0168                    if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsWindows())
 0169                    {
 0170                        if (QuicListener.IsSupported)
 0171                        {
 0172                            return new QuicServerTransport(
 0173                                provider.GetRequiredService<IOptions<QuicServerTransportOptions>>().Value);
 37174                        }
 0175                        throw new NotSupportedException(
 0176                            "The default QUIC server transport is not available on this system. Please review the Platfo
 37177                    }
 0178                    throw new PlatformNotSupportedException(
 0179                        "The default QUIC server transport is not supported on this platform. You need to register an IM
 37180                });
 181
 37182        return services;
 37183    }
 184}