Example #1
0
        /// <summary>
        /// Add the main reactive services components, including swagger generation
        /// </summary>
        /// <param name="services"></param>
        /// <param name="builderDelegate"></param>
        /// <returns></returns>
        public static IServiceCollection AddReactiveServices(this IServiceCollection services,
                                                             Action <IReactiveServicesBuilder> builderDelegate, ReactiveServicesOption options)
        {
            services.AddSingleton(new ReactiveServicesOptions(options));

            // Add reactive services core
            var builder = new ReactiveServicesBuilder();

            builderDelegate(builder);
            services.AddSingleton(builder.Build(services));

            // Optionally, expose reactive services via API
            if (options.HasFlag(ReactiveServicesOption.WithApi))
            {
                // Routing for mapping HTTP URLs in Kestrel
                services.AddRouting();

                // Swagger generation
                if (options.HasFlag(ReactiveServicesOption.WithSwagger))
                {
                    services.TryAddSingleton <IApiDescriptionGroupCollectionProvider, ReactiveServicesApiDescriptionGroupProvider>();
                    services.AddSwaggerGen(c =>
                    {
                        c.DocumentFilter <ReactiveServicesApiDescriptionsDocumentFilter>();
                        c.SwaggerDoc("v1", new Info()
                        {
                            Title   = "My Reactive Services",
                            Version = "v1"
                        });
                    });
                }
            }

            return(services);
        }
Example #2
0
        public static IApplicationBuilder UseReactiveServices(this IApplicationBuilder app)
        {
            var services         = app.ApplicationServices;
            var reactiveServices = services.GetService <IReactiveServices>();

            void ServiceIterator(Action <Service, Type> x)
            {
                foreach (var(serviceType, _) in reactiveServices)
                {
                    x((Service)services.GetService(serviceType), serviceType);
                }
            }

            // Register any service bound topics
            if (Options.HasFlag(ReactiveServicesOption.WithTopics))
            {
                ServiceIterator((service, serviceType) =>
                {
                    foreach (var topic in service.Descriptor.Topics)
                    {
                        RegisterTopic(
                            topic,
                            service,
                            services.GetService <ISerializer>(),
                            services.GetService <IMessagePropertyExtractor>(),
                            app.ApplicationServices.GetService <ActorSystem>()
                            );
                    }
                });
            }

            app.UseWebSockets();

            // Build the API components
            if (Options.HasFlag(ReactiveServicesOption.WithApi))
            {
                var router = new RouteBuilder(app);

                // Register all calls for the services
                ServiceIterator((service, serviceType) =>
                {
                    foreach (var call in service.Descriptor.Calls)
                    {
                        switch (call.CallId)
                        {
                        case RestCallId r:
                            RegisterCall(router, service, serviceType, call);
                            break;

                        case StreamCallId s:
                            RegisterStream(router, service, serviceType, call, app);
                            break;

                        default:
                            throw new Exception("Unknown call type");
                        }
                    }
                });

                // Visualization components
                if (Options.HasFlag(ReactiveServicesOption.WithVisualizer))
                {
                    AddVisualizer(router);
                }

                // Build the API
                var routes = router.Build();
                app.UseRouter(routes);

                // Optionally, add swagger components
                if (Options.HasFlag(ReactiveServicesOption.WithSwagger))
                {
                    var config             = services.GetService <IConfiguration>();
                    var swaggerDocsApiName = config.GetValue <string>("SwaggerDocs:ApiName", "My API V1");

                    app.UseSwagger();
                    app.UseSwaggerUI(x =>
                    {
                        x.SwaggerEndpoint("/swagger/v1/swagger.json", swaggerDocsApiName);
                        x.RoutePrefix = string.Empty;
                    });
                }
            }

            return(app);
        }