private static IServiceCollection AddRazorComponentsCore(
            IServiceCollection services,
            Type startupType)
        {
            AddStandardRazorComponentsServices(services);

            if (startupType != null)
            {
                // Call TStartup's ConfigureServices method immediately
                var startup = Activator.CreateInstance(startupType);
                var wrapper = new ConventionBasedStartup(startup);
                wrapper.ConfigureServices(services);

                // Configure the circuit factory to call a startup action when each
                // incoming connection is established. The startup action is "call
                // TStartup's Configure method".
                services.Configure <DefaultCircuitFactoryOptions>(circuitFactoryOptions =>
                {
                    var endpoint = BlazorHub.DefaultPath; // TODO: allow configuring this
                    if (circuitFactoryOptions.StartupActions.ContainsKey(endpoint))
                    {
                        throw new InvalidOperationException(
                            "Multiple Components app entries are configured to use " +
                            $"the same endpoint '{endpoint}'.");
                    }

                    circuitFactoryOptions.StartupActions.Add(endpoint, builder =>
                    {
                        wrapper.Configure(builder, builder.Services);
                    });
                });
            }

            return(services);
        }
Exemple #2
0
        /// <summary>
        /// Registers Server-Side Blazor in the pipeline.
        /// </summary>
        /// <param name="builder">The <see cref="IApplicationBuilder"/>.</param>
        /// <param name="startupType">A Blazor startup type.</param>
        /// <returns>The <see cref="IApplicationBuilder"/>.</returns>
        public static IApplicationBuilder UseServerSideBlazor(
            this IApplicationBuilder builder,
            Type startupType)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (startupType == null)
            {
                throw new ArgumentNullException(nameof(startupType));
            }

            var startup = builder.ApplicationServices.GetRequiredService(startupType);
            var wrapper = new ConventionBasedStartup(startup);
            Action <IBlazorApplicationBuilder> configure = (b) =>
            {
                wrapper.Configure(b, b.Services);
            };

            UseServerSideBlazorCore(builder, configure);

            builder.UseBlazor(new BlazorOptions()
            {
                ClientAssemblyPath = startupType.Assembly.Location,
            });

            return(builder);
        }
        private static IServiceCollection AddServerSideBlazorCore(
            IServiceCollection services,
            Type startupType,
            Action <ServerSideBlazorOptions> configure)
        {
            services.AddSingleton <CircuitFactory, DefaultCircuitFactory>();
            services.AddScoped <ICircuitAccessor, DefaultCircuitAccessor>();
            services.AddScoped <Circuit>(s => s.GetRequiredService <ICircuitAccessor>().Circuit);

            services.AddScoped <IJSRuntimeAccessor, DefaultJSRuntimeAccessor>();
            services.AddScoped <IJSRuntime>(s => s.GetRequiredService <IJSRuntimeAccessor>().JSRuntime);

            services.AddScoped <IUriHelper, RemoteUriHelper>();

            services.AddSignalR().AddMessagePackProtocol(options =>
            {
                // TODO: Enable compression, either by having SignalR use
                // LZ4MessagePackSerializer instead of MessagePackSerializer,
                // or perhaps by compressing the RenderBatch bytes ourselves
                // and then using https://github.com/nodeca/pako in JS to decompress.
                options.FormatterResolvers.Insert(0, new RenderBatchFormatterResolver());
            });

            if (startupType != null)
            {
                // Make sure we only create a single instance of the startup type. We can register
                // it in the services so we can retrieve it later when creating the middlware.
                var startup = Activator.CreateInstance(startupType);
                services.AddSingleton(startupType, startup);

                // We don't need to reuse the wrapper, it's not stateful.
                var wrapper = new ConventionBasedStartup(startup);
                wrapper.ConfigureServices(services);
            }

            if (configure != null)
            {
                services.Configure(configure);
            }

            return(services);
        }