internal static ServiceHubDispatcher PrepareAndGetDispatcher()

in src/Microsoft.Azure.SignalR.AspNet/DispatcherHelper.cs [47:160]


    internal static ServiceHubDispatcher PrepareAndGetDispatcher(IAppBuilder builder, HubConfiguration configuration, ServiceOptions options, string applicationName, ILoggerFactory loggerFactory)
    {
        // Ensure we have the conversions for MS.Owin so that
        // the app builder respects the OwinMiddleware base class
        SignatureConversions.AddConversions(builder);

        // ServiceEndpointManager needs the logger
        var hubs = GetAvailableHubNames(configuration);

        // Get the one from DI or new a default one
        var router = configuration.Resolver.Resolve<IEndpointRouter>() ?? new DefaultEndpointRouter();

        var serverNameProvider = configuration.Resolver.Resolve<IServerNameProvider>();
        if (serverNameProvider == null)
        {
            serverNameProvider = new DefaultServerNameProvider();
            configuration.Resolver.Register(typeof(IServerNameProvider), () => serverNameProvider);
        }

        var endpoint = new ServiceEndpointManager(options, loggerFactory);
        configuration.Resolver.Register(typeof(IServiceEndpointManager), () => endpoint);

        var requestIdProvider = configuration.Resolver.Resolve<IConnectionRequestIdProvider>();
        if (requestIdProvider == null)
        {
            requestIdProvider = new DefaultConnectionRequestIdProvider();
            configuration.Resolver.Register(typeof(IConnectionRequestIdProvider), () => requestIdProvider);
        }

        builder.Use<NegotiateMiddleware>(configuration, applicationName, endpoint, router, options, serverNameProvider, requestIdProvider, loggerFactory);

        builder.RunSignalR(configuration);

        // Fetch the trace manager from DI and add logger provider
        var traceManager = configuration.Resolver.Resolve<ITraceManager>();
        if (traceManager != null)
        {
            loggerFactory.AddProvider(new TraceManagerLoggerProvider(traceManager));
        }

        configuration.Resolver.Register(typeof(ILoggerFactory), () => loggerFactory);

        // TODO: Using IOptions looks wierd, thinking of a way removing it
        // share the same object all through
        var serviceOptions = Options.Create(options);

        // For safety, ALWAYS register abstract classes or interfaces
        // Some third-party DI frameworks such as Ninject, implicit self-binding concrete types:
        // https://github.com/ninject/ninject/wiki/dependency-injection-with-ninject#skipping-the-type-binding-bit--implicit-self-binding-of-concrete-types
        configuration.Resolver.Register(typeof(IOptions<ServiceOptions>), () => serviceOptions);

        var serviceProtocol = new ServiceProtocol();
        configuration.Resolver.Register(typeof(IServiceProtocol), () => serviceProtocol);

        // allow override from tests
        var scm = configuration.Resolver.Resolve<IServiceConnectionManager>();
        if (scm == null)
        {
            scm = new ServiceConnectionManager(applicationName, hubs);
            configuration.Resolver.Register(typeof(IServiceConnectionManager), () => scm);
        }

        var ccm = configuration.Resolver.Resolve<IClientConnectionManagerAspNet>();
        if (ccm == null)
        {
            ccm = new ClientConnectionManager(configuration, loggerFactory);
            configuration.Resolver.Register(typeof(IClientConnectionManagerAspNet), () => ccm);
        }

        var atm = new AzureTransportManager(configuration.Resolver);
        configuration.Resolver.Register(typeof(ITransportManager), () => atm);

        var parser = new SignalRMessageParser(hubs, configuration.Resolver, loggerFactory.CreateLogger<SignalRMessageParser>());
        configuration.Resolver.Register(typeof(IMessageParser), () => parser);

        var smb = new ServiceMessageBus(configuration.Resolver, loggerFactory.CreateLogger<ServiceMessageBus>());
        configuration.Resolver.Register(typeof(IMessageBus), () => smb);

        var serviceEventHandler = configuration.Resolver.Resolve<IServiceEventHandler>();
        if (serviceEventHandler == null)
        {
            serviceEventHandler = new DefaultServiceEventHandler(loggerFactory);
            configuration.Resolver.Register(typeof(IServiceEventHandler), () => serviceEventHandler);
        }

        var cf = configuration.Resolver.Resolve<IConnectionFactory>();
        if (cf == null)
        {
            cf = new ConnectionFactory(serverNameProvider, loggerFactory)
            {
                ConfigureServiceConnectionWebSocketOptions = options.ConfigureServiceConnectionWebSocketOptions
            };
            configuration.Resolver.Register(typeof(IConnectionFactory), () => cf);
        }

        var scf = configuration.Resolver.Resolve<IServiceConnectionFactory>();
        if (scf == null)
        {
            scf = new ServiceConnectionFactory(serviceProtocol, ccm, cf, loggerFactory, serverNameProvider, serviceEventHandler);
            configuration.Resolver.Register(typeof(IServiceConnectionFactory), () => scf);
        }

        var sccf = new ServiceConnectionContainerFactory(scf, endpoint, router, options, loggerFactory);

        if (hubs?.Count > 0)
        {
            return new ServiceHubDispatcher(hubs, scm, sccf, serviceOptions, loggerFactory);
        }
        else
        {
            loggerFactory.CreateLogger<DispatcherHelper>().Log(LogLevel.Warning, "No hubs found.");
            return null;
        }
    }