|  | 
| 16 | 16 | using Microsoft.Owin.Infrastructure; | 
| 17 | 17 | using Owin; | 
| 18 | 18 | 
 | 
| 19 |  | -namespace Microsoft.Azure.SignalR.AspNet | 
|  | 19 | +namespace Microsoft.Azure.SignalR.AspNet; | 
|  | 20 | + | 
|  | 21 | +internal class DispatcherHelper | 
| 20 | 22 | { | 
| 21 |  | -    internal class DispatcherHelper | 
|  | 23 | +    internal static ILoggerFactory GetLoggerFactory(HubConfiguration configuration) | 
| 22 | 24 |     { | 
| 23 |  | -        internal static ILoggerFactory GetLoggerFactory(HubConfiguration configuration) | 
| 24 |  | -        { | 
| 25 |  | -            var resolver = configuration.Resolver ?? throw new ArgumentException("A dependency resolver must be specified.", nameof(configuration.Resolver)); | 
| 26 |  | - | 
| 27 |  | -            // 1. check if loggerFactory is already defined | 
| 28 |  | -            var loggerFactory = resolver.Resolve<ILoggerFactory>(); | 
| 29 |  | -            if (loggerFactory != null) | 
| 30 |  | -            { | 
| 31 |  | -                return loggerFactory; | 
| 32 |  | -            } | 
| 33 |  | - | 
| 34 |  | -            // 2. check if loggingBuilder is already defined | 
| 35 |  | -            var loggingBuilder = configuration?.Resolver.Resolve<ILoggingBuilder>() ?? new DefaultLoggingBuilder(); | 
| 36 |  | -            var providers = loggingBuilder.Services?.BuildServiceProvider().GetServices<ILoggerProvider>(); | 
| 37 |  | -            if (providers != null) | 
| 38 |  | -            { | 
| 39 |  | -                loggerFactory = new LoggerFactory(providers); | 
| 40 |  | -            } | 
|  | 25 | +        var resolver = configuration.Resolver ?? throw new ArgumentException("A dependency resolver must be specified.", nameof(configuration.Resolver)); | 
| 41 | 26 | 
 | 
|  | 27 | +        // 1. check if loggerFactory is already defined | 
|  | 28 | +        var loggerFactory = resolver.Resolve<ILoggerFactory>(); | 
|  | 29 | +        if (loggerFactory != null) | 
|  | 30 | +        { | 
| 42 | 31 |             return loggerFactory; | 
| 43 | 32 |         } | 
| 44 | 33 | 
 | 
| 45 |  | -        internal static ServiceHubDispatcher PrepareAndGetDispatcher(IAppBuilder builder, HubConfiguration configuration, ServiceOptions options, string applicationName, ILoggerFactory loggerFactory) | 
|  | 34 | +        // 2. check if loggingBuilder is already defined | 
|  | 35 | +        var loggingBuilder = configuration?.Resolver.Resolve<ILoggingBuilder>() ?? new DefaultLoggingBuilder(); | 
|  | 36 | +        var providers = loggingBuilder.Services?.BuildServiceProvider().GetServices<ILoggerProvider>(); | 
|  | 37 | +        if (providers != null) | 
|  | 38 | +        { | 
|  | 39 | +            loggerFactory = new LoggerFactory(providers); | 
|  | 40 | +        } | 
|  | 41 | + | 
|  | 42 | +        return loggerFactory; | 
|  | 43 | +    } | 
|  | 44 | + | 
|  | 45 | +    internal static ServiceHubDispatcher PrepareAndGetDispatcher(IAppBuilder builder, HubConfiguration configuration, ServiceOptions options, string applicationName, ILoggerFactory loggerFactory) | 
|  | 46 | +    { | 
|  | 47 | +        // Ensure we have the conversions for MS.Owin so that | 
|  | 48 | +        // the app builder respects the OwinMiddleware base class | 
|  | 49 | +        SignatureConversions.AddConversions(builder); | 
|  | 50 | + | 
|  | 51 | +        // ServiceEndpointManager needs the logger | 
|  | 52 | +        var hubs = GetAvailableHubNames(configuration); | 
|  | 53 | + | 
|  | 54 | +        // Get the one from DI or new a default one | 
|  | 55 | +        var router = configuration.Resolver.Resolve<IEndpointRouter>() ?? new DefaultEndpointRouter(); | 
|  | 56 | + | 
|  | 57 | +        var serverNameProvider = configuration.Resolver.Resolve<IServerNameProvider>(); | 
|  | 58 | +        if (serverNameProvider == null) | 
|  | 59 | +        { | 
|  | 60 | +            serverNameProvider = new DefaultServerNameProvider(); | 
|  | 61 | +            configuration.Resolver.Register(typeof(IServerNameProvider), () => serverNameProvider); | 
|  | 62 | +        } | 
|  | 63 | + | 
|  | 64 | +        var synchronizer = configuration.Resolver.Resolve<IAccessKeySynchronizer>(); | 
|  | 65 | +        if (synchronizer == null) | 
|  | 66 | +        { | 
|  | 67 | +            synchronizer = new AccessKeySynchronizer(loggerFactory); | 
|  | 68 | +            configuration.Resolver.Register(typeof(IAccessKeySynchronizer), () => synchronizer); | 
|  | 69 | +        } | 
|  | 70 | + | 
|  | 71 | +        var endpoint = new ServiceEndpointManager(synchronizer, options, loggerFactory); | 
|  | 72 | +        configuration.Resolver.Register(typeof(IServiceEndpointManager), () => endpoint); | 
|  | 73 | + | 
|  | 74 | +        var requestIdProvider = configuration.Resolver.Resolve<IConnectionRequestIdProvider>(); | 
|  | 75 | +        if (requestIdProvider == null) | 
|  | 76 | +        { | 
|  | 77 | +            requestIdProvider = new DefaultConnectionRequestIdProvider(); | 
|  | 78 | +            configuration.Resolver.Register(typeof(IConnectionRequestIdProvider), () => requestIdProvider); | 
|  | 79 | +        } | 
|  | 80 | + | 
|  | 81 | +        builder.Use<NegotiateMiddleware>(configuration, applicationName, endpoint, router, options, serverNameProvider, requestIdProvider, loggerFactory); | 
|  | 82 | + | 
|  | 83 | +        builder.RunSignalR(configuration); | 
|  | 84 | + | 
|  | 85 | +        // Fetch the trace manager from DI and add logger provider | 
|  | 86 | +        var traceManager = configuration.Resolver.Resolve<ITraceManager>(); | 
|  | 87 | +        if (traceManager != null) | 
|  | 88 | +        { | 
|  | 89 | +            loggerFactory.AddProvider(new TraceManagerLoggerProvider(traceManager)); | 
|  | 90 | +        } | 
|  | 91 | + | 
|  | 92 | +        configuration.Resolver.Register(typeof(ILoggerFactory), () => loggerFactory); | 
|  | 93 | + | 
|  | 94 | +        // TODO: Using IOptions looks wierd, thinking of a way removing it | 
|  | 95 | +        // share the same object all through | 
|  | 96 | +        var serviceOptions = Options.Create(options); | 
|  | 97 | + | 
|  | 98 | +        // For safety, ALWAYS register abstract classes or interfaces | 
|  | 99 | +        // Some third-party DI frameworks such as Ninject, implicit self-binding concrete types: | 
|  | 100 | +        // https://github.com/ninject/ninject/wiki/dependency-injection-with-ninject#skipping-the-type-binding-bit--implicit-self-binding-of-concrete-types | 
|  | 101 | +        configuration.Resolver.Register(typeof(IOptions<ServiceOptions>), () => serviceOptions); | 
|  | 102 | + | 
|  | 103 | +        var serviceProtocol = new ServiceProtocol(); | 
|  | 104 | +        configuration.Resolver.Register(typeof(IServiceProtocol), () => serviceProtocol); | 
|  | 105 | + | 
|  | 106 | +        // allow override from tests | 
|  | 107 | +        var scm = configuration.Resolver.Resolve<IServiceConnectionManager>(); | 
|  | 108 | +        if (scm == null) | 
|  | 109 | +        { | 
|  | 110 | +            scm = new ServiceConnectionManager(applicationName, hubs); | 
|  | 111 | +            configuration.Resolver.Register(typeof(IServiceConnectionManager), () => scm); | 
|  | 112 | +        } | 
|  | 113 | + | 
|  | 114 | +        var ccm = configuration.Resolver.Resolve<IClientConnectionManagerAspNet>(); | 
|  | 115 | +        if (ccm == null) | 
| 46 | 116 |         { | 
| 47 |  | -            // Ensure we have the conversions for MS.Owin so that | 
| 48 |  | -            // the app builder respects the OwinMiddleware base class | 
| 49 |  | -            SignatureConversions.AddConversions(builder); | 
| 50 |  | - | 
| 51 |  | -            // ServiceEndpointManager needs the logger | 
| 52 |  | -            var hubs = GetAvailableHubNames(configuration); | 
| 53 |  | - | 
| 54 |  | -            // Get the one from DI or new a default one | 
| 55 |  | -            var router = configuration.Resolver.Resolve<IEndpointRouter>() ?? new DefaultEndpointRouter(); | 
| 56 |  | - | 
| 57 |  | -            var serverNameProvider = configuration.Resolver.Resolve<IServerNameProvider>(); | 
| 58 |  | -            if (serverNameProvider == null) | 
| 59 |  | -            { | 
| 60 |  | -                serverNameProvider = new DefaultServerNameProvider(); | 
| 61 |  | -                configuration.Resolver.Register(typeof(IServerNameProvider), () => serverNameProvider); | 
| 62 |  | -            } | 
| 63 |  | - | 
| 64 |  | -            var synchronizer = configuration.Resolver.Resolve<IAccessKeySynchronizer>(); | 
| 65 |  | -            if (synchronizer == null) | 
| 66 |  | -            { | 
| 67 |  | -                synchronizer = new AccessKeySynchronizer(loggerFactory); | 
| 68 |  | -                configuration.Resolver.Register(typeof(IAccessKeySynchronizer), () => synchronizer); | 
| 69 |  | -            } | 
| 70 |  | - | 
| 71 |  | -            var endpoint = new ServiceEndpointManager(synchronizer, options, loggerFactory); | 
| 72 |  | -            configuration.Resolver.Register(typeof(IServiceEndpointManager), () => endpoint); | 
| 73 |  | - | 
| 74 |  | -            var requestIdProvider = configuration.Resolver.Resolve<IConnectionRequestIdProvider>(); | 
| 75 |  | -            if (requestIdProvider == null) | 
| 76 |  | -            { | 
| 77 |  | -                requestIdProvider = new DefaultConnectionRequestIdProvider(); | 
| 78 |  | -                configuration.Resolver.Register(typeof(IConnectionRequestIdProvider), () => requestIdProvider); | 
| 79 |  | -            } | 
| 80 |  | - | 
| 81 |  | -            builder.Use<NegotiateMiddleware>(configuration, applicationName, endpoint, router, options, serverNameProvider, requestIdProvider, loggerFactory); | 
| 82 |  | - | 
| 83 |  | -            builder.RunSignalR(configuration); | 
| 84 |  | - | 
| 85 |  | -            // Fetch the trace manager from DI and add logger provider | 
| 86 |  | -            var traceManager = configuration.Resolver.Resolve<ITraceManager>(); | 
| 87 |  | -            if (traceManager != null) | 
| 88 |  | -            { | 
| 89 |  | -                loggerFactory.AddProvider(new TraceManagerLoggerProvider(traceManager)); | 
| 90 |  | -            } | 
| 91 |  | - | 
| 92 |  | -            configuration.Resolver.Register(typeof(ILoggerFactory), () => loggerFactory); | 
| 93 |  | - | 
| 94 |  | -            // TODO: Using IOptions looks wierd, thinking of a way removing it | 
| 95 |  | -            // share the same object all through | 
| 96 |  | -            var serviceOptions = Options.Create(options); | 
| 97 |  | - | 
| 98 |  | -            // For safety, ALWAYS register abstract classes or interfaces | 
| 99 |  | -            // Some third-party DI frameworks such as Ninject, implicit self-binding concrete types: | 
| 100 |  | -            // https://github.com/ninject/ninject/wiki/dependency-injection-with-ninject#skipping-the-type-binding-bit--implicit-self-binding-of-concrete-types | 
| 101 |  | -            configuration.Resolver.Register(typeof(IOptions<ServiceOptions>), () => serviceOptions); | 
| 102 |  | - | 
| 103 |  | -            var serviceProtocol = new ServiceProtocol(); | 
| 104 |  | -            configuration.Resolver.Register(typeof(IServiceProtocol), () => serviceProtocol); | 
| 105 |  | - | 
| 106 |  | -            // allow override from tests | 
| 107 |  | -            var scm = configuration.Resolver.Resolve<IServiceConnectionManager>(); | 
| 108 |  | -            if (scm == null) | 
| 109 |  | -            { | 
| 110 |  | -                scm = new ServiceConnectionManager(applicationName, hubs); | 
| 111 |  | -                configuration.Resolver.Register(typeof(IServiceConnectionManager), () => scm); | 
| 112 |  | -            } | 
| 113 |  | - | 
| 114 |  | -            var ccm = configuration.Resolver.Resolve<IClientConnectionManagerAspNet>(); | 
| 115 |  | -            if (ccm == null) | 
| 116 |  | -            { | 
| 117 |  | -                ccm = new ClientConnectionManager(configuration, loggerFactory); | 
| 118 |  | -                configuration.Resolver.Register(typeof(IClientConnectionManagerAspNet), () => ccm); | 
| 119 |  | -            } | 
| 120 |  | - | 
| 121 |  | -            var atm = new AzureTransportManager(configuration.Resolver); | 
| 122 |  | -            configuration.Resolver.Register(typeof(ITransportManager), () => atm); | 
| 123 |  | - | 
| 124 |  | -            var parser = new SignalRMessageParser(hubs, configuration.Resolver, loggerFactory.CreateLogger<SignalRMessageParser>()); | 
| 125 |  | -            configuration.Resolver.Register(typeof(IMessageParser), () => parser); | 
| 126 |  | - | 
| 127 |  | -            var smb = new ServiceMessageBus(configuration.Resolver, loggerFactory.CreateLogger<ServiceMessageBus>()); | 
| 128 |  | -            configuration.Resolver.Register(typeof(IMessageBus), () => smb); | 
| 129 |  | - | 
| 130 |  | -            var serviceEventHandler = configuration.Resolver.Resolve<IServiceEventHandler>(); | 
| 131 |  | -            if (serviceEventHandler == null) | 
| 132 |  | -            { | 
| 133 |  | -                serviceEventHandler = new DefaultServiceEventHandler(loggerFactory); | 
| 134 |  | -                configuration.Resolver.Register(typeof(IServiceEventHandler), () => serviceEventHandler); | 
| 135 |  | -            } | 
| 136 |  | - | 
| 137 |  | -            var cf = configuration.Resolver.Resolve<IConnectionFactory>(); | 
| 138 |  | -            if (cf == null) | 
| 139 |  | -            { | 
| 140 |  | -                var connectionFactory = new ConnectionFactory(serverNameProvider, loggerFactory); | 
| 141 |  | -                configuration.Resolver.Register(typeof(IConnectionFactory), () => cf); | 
| 142 |  | -            } | 
| 143 |  | - | 
| 144 |  | -            var scf = configuration.Resolver.Resolve<IServiceConnectionFactory>(); | 
| 145 |  | -            if (scf == null) | 
| 146 |  | -            { | 
| 147 |  | -                scf = new ServiceConnectionFactory(serviceProtocol, ccm, cf, loggerFactory, serverNameProvider, serviceEventHandler); | 
| 148 |  | -                configuration.Resolver.Register(typeof(IServiceConnectionFactory), () => scf); | 
| 149 |  | -            } | 
| 150 |  | - | 
| 151 |  | -            var sccf = new ServiceConnectionContainerFactory(scf, endpoint, router, options, loggerFactory); | 
| 152 |  | - | 
| 153 |  | -            if (hubs?.Count > 0) | 
| 154 |  | -            { | 
| 155 |  | -                return new ServiceHubDispatcher(hubs, scm, sccf, serviceOptions, loggerFactory); | 
| 156 |  | -            } | 
| 157 |  | -            else | 
| 158 |  | -            { | 
| 159 |  | -                loggerFactory.CreateLogger<DispatcherHelper>().Log(LogLevel.Warning, "No hubs found."); | 
| 160 |  | -                return null; | 
| 161 |  | -            } | 
|  | 117 | +            ccm = new ClientConnectionManager(configuration, loggerFactory); | 
|  | 118 | +            configuration.Resolver.Register(typeof(IClientConnectionManagerAspNet), () => ccm); | 
| 162 | 119 |         } | 
| 163 | 120 | 
 | 
| 164 |  | -        private static IReadOnlyList<string> GetAvailableHubNames(HubConfiguration configuration) | 
|  | 121 | +        var atm = new AzureTransportManager(configuration.Resolver); | 
|  | 122 | +        configuration.Resolver.Register(typeof(ITransportManager), () => atm); | 
|  | 123 | + | 
|  | 124 | +        var parser = new SignalRMessageParser(hubs, configuration.Resolver, loggerFactory.CreateLogger<SignalRMessageParser>()); | 
|  | 125 | +        configuration.Resolver.Register(typeof(IMessageParser), () => parser); | 
|  | 126 | + | 
|  | 127 | +        var smb = new ServiceMessageBus(configuration.Resolver, loggerFactory.CreateLogger<ServiceMessageBus>()); | 
|  | 128 | +        configuration.Resolver.Register(typeof(IMessageBus), () => smb); | 
|  | 129 | + | 
|  | 130 | +        var serviceEventHandler = configuration.Resolver.Resolve<IServiceEventHandler>(); | 
|  | 131 | +        if (serviceEventHandler == null) | 
|  | 132 | +        { | 
|  | 133 | +            serviceEventHandler = new DefaultServiceEventHandler(loggerFactory); | 
|  | 134 | +            configuration.Resolver.Register(typeof(IServiceEventHandler), () => serviceEventHandler); | 
|  | 135 | +        } | 
|  | 136 | + | 
|  | 137 | +        var cf = configuration.Resolver.Resolve<IConnectionFactory>(); | 
|  | 138 | +        if (cf == null) | 
|  | 139 | +        { | 
|  | 140 | +            var connectionFactory = new ConnectionFactory(serverNameProvider, loggerFactory); | 
|  | 141 | +            configuration.Resolver.Register(typeof(IConnectionFactory), () => cf); | 
|  | 142 | +        } | 
|  | 143 | + | 
|  | 144 | +        var scf = configuration.Resolver.Resolve<IServiceConnectionFactory>(); | 
|  | 145 | +        if (scf == null) | 
|  | 146 | +        { | 
|  | 147 | +            scf = new ServiceConnectionFactory(serviceProtocol, ccm, cf, loggerFactory, serverNameProvider, serviceEventHandler); | 
|  | 148 | +            configuration.Resolver.Register(typeof(IServiceConnectionFactory), () => scf); | 
|  | 149 | +        } | 
|  | 150 | + | 
|  | 151 | +        var sccf = new ServiceConnectionContainerFactory(scf, endpoint, router, options, loggerFactory); | 
|  | 152 | + | 
|  | 153 | +        if (hubs?.Count > 0) | 
|  | 154 | +        { | 
|  | 155 | +            return new ServiceHubDispatcher(hubs, scm, sccf, serviceOptions, loggerFactory); | 
|  | 156 | +        } | 
|  | 157 | +        else | 
|  | 158 | +        { | 
|  | 159 | +            loggerFactory.CreateLogger<DispatcherHelper>().Log(LogLevel.Warning, "No hubs found."); | 
|  | 160 | +            return null; | 
|  | 161 | +        } | 
|  | 162 | +    } | 
|  | 163 | + | 
|  | 164 | +    private static IReadOnlyList<string> GetAvailableHubNames(HubConfiguration configuration) | 
|  | 165 | +    { | 
|  | 166 | +        var hubManager = configuration.Resolver.Resolve<IHubManager>(); | 
|  | 167 | +        return hubManager?.GetHubs().Select(s => s.Name).ToList(); | 
|  | 168 | +    } | 
|  | 169 | + | 
|  | 170 | +    /// <summary> | 
|  | 171 | +    /// For compatibility issue that | 
|  | 172 | +    /// public static ILoggerFactory AddEventSourceLogger(this ILoggerFactory factory) | 
|  | 173 | +    /// is removed since Microsoft.Extensions.Logging.EventSource 3.0.0 | 
|  | 174 | +    /// </summary> | 
|  | 175 | +    private sealed class DefaultLoggingBuilder : ILoggingBuilder | 
|  | 176 | +    { | 
|  | 177 | +        public IServiceCollection Services { get; } | 
|  | 178 | + | 
|  | 179 | +        public DefaultLoggingBuilder() | 
| 165 | 180 |         { | 
| 166 |  | -            var hubManager = configuration.Resolver.Resolve<IHubManager>(); | 
| 167 |  | -            return hubManager?.GetHubs().Select(s => s.Name).ToList(); | 
|  | 181 | +            Services = new ServiceCollection(); | 
|  | 182 | +            this.AddEventSourceLogger(); | 
| 168 | 183 |         } | 
| 169 | 184 | 
 | 
| 170 |  | -        /// <summary> | 
| 171 |  | -        /// For compatibility issue that | 
| 172 |  | -        /// public static ILoggerFactory AddEventSourceLogger(this ILoggerFactory factory) | 
| 173 |  | -        /// is removed since Microsoft.Extensions.Logging.EventSource 3.0.0 | 
| 174 |  | -        /// </summary> | 
| 175 |  | -        private sealed class DefaultLoggingBuilder : ILoggingBuilder | 
|  | 185 | +        public IServiceProvider Build() | 
| 176 | 186 |         { | 
| 177 |  | -            public IServiceCollection Services { get; } | 
| 178 |  | - | 
| 179 |  | -            public DefaultLoggingBuilder() | 
| 180 |  | -            { | 
| 181 |  | -                Services = new ServiceCollection(); | 
| 182 |  | -                this.AddEventSourceLogger(); | 
| 183 |  | -            } | 
| 184 |  | - | 
| 185 |  | -            public IServiceProvider Build() | 
| 186 |  | -            { | 
| 187 |  | -                return Services.BuildServiceProvider(); | 
| 188 |  | -            } | 
|  | 187 | +            return Services.BuildServiceProvider(); | 
| 189 | 188 |         } | 
| 190 | 189 |     } | 
| 191 | 190 | } | 
0 commit comments