using System; using GraphQL.Server; using GraphQL.Types; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using MySql.EntityFrameworkCore.Extensions; using xCommons.Extensions; using xDataService.Constants; using xDataService.Db; using xDataService.EFRepositories; using xDataService.Events; using xDataService.Extensions; using xDataService.GraphQL; using xDataService.InMemRepositories; using xDataService.Interfaces; using xDataService.Models; using xDataService.MongoRepositories; using xDataService.Providers; using xExceptions.Constants; using xModels.Base; namespace xDataService.Helpers { public static class XDataServiceHelper { /// /// Register DbContext ... /// /// /// /// /// public static void AddXDbContext( IServiceCollection source, XDatabaseDescriptor databaseDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TContext : XDbContext { // var isValid = databaseDescriptor.IsValid() && databaseDescriptor.HasProvider(); if (!isValid) { XException.InvalidConfiguration.Throw(); } // switch (databaseDescriptor.Provider) { // // MySQL ... case XDbProviders.MySQL: // source.AddEntityFrameworkMySQL(); source.AddDbContext(cfg => { // cfg.UseMySQL( databaseDescriptor.ConnectionString, databaseDescriptor.OptionsBuilder ); }, lifetime); break; // // SQLite ... case XDbProviders.SQLite: // source.AddEntityFrameworkSqlite(); source.AddDbContext(cfg => { // cfg.UseSqlite( databaseDescriptor.ConnectionString, databaseDescriptor.OptionsBuilder ); }, lifetime); break; // // SQLServer ... case XDbProviders.SQLServer: // source.AddEntityFrameworkSqlServer(); source.AddDbContext(cfg => { // cfg.UseSqlServer( databaseDescriptor.ConnectionString, databaseDescriptor.OptionsBuilder ); }, lifetime); break; // // Mongo DB ... case XDbProviders.MongoDB: // #region XBaseEntity Mappers ... // // Map ID as BsonId here ... BsonClassMap.RegisterClassMap>(cm => { // cm.AutoMap(); cm.MapIdMember(c => c.Id); }); BsonClassMap.RegisterClassMap>(cm => { // cm.AutoMap(); cm.MapIdMember(c => c.Id); }); BsonClassMap.RegisterClassMap>(cm => { // cm.AutoMap(); cm.MapIdMember(c => c.Id); }); BsonClassMap.RegisterClassMap>(cm => { // cm.AutoMap(); cm.MapIdMember(c => c.Id); }); #endregion // // Check Has Convention Packs ... isValid = databaseDescriptor.HasConventionPacks(); if (isValid) { // ConventionRegistry.Register( nameof( databaseDescriptor.ConventionPacks ), databaseDescriptor.ConventionPacks, type => !type.FullName .IsNullOrEmpty() ); } break; } // isValid = databaseDescriptor.Provider == XDbProviders.MySQL || databaseDescriptor.Provider == XDbProviders.SQLite || databaseDescriptor.Provider == XDbProviders.SQLServer; if (isValid) { // AddXUnitOfWorks( source, lifetime ); } } // #region Repository ... /// /// Register Repository ... /// /// /// /// /// /// /// public static void AddXRepository( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TEntity : XBaseEntity { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TEntity : XBaseEntity where TKeyGeneratorService : IXKeyGenerator where TKeyGeneratorImplementation : XKeyGenerator { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TEntity : XBaseEntity where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } // // Register Events ... isValid = repositoryDescriptor.HasEvents(); if (isValid) { // AddXEvents( source, repositoryDescriptor, lifetime ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } // // Register Events ... isValid = repositoryDescriptor.HasEvents(); if (isValid) { // AddXEvents( source, repositoryDescriptor, lifetime ); } // // Register Graph ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // AddXGraphQL( source, repositoryDescriptor, lifetime ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation >( IServiceCollection source, XInMemoryRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TRepositoryImplementation : XBaseInMemoryRepositoy where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } // // Register Events ... isValid = repositoryDescriptor.HasEvents(); if (isValid) { // AddXEvents( source, repositoryDescriptor, lifetime ); } // // Register Graph ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // AddXGraphQL( source, repositoryDescriptor, lifetime ); } // // Register Repository ... isValid = repositoryDescriptor.HasRepository(); if (isValid) { // source.Add( new ServiceDescriptor( repositoryDescriptor.RepositoryService, repositoryDescriptor.RepositoryImplementation, lifetime ) ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation >( IServiceCollection source, XMongoRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TRepositoryImplementation : XBaseMongoRepository where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } // // Register Events ... isValid = repositoryDescriptor.HasEvents(); if (isValid) { // AddXEvents( source, repositoryDescriptor, lifetime ); } // // Register Graph ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // AddXGraphQL( source, repositoryDescriptor, lifetime ); } // // Register Repository ... isValid = repositoryDescriptor.HasRepository(); if (isValid) { // source.Add( new ServiceDescriptor( repositoryDescriptor.RepositoryService, repositoryDescriptor.RepositoryImplementation, lifetime ) ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void AddXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TContext >( IServiceCollection source, XEFRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TGraphSchema : Schema where TContext : XDbContext where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TRepositoryImplementation : XBaseEFRepository where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // Register KeyGenerator ... isValid = repositoryDescriptor.HasKeyGenerator(); if (isValid) { // AddXKeyGenerator( source, repositoryDescriptor, lifetime ); } // // Register Events ... isValid = repositoryDescriptor.HasEvents(); if (isValid) { // AddXEvents( source, repositoryDescriptor, lifetime ); } // // Register Graph ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // AddXGraphQL( source, repositoryDescriptor, lifetime ); } // // Register Repository ... isValid = repositoryDescriptor.HasRepository(); if (isValid) { // source.Add( new ServiceDescriptor( repositoryDescriptor.RepositoryService, repositoryDescriptor.RepositoryImplementation, lifetime ) ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void UseXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation >( IApplicationBuilder source, XInMemoryRepositoryDescriptor repositoryDescriptor ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TRepositoryImplementation : XBaseInMemoryRepositoy where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // GraphQL ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // UseXGraphQL( source, repositoryDescriptor ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void UseXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation >( IApplicationBuilder source, XMongoRepositoryDescriptor repositoryDescriptor ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TRepositoryImplementation : XBaseMongoRepository where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // GraphQL ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // UseXGraphQL( source, repositoryDescriptor ); } } /// /// Register Repository ... /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static void UseXRepository< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TContext >( IApplicationBuilder source, XEFRepositoryDescriptor repositoryDescriptor ) where TGraphSchema : Schema where TContext : XDbContext where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TEventsService : IXBaseRepositoryEvents where TKeyGeneratorService : IXKeyGenerator where TRepositoryService : IXBaseRepository where TEventsImplementation : XBaseRepositoryEvents where TKeyGeneratorImplementation : XKeyGenerator where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TRepositoryImplementation : XBaseEFRepository where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // var isValid = repositoryDescriptor.IsValid(); if (!isValid) { return; } // // GraphQL ... isValid = repositoryDescriptor.HasGraphSupport(); if (isValid) { // UseXGraphQL( source, repositoryDescriptor ); } } #endregion // #region Private ... /// /// Register Unit of Works ... /// /// /// /// public static void AddXUnitOfWorks( IServiceCollection source, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TContext : XDbContext { // source.Add( new ServiceDescriptor( typeof(IXUnitOfWorks), typeof(XUnitOfWorks), lifetime ) ); } /// /// Register Key Generator Service ... /// /// /// /// /// /// /// /// /// public static void AddXKeyGenerator< TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TEntity : XBaseEntity where TKeyGeneratorService : IXKeyGenerator where TKeyGeneratorImplementation : XKeyGenerator { // // Validate ... var isValid = !source.IsNull() && !repositoryDescriptor.IsNull() && !repositoryDescriptor.KeyGeneratorService.IsNull() && !repositoryDescriptor.KeyGeneratorImplementation.IsNull(); if (!isValid) { return; } // // Register ... source.Add( new ServiceDescriptor( repositoryDescriptor.KeyGeneratorService, repositoryDescriptor.KeyGeneratorImplementation, lifetime ) ); } /// /// Register Events Service ... /// /// /// /// /// /// /// /// /// public static void AddXEvents< TEntity, TKey, TEventsService, TEventsImplementation >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TEntity : XBaseEntity where TEventsService : IXBaseRepositoryEvents where TEventsImplementation : XBaseRepositoryEvents { // // Validate ... var isValid = !source.IsNull() && !repositoryDescriptor.IsNull() && !repositoryDescriptor.EventsService.IsNull() && !repositoryDescriptor.EventsImplementation.IsNull(); if (!isValid) { return; } // // Register ... source.Add( new ServiceDescriptor( repositoryDescriptor.EventsService, repositoryDescriptor.EventsImplementation, lifetime ) ); } /// /// Register GraphQL Service ... /// /// /// /// /// /// /// /// /// /// /// /// /// public static void AddXGraphQL< TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema >( IServiceCollection source, XRepositoryDescriptor repositoryDescriptor, ServiceLifetime lifetime = ServiceLifetime.Scoped ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // // Validate ... var isValid = !source.IsNull() && !repositoryDescriptor.IsNull() && !repositoryDescriptor.GraphType.IsNull() && !repositoryDescriptor.GraphQuery.IsNull() && !repositoryDescriptor.GraphSchema.IsNull() && !repositoryDescriptor.GraphTypeKey.IsNull() && !repositoryDescriptor.GraphTypeHelperService.IsNull() && !repositoryDescriptor.GraphTypeHelperImplementation.IsNull(); if (!isValid) { return; } // // Register Graph Schema ... source.Add( new ServiceDescriptor( repositoryDescriptor.GraphSchema, repositoryDescriptor.GraphSchema, lifetime ) ); // // Register Graph Query ... source.Add( new ServiceDescriptor( repositoryDescriptor.GraphQuery, repositoryDescriptor.GraphQuery, lifetime ) ); // // Register Graph Type Helper ... source.Add( new ServiceDescriptor( repositoryDescriptor.GraphTypeHelperService, repositoryDescriptor.GraphTypeHelperImplementation, lifetime: ServiceLifetime.Singleton ) ); // // Register Graph Type ... source.Add( new ServiceDescriptor( repositoryDescriptor.GraphType, repositoryDescriptor.GraphType, ServiceLifetime.Singleton ) ); // // Register Graph Events ... source.Add( new ServiceDescriptor( typeof(XBaseGraphQLEventType), typeof(XBaseGraphQLEventType), ServiceLifetime.Singleton ) ); // // Register Graph Type Schema ... var builder = source.GetRegisteredService(); if (builder.IsNull()) { // Action options = x => { }; builder = source.AddGraphQL(options) .AddNewtonsoftJson(deserializerSettings => { }, serializerSettings => { }) .AddWebSockets() .AddDataLoader() .AddGraphTypes(); } builder.AddGraphTypes(repositoryDescriptor.GraphSchema); } /// /// Use GraphQL Middleware ... /// /// /// /// /// /// /// /// /// /// /// /// /// public static void UseXGraphQL< TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema >( IApplicationBuilder source, XRepositoryDescriptor repositoryDescriptor ) where TGraphSchema : Schema where TGraphKey : IGraphType where TEntity : XBaseEntity where TGraph : XBaseGraphObjectType where TGraphTypeHelperService : IXBaseGraphQLTypeHelper where TGraphQuery : XBaseGraphQLQuery where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper { // // Validate ... var isValid = !source.IsNull() && !repositoryDescriptor.IsNull() && !repositoryDescriptor.GraphType.IsNull() && !repositoryDescriptor.GraphQuery.IsNull() && !repositoryDescriptor.GraphSchema.IsNull() && !repositoryDescriptor.GraphTypeKey.IsNull() && !repositoryDescriptor.GraphTypeHelperService.IsNull() && !repositoryDescriptor.GraphTypeHelperImplementation.IsNull(); if (!isValid) { return; } // // Create an Scope for Services Acces ... using (var scope = source.ApplicationServices.CreateScope()) { // // Inject GraphQL Type Helper ... var helper = scope.ServiceProvider.GetService(); // source.UseGraphQL(helper.GetGraphQLPath()); source.UseGraphQLWebSockets(); } } #endregion } }