/// <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); }
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); }