using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using xCommons.Extensions; using xExceptions.Constants; using xPushService.Configurations; using xPushService.Constants; using xPushService.Helpers; using xPushService.Providers; namespace xPushService.DI { public static partial class XDIHelperExtension { /// /// Extract Module Configuration from provided IConfiguration /// /// /// an instance of XPushServiceConfiguration public static XPushServiceConfiguration GetXPushServiceConfiguration(this IConfiguration config) { // var xPushConfigSection = config.GetSection(XPushServiceConstants.XConfigurationNodes.XPushServiceConfiguration); return xPushConfigSection.Get(); } /// /// Register XPushServiceHelper ... /// /// /// public static void AddXPushServiceHelper( this IServiceCollection services, XPushServiceHelper helper ) { // // Validate Args ... if (helper.IsNull()) { // Log("AddXPushServiceHelper failed, helper not provided ..."); throw XException.InvalidArgs.ToException(); } // // Register Helper ... services.AddSingleton(helper); } /// /// Register Module Provided Service on DI /// /// /// /// public static void AddXPushService( this IServiceCollection services, IConfiguration config, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // AddPushService( services, config.GetXPushServiceConfiguration(), lifeTime ); } /// /// Register Module Provided Service on DI /// /// /// /// public static void AddXPushService( this IServiceCollection services, XPushServiceConfiguration config, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // AddPushService( services, config, lifeTime ); } /// /// Use Module Middlewares on Application Builder /// /// /// public static void UseXPushService( this IApplicationBuilder app, XPushServiceHelper helper ) { // // Validate Args ... var isHelperExists = !helper.IsNull(); if (!isHelperExists) { // Log("AddXPushServiceHelper failed, helper not provided ..."); throw XException.InvalidArgs.ToException(); } // // Create an Scope for Accessing Registered Services ... using (var scope = app.ApplicationServices.CreateScope()) { // // try to Retrieve Configuration .... var config = scope.ServiceProvider.GetService(); if ( config.IsNull() || config.BaseRoute.IsNullOrEmpty() || config.BaseRoute.Trim().IsNullOrEmpty() ) { // Log("AddXPushServiceHelper failed, Configuration not provided ..."); throw XException.InvalidConfiguration.ToException(); } // #region Normalize Routes ... // // Base Reoute ... config.BaseRoute = config.BaseRoute.ToNormalString(); if (!config.BaseRoute.StartsWith("/")) { config.BaseRoute = "/" + config.BaseRoute; } #endregion // // add XPushService Hub to Helper ... // var hubRoutes = new List(); // // Try to Register Hubs ... // // Use SignalR in App ... app.UseSignalR(routes => { // helper.GetHubs().ForEach(hubDescriptor => { // var hubRoute = config.BaseRoute + "/" + hubDescriptor.Route; hubRoutes.Add(hubRoute); // try { // Type routesType = routes.GetType(); MethodInfo mapHubMethod = routesType .GetMethods() .SingleOrDefault(m => m.Name == "MapHub" && m.GetParameters().Length == 1 ); if (mapHubMethod.IsNull()) { throw XException.ActionFailed.ToException(); } // object[] genericMapHubMethodArgs = { new PathString(hubRoute) }; MethodInfo genericMapHubMethod = mapHubMethod.MakeGenericMethod(hubDescriptor.Hub); genericMapHubMethod.Invoke(routes, genericMapHubMethodArgs); // Log($"Register {hubDescriptor.Hub} Hub: {hubRoute}"); } catch { throw; } }); }); } } // #region Private ... /// /// a LogTag for XPushService ... /// private static string XLogTag = "XPushService"; /// /// print a log in Console ... /// /// private static void Log(string message) { Console.WriteLine($"{XLogTag} => {message}"); } /// /// Register Push Service ... /// /// /// /// private static void AddPushService( IServiceCollection services, XPushServiceConfiguration config, ServiceLifetime lifeTime ) { // #region Validate Args ... // var exception = XException.InvalidArgs.ToException(); ; // // Services ... var isServicesExists = !services.IsNull(); if (!isServicesExists) { // Log("AddXPushServiceHelper failed, services not provided ..."); throw exception; } // // Config ... var isConfigExists = !config.IsNull(); if (!isConfigExists) { // Log("AddXPushServiceHelper failed, configuration not provided ..."); throw exception; } // // Lifetime ... var isLifetimeExists = !lifeTime.IsNull(); if (!isLifetimeExists) { // Log("AddXPushServiceHelper failed, lifetime not provided ..."); throw exception; } #endregion // // Register XPushService Configuration ... services.AddSingleton(config); // // Register SignalR ... var builder = services.AddSignalR(options => { options.KeepAliveInterval = TimeSpan.FromSeconds(10); options.ClientTimeoutInterval = TimeSpan.FromSeconds(10); }); // // Add NewtonSoftJson Protocol ... builder.AddNewtonsoftJsonProtocol(x => { x.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; x.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // // Register XPushServiceUserNameProvider ... services.AddSingleton(); // // add Message Protocol Support ... if (config.AddSupportMessageProtocol) { builder.AddMessagePackProtocol(); } } #endregion } }