From 34afd95640688a5837ed41e6b9a7f6e768cb835b Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 8 May 2026 04:30:04 +0330 Subject: [PATCH] last ... --- Configuration/XDataBaseConfiguration.cs | 22 + Configuration/XDataServiceConfiguration.cs | 37 +- Configuration/XDbProviderConfigurations.cs | 8 - DI/XDIHelperExtension.cs | 722 +++++------------- .../XDataServiceConfigurationExtensions.cs | 6 +- GraphQL/XBaseGraphQLQuery.cs | 178 +++-- GraphQL/XBaseGraphQLTypeHelper.cs | 164 ++-- Helpers/XDataServiceHelper.cs | 79 ++ Interfaces/IXBaseGraphQLQuery.cs | 18 +- Interfaces/IXBaseGraphQLTypeHelper.cs | 30 +- Interfaces/IXBaseRepository.cs | 4 +- Interfaces/IXDatabaseDescriptor.cs | 113 +++ Interfaces/IXKeyGenerator.cs | 30 +- Models/XDatabaseDescriptor.cs | 229 ++++++ Models/XRepositoryDescriptor.cs | 63 ++ MongoRepositories/XBaseMongoRepository.cs | 8 +- Providers/XGuidKeyGenerator.cs | 6 +- Providers/XIntKeyGenerator.cs | 6 +- Providers/XStringKeyGenerator.cs | 10 +- xDataService.csproj | 2 +- 20 files changed, 1022 insertions(+), 713 deletions(-) create mode 100644 Configuration/XDataBaseConfiguration.cs delete mode 100644 Configuration/XDbProviderConfigurations.cs create mode 100644 Helpers/XDataServiceHelper.cs create mode 100644 Interfaces/IXDatabaseDescriptor.cs create mode 100644 Models/XDatabaseDescriptor.cs create mode 100644 Models/XRepositoryDescriptor.cs diff --git a/Configuration/XDataBaseConfiguration.cs b/Configuration/XDataBaseConfiguration.cs new file mode 100644 index 0000000..c43fec9 --- /dev/null +++ b/Configuration/XDataBaseConfiguration.cs @@ -0,0 +1,22 @@ +using xDataService.Constants; + +namespace xDataService.Configuration +{ + /// + /// Describe a Database ... + /// + public class XDataBaseConfiguration + { + /// + /// Provider Type ... + /// + /// + public XDbProviders Provider { get; set; } + + /// + /// Connection String which provide Requires Data to Connect to Db Provider ... + /// + /// + public string ConnectionString { get; set; } + } +} \ No newline at end of file diff --git a/Configuration/XDataServiceConfiguration.cs b/Configuration/XDataServiceConfiguration.cs index 3bbfe0d..c7d97fa 100644 --- a/Configuration/XDataServiceConfiguration.cs +++ b/Configuration/XDataServiceConfiguration.cs @@ -1,28 +1,32 @@ +using System.Collections.Generic; using xDataService.Constants; -namespace xDataService.Configuration { +namespace xDataService.Configuration +{ /// /// Represent Configurations of DataService Module ... /// - public partial class XDataServiceConfiguration { + public partial class XDataServiceConfiguration + { /// - /// Provider Type ... + /// the base path for providing GraphQL ... /// /// - public XDbProviders Provider { get; set; } - + public string GraphQLBasePath { get; set; } = "/graphql"; + + /// + /// Data Bases Configuration ... + /// + /// + /// + public Dictionary Databases { get; set; } = new Dictionary(); + /// /// Enable Soft Delete Entities or Not ... /// /// public bool EnableSoftDelete { get; set; } - /// - /// Connection String which provide Requires Data to Connect to Db Provider ... - /// - /// - public string ConnectionString { get; set; } - /// /// Enable Tracking of Entities ... /// Only Used on EFCore ... @@ -48,19 +52,14 @@ namespace xDataService.Configuration { /// this is a way to provide Default Pagination Data on XQuery based requests ... /// /// - public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration (); - - /// - /// the base path for providing GraphQL ... - /// - /// - public string GraphQLBasePath { get; set; } = "/graphql"; + public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration(); } /// /// this is a way to provide Default Pagination Data on XQuery based requests ... /// - public partial class PagingConfiguration { + public partial class PagingConfiguration + { /// /// Default Page Size ... /// diff --git a/Configuration/XDbProviderConfigurations.cs b/Configuration/XDbProviderConfigurations.cs deleted file mode 100644 index f086a29..0000000 --- a/Configuration/XDbProviderConfigurations.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace xDataService.Configuration { - public partial class XDbProviderConfigurations { - /// - /// Default ConnectionString Name ... - /// - public const string DEFAULT_CONNECTION_NAME = "DataConnection"; - } -} \ No newline at end of file diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index b3ad6f3..a23b797 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -1,590 +1,278 @@ using System; -using System.Collections.Generic; using System.Linq; -using GraphQL.Server; -using GraphQL.Server.Ui.Playground; +using System.Reflection; using Microsoft.AspNetCore.Builder; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; -using MySql.EntityFrameworkCore.Extensions; using xCommons.Extensions; +using xCommons.Helpers; using xDataService.Configuration; using xDataService.Constants; using xDataService.Db; -using xDataService.Extensions; +using xDataService.Helpers; using xDataService.Interfaces; +using xDataService.Models; using xExceptions.Constants; -using xModels.Base; - -namespace xDataService.DI { - public static class XDIHelperExtension { - /// - /// Extract Connection String From IConfiguration - /// - /// - /// - /// - public static string GetXConnectionString ( - this IConfiguration config, - string connectionName = null - ) { - // - if (connectionName.IsNullOrEmpty ()) { - connectionName = XDbProviderConfigurations.DEFAULT_CONNECTION_NAME; - } - - // - return config.GetConnectionString (connectionName); - } - - /// - /// Retrieve Data Provider Type from Configurations - /// - /// - /// - public static XDbProviders GetXDbProviderType (this IConfiguration source) { - // - var provider = (source[$"{ConfigurationNodeNames.DB_PROVIDER_NODE}"]) - .ToNormalString (); - - // - return provider.ToDbProvider (); - } +namespace xDataService.DI +{ + public static partial class XDIHelperExtension + { /// /// Retrive XDataService Configurations /// /// /// /// - public static XDataServiceConfiguration GetXDataServiceConfiguration ( - this IConfiguration source, - string connectionName = null - ) { + public static XDataServiceConfiguration GetXDataServiceConfiguration( + this IConfiguration source + ) + { // var xDataServiceConfigSection = source - .GetSection (ConfigurationNodeNames.DATA_SERVICE_NODE); - var result = xDataServiceConfigSection.Get (); - - // - result.Provider = source.GetXDbProviderType (); - result.ConnectionString = source.GetXConnectionString (connectionName); + .GetSection(ConfigurationNodeNames.DATA_SERVICE_NODE); + var result = xDataServiceConfigSection.Get(); // return result; } /// - /// Register XDataService Configuration + /// Register XDataService Configuration ... /// - /// + /// /// - /// - public static void AddXDataServiceConfiguration ( - this IServiceCollection services, - IConfiguration configuration, - string connectionName = null - ) { + public static void AddXDataServiceConfiguration( + this IServiceCollection source, + IConfiguration configuration + ) + { // - var dataServiceConfiguration = configuration - .GetXDataServiceConfiguration (connectionName); - if (dataServiceConfiguration.IsNull ()) { - dataServiceConfiguration = new XDataServiceConfiguration (); + var config = configuration.GetXDataServiceConfiguration(); + if (config.IsNullOrDefault()) + { + // + Log("Configurations Not Founded ..."); + XException.NotFound.Throw(); } // - services.AddSingleton (dataServiceConfiguration); + source.AddSingleton(config); } /// - /// Register XDataService Configuration + /// Register XDataService Configuration ... /// - /// + /// /// - public static void AddXDataServiceConfiguration ( - this IServiceCollection services, + public static void AddXDataServiceConfiguration( + this IServiceCollection source, XDataServiceConfiguration configuration - ) { + ) + { // - if (configuration.IsNull ()) { - configuration = new XDataServiceConfiguration (); + if (configuration.IsNullOrDefault()) + { + // + Log("Configurations Not Founded ..."); + XException.NotFound.Throw(); } // - services.AddSingleton (configuration); + source.AddSingleton(configuration); } - /// - /// Register XDataService on DI - /// Only Used when EFCore Provider configured to use ... - /// - /// - /// - /// - /// - /// - public static void AddXDataService ( - this IServiceCollection services, - IConfiguration config, - ServiceLifetime lifetime, - string connectionName = null, - Action optionsBuilder = null + public static void AddXDatabase( + this IServiceCollection source, + IConfiguration configuration, + XDatabaseDescriptor descriptor, + ServiceLifetime lifetime = ServiceLifetime.Scoped ) - where TDbContext : XDbContext - where TDbSeeder : IXDbSeeder { + { // - // Register DataService Configuration ... - if (services.GetRegisteredService ().IsNull ()) { - Console.WriteLine ($"XDataService: there is no provided DataService Config, try to register default ..."); - services.AddXDataServiceConfiguration (config, connectionName); - } - - // - // prevent from going forward if there is no Provider configured ... - var providerType = config.GetXDbProviderType (); - Console.WriteLine ($"XDataService: registered db provider type is => {providerType} ..."); - if (providerType == XDbProviders.None) { + // Validate Database Descriptor ... + var isValid = + !descriptor.IsNullOrDefault() && + !descriptor.Name.IsNullOrEmpty(); + if (!isValid) + { + // + Log("Invalid Database Descriptor ..."); return; } // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (!dataServiceHelper.IsNull ()) { + // Check Service Collection Validation ... + isValid = + !source.IsNull() && + !configuration.IsNull(); + if (!isValid) + { // - // Use Db Context Helper ... - Console.WriteLine ($"XDataService: use provided IXDbContextHelper ..."); + Log("Invalid Service Provider or Configuration ..."); + return; + } + // + // Get Registere Data Service Configuration ... + var xDataServiceConfiguration = source + .GetRegisteredService(); + isValid = !xDataServiceConfiguration.IsNullOrDefault(); + if (!isValid) + { // - // Retrieve Connection String ... - var addContext = true; - var connectionString = config.GetXConnectionString (connectionName); - switch (providerType) { + // Extract Configuration from Configuration ... + xDataServiceConfiguration = configuration.GetXDataServiceConfiguration(); + isValid = !xDataServiceConfiguration.IsNullOrDefault(); + if (!isValid) + { // - case XDbProviders.MySQL: - addContext = true; - services.AddEntityFrameworkMySQL (); - break; - - // - case XDbProviders.SQLite: - addContext = true; - services.AddEntityFrameworkSqlite (); - break; - - // - case XDbProviders.SQLServer: - addContext = true; - services.AddEntityFrameworkSqlServer (); - break; - - // - case XDbProviders.MongoDB: - addContext = false; - break; + Log("DataService Configuration notProvided ..."); + return; } // - // Register DbContext in DI ... - if (addContext) { - dataServiceHelper.AddDbContext ( - services, - connectionString, - providerType, + // Register Configuration in DI ... + source.AddSingleton(xDataServiceConfiguration); + } + + // + // Check Data Service Configuration has Database ... + isValid = + !xDataServiceConfiguration.Databases.IsNullOrDefault() && + xDataServiceConfiguration.Databases.HasChild() && + xDataServiceConfiguration.Databases.Keys.Contains(descriptor.Name); + if (!isValid) + { + // + Log("Invalid Database Descriptor ..."); + return; + } + + // + // Configure Database Descriptor ... + descriptor.Configure(source); + + // + // Register Context ... + if (!descriptor.Context.IsNull() && + descriptor.Provider != XDbProviders.None && + !descriptor.ConnectionString.IsNullOrEmpty()) + { + // + typeof(XDataServiceHelper).InvokeGenericMethod( + methodName: "AddXDbContext", + runtimeType: descriptor.Context, + args: [ + source, + descriptor.Provider, + descriptor.ConnectionString, lifetime, - optionsBuilder - ); - - // - // Register Unit Of Works ... - services.Add (new ServiceDescriptor (typeof (IXUnitOfWorks), typeof (XUnitOfWorks), lifetime)); - } + descriptor.OptionsBuilder + ] + ); // - // Comment this in related to Task no. 27 ... - // Register IXSequentialGuid for handle XBaseGuidEntities ... - // services.AddSingleton (); - - // - // Register All Repository Patterns ... - AddRepositories (services, config, lifetime, providerType); - } else { - Console.WriteLine ($"XDataService: there is no provided IXDbContextHelper, data service registration failed ..."); + // source.AddXDbContext( + // lifetime: lifetime, + // provider: descriptor.Provider, + // optionsBuilder: descriptor.OptionsBuilder, + // connectionString: descriptor.ConnectionString + // ); } - } - - /// - /// Register XDataService on DI - /// Only Used when non EFCore Provider configured to use ... - /// - /// - /// - /// - /// - public static void AddXDataService ( - this IServiceCollection services, - IConfiguration config, - ServiceLifetime lifetime, - string connectionName = null - ) - where TDbSeeder : IXDbSeeder { + // - // Register DataService Configuration ... - if (services.GetRegisteredService ().IsNull ()) { - Console.WriteLine ($"XDataService: there is no provided DataService Config, try to register default ..."); - services.AddXDataServiceConfiguration (config, connectionName); - } + // Register Repositories ... + if (!descriptor.Repositories.IsNull() && + descriptor.Repositories.HasChild()) + { + // source.AddXDataRepositories( - // - // prevent from going forward if there is no Provider configured ... - var providerType = config.GetXDbProviderType (); - Console.WriteLine ($"XDataService: registered db provider type is => {providerType} ..."); - if (providerType == XDbProviders.None) { - return; - } - - // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (!dataServiceHelper.IsNull ()) { - // - // Use Db Context Helper ... - Console.WriteLine ($"XDataService: use provided IXDataServiceHelper ..."); - - // - // Retrieve Connection String ... - var connectionString = config.GetXConnectionString (connectionName); - switch (providerType) { - // - case XDbProviders.MySQL: - case XDbProviders.SQLite: - case XDbProviders.SQLServer: - Console.WriteLine ($"XDataService: for EF Provider Types use AddXDataService instead of AddXDataService ..."); - XException.InvalidConfiguration.Throw (); - break; - - // - 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); - }); - #endregion - - // - var conventionPacks = dataServiceHelper.MongoConventionPacks (); - if (!conventionPacks.IsNull ()) { - ConventionRegistry.Register ( - nameof ( - dataServiceHelper.MongoConventionPacks - ), - conventionPacks, - type => !type.FullName - .IsNullOrEmpty () - ); - } - - // - dataServiceHelper.RegisterMongoExtras (); - break; - } - - // - // Comment this in related to Task no. 27 ... - // Register IXSequentialGuid for handle XBaseGuidEntities ... - // services.AddSingleton (); - - // - // Register All Repository Patterns ... - AddRepositories (services, config, lifetime, providerType); - } else { - Console.WriteLine ($"XDataService: there is no provided IXDbContextHelper, data service registration failed ..."); - } - } - - /// - /// Register XGraphQL service ... - /// - /// - /// - public static void AddXGraphQL ( - this IServiceCollection services, - Action options = null - ) { - // - var xGraphQLHelper = services.GetRegisteredService (); - if (!xGraphQLHelper.IsNull ()) { - // - xGraphQLHelper.AddXGraphEnumTypes (services); - xGraphQLHelper.AddXGraphObjectTypes (services); - xGraphQLHelper.AddXGraphInputTypes (services); - xGraphQLHelper.AddXGraphQueries (services); - xGraphQLHelper.AddXGraphMutations (services); - xGraphQLHelper.AddXGraphSubscriptions (services); - xGraphQLHelper.AddXGraphSchemas (services); - - // - // Add GraphQL Server ... - if (options.IsNull ()) { - // - options = x => { }; - Console.WriteLine ($"XDataService: there is no provided GraphQLOption, use default ..."); - } - - // - var xGraphQlBuilder = services.AddGraphQL (options) - .AddNewtonsoftJson (deserializerSettings => { }, serializerSettings => { }) - .AddWebSockets () - .AddDataLoader () - .AddGraphTypes (); - - // - xGraphQLHelper.AddXGraphTypes (xGraphQlBuilder); - } else { - Console.WriteLine ($"XDataService: there is no provided IXGraphQLHelper, data service registration failed ..."); - } - } - - /// - /// Use XDataService MiddleWare - /// - /// - public static void UseXDataService ( - this IApplicationBuilder app - ) { - app.SeedData (); - } - - /// - /// Use XGraphQL Middleware ... - /// - /// - /// - /// - public static void UseXGraphQL ( - this IApplicationBuilder app, - GraphQLPlaygroundOptions options = null, - bool withPlayground = true - ) { - // - // Use GraphQl WebSockets ... - app.UseWebSockets (); - - // - // Registered Graph Types ... - using (var scope = app.ApplicationServices.CreateScope ()) { - // - var xGraphQLHelper = scope.ServiceProvider.GetService (); - if (!xGraphQLHelper.IsNull ()) { - xGraphQLHelper.UseXGraph (app); - } else { - Console.WriteLine ($"XDataService: there is no provided IXGraphQLHelper, data service GraphQL not using ..."); - } - } - - // - // Use GraphQL Playground UI ... - if (withPlayground) { - app.UseGraphQLPlayground (options); + // ); } } // #region Private ... /// - /// Register Repositories on DI as Services + /// a LogTag for xDataService ... /// - /// - /// - /// - /// - private static void AddRepositories ( - IServiceCollection services, - IConfiguration config, - ServiceLifetime lifetime, - XDbProviders provider - ) - where TDbContext : XDbContext - where TDbSeeder : IXDbSeeder { - // - // Add Repositories Based On Provider Here ... - switch (provider) { - case XDbProviders.MySQL: - case XDbProviders.SQLite: - case XDbProviders.SQLServer: - AddEFRepositories (services, lifetime); - break; - case XDbProviders.MongoDB: - Console.WriteLine ($"XDataService: for Mongo Provider Types use AddXDataService instead of AddXDataService ..."); - XException.InvalidConfiguration.Throw (); - break; - } + private static string XLogTag = "xDataService"; - // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (dataServiceHelper.IsNull ()) { - // - Console.WriteLine ($"XDataService: there is no provided IXDataServiceHelper, db seeder registration failed ..."); - return; - } - - // - // Add DbSeeder Configuration ... - dataServiceHelper.AddDbSeederConfiguration (services, config); - - // - // Add Db Seeder ... - dataServiceHelper.AddDbSeeder (services, config, lifetime); + /// + /// print a log in Console ... + /// + /// + private static void Log(string message) + { + Console.WriteLine($"{XLogTag} => {message}"); } /// - /// Register Repositories on DI as Services + /// Register DbContext ... /// - /// - /// - /// + /// /// - private static void AddRepositories ( - IServiceCollection services, - IConfiguration config, - ServiceLifetime lifetime, - XDbProviders provider + /// + /// + /// + /// + private static void AddXDbContext( + this IServiceCollection source, + XDbProviders provider, + string connectionString, + ServiceLifetime lifetime = ServiceLifetime.Scoped, + Action optionsBuilder = null ) - where TDbSeeder : IXDbSeeder { + where TContext : XDbContext + { // - // Add Repositories Based On Provider Here ... - switch (provider) { + if (provider == XDbProviders.None) + { // - case XDbProviders.MySQL: - case XDbProviders.SQLite: - case XDbProviders.SQLServer: - Console.WriteLine ($"XDataService: for EF Provider Types use AddXDataService instead of AddXDataService ..."); - XException.InvalidConfiguration.Throw (); - break; + Log("Invalid Db Provider ..."); + XException.InvalidArgs.Throw(); + } + // + switch (provider) + { + // + // MySQL ... + case XDbProviders.MySQL: // - case XDbProviders.MongoDB: - AddMongoRepositories (services, lifetime); + source.AddDbContext(cfg => + { + cfg.UseMySQL(connectionString, optionsBuilder); + }, lifetime); break; - } - - // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (dataServiceHelper.IsNull ()) { - // - Console.WriteLine ($"XDataService: there is no provided IXDataServiceHelper, db seeder registration failed ..."); - return; - } - - // - // Add DbSeeder Configuration ... - dataServiceHelper.AddDbSeederConfiguration (services, config); - - // - // Add Db Seeder ... - dataServiceHelper.AddDbSeeder (services, config, lifetime); - } - - /// - /// Add Entity Framework Repositories - /// - /// - /// - private static void AddEFRepositories ( - this IServiceCollection services, - ServiceLifetime lifetime - ) - where TDbContext : XDbContext { - // - var repoServices = new List (); - - // - var dataServiceConfig = services.GetRegisteredService (); - if (!dataServiceConfig.IsNull ()) { - // - // Register Base Repositories if Required ... - } - - // - // Adding Services to DI ... - if (repoServices.Count > 0) { - repoServices - .ToList () - .ForEach (s => services.Add (s)); - } - - // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (!dataServiceHelper.IsNull ()) { - // - // Register Repositories ... - dataServiceHelper.AddRepositories (services, lifetime); // - // Register KeyGenerators ... - dataServiceHelper.AddKeyGenerators (services); - } - } - - /// - /// Add MongoDb Repositories - /// - /// - /// - private static void AddMongoRepositories ( - this IServiceCollection services, - ServiceLifetime lifetime - ) { - // - var repoServices = new List (); - - // - var dataServiceConfig = services.GetRegisteredService (); - if (!dataServiceConfig.IsNull ()) { - // - // Register Base Repositories if Required ... - } - - // - // Adding Services to DI ... - if (repoServices.Count > 0) { - repoServices - .ToList () - .ForEach (s => services.Add (s)); - } - - // - // Retrieve IXDataServiceHelper ... - var dataServiceHelper = services.GetRegisteredService (); - if (!dataServiceHelper.IsNull ()) { - // - // Register Repositories ... - dataServiceHelper.AddRepositories (services, lifetime); + // SQLite ... + case XDbProviders.SQLite: + // + source.AddDbContext(cfg => + { + cfg.UseSqlite(connectionString, optionsBuilder); + }, lifetime); + break; // - // Register KeyGenerators ... - dataServiceHelper.AddKeyGenerators (services); + // SQLServer ... + case XDbProviders.SQLServer: + // + source.AddDbContext(cfg => + { + cfg.UseSqlServer(connectionString, optionsBuilder); + }, lifetime); + break; + + // + case XDbProviders.MongoDB: + // There is notRequired to Register DBConext forMongo DB ... + break; } } @@ -592,27 +280,33 @@ namespace xDataService.DI { /// Do Seeding Initialization Data on DbContext /// /// - private static void SeedData ( + private static void SeedData( this IApplicationBuilder app - ) { + ) + { // - using (var scope = app.ApplicationServices.CreateScope ()) { + using (var scope = app.ApplicationServices.CreateScope()) + { // - var dbSeeder = scope.ServiceProvider.GetService (); - Console.WriteLine ($"XDataService: dbSeeder retrieved from DI is => {!dbSeeder.IsNull()}"); + var dbSeeder = scope.ServiceProvider.GetService(); + Console.WriteLine($"XDataService: dbSeeder retrieved from DI is => {!dbSeeder.IsNull()}"); // - if (!dbSeeder.IsNull ()) { - try { + if (!dbSeeder.IsNull()) + { + try + { // - dbSeeder.Seed () - .GetAwaiter () - .GetResult (); - } catch (Exception ex) { + dbSeeder.Seed() + .GetAwaiter() + .GetResult(); + } + catch (Exception ex) + { // - Console.WriteLine (" "); - Console.WriteLine ($"XDataService: Seeding Error: {ex.Message}"); - XException.InvalidConfiguration.Throw (); + Console.WriteLine(" "); + Console.WriteLine($"XDataService: Seeding Error: {ex.Message}"); + XException.InvalidConfiguration.Throw(); } } } diff --git a/Extensions/XDataServiceConfigurationExtensions.cs b/Extensions/XDataServiceConfigurationExtensions.cs index 0371c6c..ee84c13 100644 --- a/Extensions/XDataServiceConfigurationExtensions.cs +++ b/Extensions/XDataServiceConfigurationExtensions.cs @@ -39,7 +39,7 @@ namespace xDataService.Extensions { /// /// /// - public static string GetMongoDbURI (this XDataServiceConfiguration source) { + public static string GetMongoDbURI (this XDataBaseConfiguration source) { // var parts = source.GetConnectionParts (); var result = parts @@ -56,7 +56,7 @@ namespace xDataService.Extensions { /// /// /// - public static string GetMongoDbDatabase (this XDataServiceConfiguration source) { + public static string GetMongoDbDatabase (this XDataBaseConfiguration source) { // var parts = source.GetConnectionParts (); var result = parts @@ -70,7 +70,7 @@ namespace xDataService.Extensions { // #region Private ... - private static string[] GetConnectionParts (this XDataServiceConfiguration source) { + private static string[] GetConnectionParts (this XDataBaseConfiguration source) { // var result = source.ConnectionString.Split (';'); diff --git a/GraphQL/XBaseGraphQLQuery.cs b/GraphQL/XBaseGraphQLQuery.cs index 06783f6..fec6d58 100644 --- a/GraphQL/XBaseGraphQLQuery.cs +++ b/GraphQL/XBaseGraphQLQuery.cs @@ -9,164 +9,186 @@ using xDataService.Interfaces; using xDataService.Models; using xModels.Base; -namespace xDataService.GraphQL { - public abstract class XBaseGraphQLQuery : ObjectGraphType, IXBaseGraphQLQuery - where TEntity : XBaseEntity - where TGraph : IGraphType - where TGraphKey : IGraphType { - // - private readonly XDataServiceConfiguration configuration; - private readonly IXBaseRepository repository; - private readonly IXBaseGraphQLTypeHelper helper; +namespace xDataService.GraphQL +{ + public abstract class XBaseGraphQLQuery : ObjectGraphType, IXBaseGraphQLQuery { } + public abstract class XBaseGraphQLQuery : XBaseGraphQLQuery, IXBaseGraphQLQuery + where TEntity : XBaseEntity + { // - public XBaseGraphQLQuery ( + protected readonly XDataServiceConfiguration configuration; + protected readonly IXBaseRepository repository; + protected readonly IXBaseGraphQLTypeHelper helper; + + public XBaseGraphQLQuery( XDataServiceConfiguration configuration, IXBaseRepository repository, IXBaseGraphQLTypeHelper helper - ) { + ) + { // this.helper = helper; this.repository = repository; this.configuration = configuration; // - Name = GetType ().Name; + Name = GetType().Name; + } + } + public abstract class XBaseGraphQLQuery : XBaseGraphQLQuery, IXBaseGraphQLQuery + where TEntity : XBaseEntity + where TGraph : IGraphType + where TGraphKey : IGraphType + { + // + public XBaseGraphQLQuery( + XDataServiceConfiguration configuration, + IXBaseRepository repository, + IXBaseGraphQLTypeHelper helper + ) : base( + helper: helper, + repository: repository, + configuration: configuration + ) + { // #region Retrieve ... // // Get ... - FieldAsync ( - name: helper.GetInQuerySingleName (), - arguments: new QueryArguments ( - XGraphQLHelper.GetIdArgument (), + FieldAsync( + name: helper.GetInQuerySingleName(), + arguments: new QueryArguments( + XGraphQLHelper.GetIdArgument(), XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async context => + resolve: async context => await repository - .GetAsync ( + .GetAsync( includeBuilder: null, - id: context.GetIdArgument (), - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + id: context.GetIdArgument(), + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) - .ToDynamicObject () + .ToDynamicObject() ); // // GetAll ... - FieldAsync> ( - name: helper.GetInQueryCollectionName (), - arguments: new QueryArguments ( + FieldAsync>( + name: helper.GetInQueryCollectionName(), + arguments: new QueryArguments( XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async context => + resolve: async context => await repository - .GetAllAsync ( + .GetAllAsync( orderBuilder: null, includeBuilder: null, - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) - .ToDynamicObject () + .ToDynamicObject() ); // // FindOne ... - FieldAsync ( - name: helper.GetFindOneName (), - arguments: new QueryArguments ( + FieldAsync( + name: helper.GetFindOneName(), + arguments: new QueryArguments( XGraphQLHelper.SearchQueryArgument, XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async (context) => { + resolve: async (context) => + { // - var searchQuery = context.GetSearchQueryArgument (); + var searchQuery = context.GetSearchQueryArgument(); Expression> whereClase = pe => pe - .PropValuesContains (searchQuery); + .PropValuesContains(searchQuery); // return await repository - .FindOneAsync ( + .FindOneAsync( includeBuilder: null, predicate: whereClase, - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) - .ToDynamicObject (); + .ToDynamicObject(); } ); // // FindMany ... - FieldAsync> ( - name: helper.GetFindManyName (), - arguments: new QueryArguments ( + FieldAsync>( + name: helper.GetFindManyName(), + arguments: new QueryArguments( XGraphQLHelper.SearchQueryArgument, XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async (context) => { + resolve: async (context) => + { // - var searchQuery = context.GetSearchQueryArgument (); + var searchQuery = context.GetSearchQueryArgument(); Expression> whereClase = pe => pe - .PropValuesContains (searchQuery); + .PropValuesContains(searchQuery); // return await repository - .FindManyAsync ( + .FindManyAsync( orderBuilder: null, includeBuilder: null, predicate: whereClase, - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) - .ToDynamicObject (); + .ToDynamicObject(); } ); // // Query ... - FieldAsync> ( - name: helper.GetQueryName (), - arguments: new QueryArguments ( + FieldAsync>( + name: helper.GetQueryName(), + arguments: new QueryArguments( XGraphQLHelper.QueryArgument, XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async context => - await repository - .QueryAsync ( - predicate: null, - orderBuilder: null, - includeBuilder: null, - query: context.GetQueryArgument (), - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () - ) - .ToDynamicObject () - ); - - // - // Count ... - FieldAsync ( - name: helper.GetCountName (), - arguments: new QueryArguments ( - XGraphQLHelper.IgnoreSoftDeletedArgument - ), resolve: async context => await repository - .CountAsync ( - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + .QueryAsync( + predicate: null, + orderBuilder: null, + includeBuilder: null, + query: context.GetQueryArgument(), + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() + ) + .ToDynamicObject() + ); + + // + // Count ... + FieldAsync( + name: helper.GetCountName(), + arguments: new QueryArguments( + XGraphQLHelper.IgnoreSoftDeletedArgument + ), + resolve: async context => + await repository + .CountAsync( + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) ); // // Exists ... - FieldAsync ( - name: helper.GetExistsName (), - arguments: new QueryArguments ( - XGraphQLHelper.GetIdArgument (), + FieldAsync( + name: helper.GetExistsName(), + arguments: new QueryArguments( + XGraphQLHelper.GetIdArgument(), XGraphQLHelper.IgnoreSoftDeletedArgument ), - resolve : async context => - await repository.IsExistsAsync ( - id: context.GetIdArgument (), - ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () + resolve: async context => + await repository.IsExistsAsync( + id: context.GetIdArgument(), + ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument() ) ); #endregion diff --git a/GraphQL/XBaseGraphQLTypeHelper.cs b/GraphQL/XBaseGraphQLTypeHelper.cs index 3d7986c..1873451 100644 --- a/GraphQL/XBaseGraphQLTypeHelper.cs +++ b/GraphQL/XBaseGraphQLTypeHelper.cs @@ -3,62 +3,114 @@ using xDataService.Configuration; using xDataService.Interfaces; using xModels.Base; -namespace xDataService.GraphQL { - public abstract class XBaseGraphQLTypeHelper : IXBaseGraphQLTypeHelper - where TEntity : XBaseEntity { - // - private readonly XDataServiceConfiguration configuration; +namespace xDataService.GraphQL +{ + public abstract class XBaseGraphQLTypeHelper : IXBaseGraphQLTypeHelper + { + // + protected readonly XDataServiceConfiguration configuration; - // - public XBaseGraphQLTypeHelper ( - XDataServiceConfiguration configuration = null - ) { - this.configuration = configuration; - } - - // - public abstract string GetInQueryCollectionName (); - - public abstract string GetInQuerySingleName (); - - // - public string GetFindOneName () { - return $"find{GetInQuerySingleName ().ToNormalString().Capitalize()}"; - } - - public string GetFindManyName () { - return $"find{GetInQueryCollectionName ().ToNormalString().Capitalize()}"; - } - - public string GetQueryName () { - return $"query{GetInQueryCollectionName().ToNormalString().Capitalize()}"; - } - - public string GetCountName () { - return $"count{GetInQueryCollectionName().ToNormalString().Capitalize()}"; - } - - public string GetExistsName () { - return $"exists{GetInQuerySingleName().ToNormalString().Capitalize()}"; - } - - public string GetGraphQLPath (string baseGraphPath = null) { - // - baseGraphPath = baseGraphPath.IsNullOrEmpty () ? - configuration.IsNull () || configuration.GraphQLBasePath.IsNullOrEmpty () ? - "" : - configuration.GraphQLBasePath : - baseGraphPath; - - // - var basePath = baseGraphPath - .EndsWith ("/") ? - baseGraphPath - .Substring (0, baseGraphPath.Length - 1) : - baseGraphPath; - - // - return $"{basePath}/{GetInQueryCollectionName().ToNormalString()}"; - } + // + public XBaseGraphQLTypeHelper( + XDataServiceConfiguration configuration + ) + { + this.configuration = configuration; } + + public abstract string GetInQuerySingleName(); + + public abstract string GetInQueryCollectionName(); + + // + #region Actions ... + public virtual string GetCountName() + { + return string.Empty; + } + + public virtual string GetExistsName() + { + return string.Empty; + } + + public virtual string GetFindManyName() + { + return string.Empty; + } + + public virtual string GetFindOneName() + { + return string.Empty; + } + + public virtual string GetGraphQLPath(string baseGraphPath = null) + { + return string.Empty; + } + + public virtual string GetQueryName() + { + return string.Empty; + } + #endregion + } + + public abstract class XBaseGraphQLTypeHelper : XBaseGraphQLTypeHelper, IXBaseGraphQLTypeHelper + where TEntity : XBaseEntity + { + // + public XBaseGraphQLTypeHelper( + XDataServiceConfiguration configuration = null + ) : base(configuration) + { } + + // + #region Actions ... + public override string GetFindOneName() + { + return $"find{GetInQuerySingleName().ToNormalString().Capitalize()}"; + } + + public override string GetFindManyName() + { + return $"find{GetInQueryCollectionName().ToNormalString().Capitalize()}"; + } + + public override string GetQueryName() + { + return $"query{GetInQueryCollectionName().ToNormalString().Capitalize()}"; + } + + public override string GetCountName() + { + return $"count{GetInQueryCollectionName().ToNormalString().Capitalize()}"; + } + + public override string GetExistsName() + { + return $"exists{GetInQuerySingleName().ToNormalString().Capitalize()}"; + } + + public override string GetGraphQLPath(string baseGraphPath = null) + { + // + baseGraphPath = baseGraphPath.IsNullOrEmpty() ? + configuration.IsNull() || configuration.GraphQLBasePath.IsNullOrEmpty() ? + "" : + configuration.GraphQLBasePath : + baseGraphPath; + + // + var basePath = baseGraphPath + .EndsWith("/") ? + baseGraphPath + .Substring(0, baseGraphPath.Length - 1) : + baseGraphPath; + + // + return $"{basePath}/{GetInQueryCollectionName().ToNormalString()}"; + } + #endregion + } } \ No newline at end of file diff --git a/Helpers/XDataServiceHelper.cs b/Helpers/XDataServiceHelper.cs new file mode 100644 index 0000000..8452268 --- /dev/null +++ b/Helpers/XDataServiceHelper.cs @@ -0,0 +1,79 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using xCommons.Extensions; +using xDataService.Constants; +using xDataService.Db; +using xExceptions.Constants; + +namespace xDataService.Helpers +{ + public static class XDataServiceHelper + { + /// + /// Register DbContext ... + /// + /// + /// + /// + /// + /// + /// + public static void AddXDbContext( + IServiceCollection source, + XDbProviders provider, + string connectionString, + ServiceLifetime lifetime = ServiceLifetime.Scoped, + Action optionsBuilder = null + ) + where TContext : XDbContext + { + // + if (provider == XDbProviders.None) + { + // + // Log("Invalid Db Provider ..."); + XException.InvalidArgs.Throw(); + } + + // + switch (provider) + { + // + // MySQL ... + case XDbProviders.MySQL: + // + source.AddDbContext(cfg => + { + cfg.UseMySQL(connectionString, optionsBuilder); + }, lifetime); + break; + + // + // SQLite ... + case XDbProviders.SQLite: + // + source.AddDbContext(cfg => + { + cfg.UseSqlite(connectionString, optionsBuilder); + }, lifetime); + break; + + // + // SQLServer ... + case XDbProviders.SQLServer: + // + source.AddDbContext(cfg => + { + cfg.UseSqlServer(connectionString, optionsBuilder); + }, lifetime); + break; + + // + case XDbProviders.MongoDB: + // There is notRequired to Register DBConext forMongo DB ... + break; + } + } + } +} \ No newline at end of file diff --git a/Interfaces/IXBaseGraphQLQuery.cs b/Interfaces/IXBaseGraphQLQuery.cs index 8c84cef..9426ab2 100644 --- a/Interfaces/IXBaseGraphQLQuery.cs +++ b/Interfaces/IXBaseGraphQLQuery.cs @@ -1,9 +1,17 @@ using GraphQL.Types; using xModels.Base; -namespace xDataService.Interfaces { - public interface IXBaseGraphQLQuery - where TEntity : XBaseEntity - where TGraph : IGraphType - where TGraphKey : IGraphType { } +namespace xDataService.Interfaces +{ + public interface IXBaseGraphQLQuery { } + + public interface IXBaseGraphQLQuery : IXBaseGraphQLQuery + where TEntity : XBaseEntity + { } + + public interface IXBaseGraphQLQuery : IXBaseGraphQLQuery + where TEntity : XBaseEntity + where TGraph : IGraphType + where TGraphKey : IGraphType + { } } \ No newline at end of file diff --git a/Interfaces/IXBaseGraphQLTypeHelper.cs b/Interfaces/IXBaseGraphQLTypeHelper.cs index de2548e..940570b 100644 --- a/Interfaces/IXBaseGraphQLTypeHelper.cs +++ b/Interfaces/IXBaseGraphQLTypeHelper.cs @@ -1,21 +1,27 @@ using xModels.Base; -namespace xDataService.Interfaces { - public interface IXBaseGraphQLTypeHelper - where TEntity : XBaseEntity { - string GetInQuerySingleName (); - string GetInQueryCollectionName (); +namespace xDataService.Interfaces +{ + public interface IXBaseGraphQLTypeHelper + { + string GetInQuerySingleName(); - string GetFindOneName (); + string GetInQueryCollectionName(); - string GetFindManyName (); + string GetFindOneName(); - string GetQueryName (); + string GetFindManyName(); - string GetCountName (); + string GetQueryName(); - string GetExistsName (); + string GetCountName(); - string GetGraphQLPath (string baseGraphPath = null); - } + string GetExistsName(); + + string GetGraphQLPath(string baseGraphPath = null); + } + + public interface IXBaseGraphQLTypeHelper : IXBaseGraphQLTypeHelper + where TEntity : XBaseEntity + { } } \ No newline at end of file diff --git a/Interfaces/IXBaseRepository.cs b/Interfaces/IXBaseRepository.cs index 9a829ec..28befdd 100644 --- a/Interfaces/IXBaseRepository.cs +++ b/Interfaces/IXBaseRepository.cs @@ -10,13 +10,15 @@ using xModels.Dtos; namespace xDataService.Interfaces { + public interface IXBaseRepository : IDisposable { } + /// /// Base Repository Pattern Contracts in XDashboard's Data Service ... /// use for Data Manipulation ... /// /// /// - public interface IXBaseRepository : IDisposable + public interface IXBaseRepository : IXBaseRepository where T : XBaseEntity { // diff --git a/Interfaces/IXDatabaseDescriptor.cs b/Interfaces/IXDatabaseDescriptor.cs new file mode 100644 index 0000000..7a88253 --- /dev/null +++ b/Interfaces/IXDatabaseDescriptor.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using MongoDB.Bson.Serialization.Conventions; +using xDataService.Configuration; +using xDataService.Constants; +using xDataService.Db; +using xDataService.Models; + +namespace xDataService.Interfaces +{ + /// + /// Data Base Descriptor ... + /// + public interface IXDatabaseDescriptor + { + // + #region Props ... + /// + /// Database Name ... + /// + /// + string Name { get; set; } + + /// + /// Database Provider ... + /// + /// + XDbProviders Provider { get; set; } + + /// + /// Db Context Type ... + /// + /// + Type Context { get; set; } + + /// + /// Database Connecion String ... + /// + /// + string ConnectionString { get; set; } + + /// + /// Data Service Configuration ... + /// + /// + XDataBaseConfiguration Configuration { get; set; } + + /// + /// Repositories Descriptions ... + /// + /// + IList Repositories { get; set; } + + /// + /// Mongo Convention Packs ... + /// + ConventionPack ConventionPacks { get; set; } + + /// + /// DbContext Options Builder ... + /// + /// + Action OptionsBuilder { get; set; } + #endregion + + // + #region Configure ... + /// + /// Configure Database Descriptor using Registered Services ... + /// + /// + void Configure( + IServiceCollection services + ); + + /// + /// Configure Database Descriptor using IConfiguration ... + /// + /// + void Configure( + IConfiguration configuration + ); + + /// + /// Configure Database Descriptor using Database Configuration ... + /// + /// + void Configure( + XDataBaseConfiguration configuration + ); + + /// + /// Configure Database Descriptor using Provider and Connection String ... + /// + /// + /// + void Configure( + XDbProviders provider, + string connectionString + ); + #endregion + } + + /// + /// Data Base Descriptor ... + /// + /// + public interface IXDatabaseDescriptor : IXDatabaseDescriptor + where TContext : XDbContext + { } +} \ No newline at end of file diff --git a/Interfaces/IXKeyGenerator.cs b/Interfaces/IXKeyGenerator.cs index caba890..58c77b2 100644 --- a/Interfaces/IXKeyGenerator.cs +++ b/Interfaces/IXKeyGenerator.cs @@ -2,13 +2,25 @@ using System.Threading; using System.Threading.Tasks; using xModels.Base; -namespace xDataService.Interfaces { - public interface IXKeyGenerator - where TEntity : XBaseEntity { - bool IsEmpty (TKey id); - Task GenerateKey ( - IXBaseRepository repository, - CancellationToken cancellationToken = default - ); - } +namespace xDataService.Interfaces +{ + /// + /// Non Generic Key Generator Interface ... + /// + public interface IXKeyGenerator { } + + /// + /// Typed Base Key Generator ... + /// + /// + /// + public interface IXKeyGenerator : IXKeyGenerator + where TEntity : XBaseEntity + { + bool IsEmpty(TKey id); + Task GenerateKey( + IXBaseRepository repository, + CancellationToken cancellationToken = default + ); + } } \ No newline at end of file diff --git a/Models/XDatabaseDescriptor.cs b/Models/XDatabaseDescriptor.cs new file mode 100644 index 0000000..947bb97 --- /dev/null +++ b/Models/XDatabaseDescriptor.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using MongoDB.Bson.Serialization.Conventions; +using xCommons.Extensions; +using xDataService.Configuration; +using xDataService.Constants; +using xDataService.Db; +using xDataService.DI; +using xDataService.Interfaces; + +namespace xDataService.Models +{ + /// + /// Data Base Descriptor ... + /// + public abstract class XDatabaseDescriptor : IXDatabaseDescriptor + { + // + #region Props ... + /// + /// Database Name ... + /// + /// + public virtual string Name { get; set; } + + /// + /// Database Provider ... + /// + /// + public virtual XDbProviders Provider { get; set; } + + /// + /// Db Context... + /// + /// + public virtual Type Context { get; set; } = null; + + /// + /// Database Connecion String ... + /// + /// + public virtual string ConnectionString { get; set; } + + /// + /// Data Service Configuration ... + /// + /// + public virtual XDataBaseConfiguration Configuration { get; set; } + + /// + /// Repositories Descriptions ... + /// + /// + public virtual IList Repositories { get; set; } = null; + + /// + /// Mongo Convention Packs ... + /// + public ConventionPack ConventionPacks { get; set; } = null; + + /// + /// DbContext Options Builder ... + /// + /// + public Action OptionsBuilder { get; set; } = null; + #endregion + + // + #region Constructor ... + /// + /// Constructor of Descriptor ... + /// + /// + /// + /// + public XDatabaseDescriptor( + string name, + IList repositories = null + ) + { + // + Name = name; + Repositories = repositories; + } + #endregion + + // + #region Configure ... + /// + /// Configure Database Descriptor using Registered Services ... + /// + /// + public void Configure( + IServiceCollection services + ) + { + // + bool isValid = !Name.IsNullOrEmpty(); + if (!isValid) + { + return; + } + + // + var xDataServiceConfiguration = services.GetRegisteredService(); + isValid = + !xDataServiceConfiguration.IsNullOrDefault() && + xDataServiceConfiguration.Databases.HasChild() && + xDataServiceConfiguration.Databases.Keys.Any(k => k == Name); + if (!isValid) + { + return; + } + + // + var database = xDataServiceConfiguration.Databases[Name]; + isValid = !database.IsNullOrDefault(); + if (!isValid) + { + return; + } + + // + Configure(database); + } + + /// + /// Configure Database Descriptor using IConfiguration ... + /// + /// + public void Configure( + IConfiguration configuration + ) + { + // + bool isValid = !Name.IsNullOrEmpty(); + if (!isValid) + { + return; + } + + // + var xDataServiceConfiguration = configuration.GetXDataServiceConfiguration(); + isValid = + !xDataServiceConfiguration.IsNullOrDefault() && + xDataServiceConfiguration.Databases.HasChild() && + xDataServiceConfiguration.Databases.Keys.Any(k => k == Name); + if (!isValid) + { + return; + } + + // + var database = xDataServiceConfiguration.Databases[Name]; + isValid = !database.IsNullOrDefault(); + if (!isValid) + { + return; + } + + // + Configure(database); + } + + /// + /// Configure Database Descriptor using Database Configuration ... + /// + /// + public void Configure( + XDataBaseConfiguration configuration + ) + { + // + Configuration = configuration; + Provider = configuration.Provider; + ConnectionString = configuration.ConnectionString; + } + + /// + /// Configure Database Descriptor using Provider and Connection String ... + /// + /// + /// + public void Configure( + XDbProviders provider, + string connectionString + ) + { + // + Provider = provider; + ConnectionString = connectionString; + Configuration = new XDataBaseConfiguration + { + Provider = provider, + ConnectionString = connectionString + }; + } + #endregion + } + + /// + /// Data Base Descriptor ... + /// + /// + public abstract class XDatabaseDescriptor : XDatabaseDescriptor, IXDatabaseDescriptor + where TContext : XDbContext + { + /// + /// Constructor of Descriptor ... + /// + /// + /// + /// + /// + public XDatabaseDescriptor( + string name, + IList repositories = null + ) : base( + name: name, + repositories: repositories + ) + { + Context = typeof(TContext); + } + } +} \ No newline at end of file diff --git a/Models/XRepositoryDescriptor.cs b/Models/XRepositoryDescriptor.cs new file mode 100644 index 0000000..7aba507 --- /dev/null +++ b/Models/XRepositoryDescriptor.cs @@ -0,0 +1,63 @@ +using GraphQL.Types; +using xDataService.GraphQL; +using xDataService.Interfaces; +using xModels.Base; + +namespace xDataService.Models +{ + /// + /// a Global non Generic Repository Descriptor ... + /// + public class XRepositoryDescriptor { } + + /// + /// a Repository Descriptor ... + /// + /// + /// + public class XRepositoryDescriptor : XRepositoryDescriptor + where TEntity : XBaseEntity + { + /// + /// Entity Type GraphQL Schema ... + /// + /// + public Schema GraphSchema { get; set; } = null; + + /// + /// Entity GraphQL Type Helper ... + /// + /// + public IXBaseGraphQLTypeHelper GraphTypeHelper { get; set; } = null; + + /// + /// Entity GrapQL Query ... + /// + /// + public IXBaseGraphQLQuery GraphQuery { get; set; } = null; + + /// + /// Entity GraphQL Type ... + /// + /// + public XBaseGraphObjectType GraphType { get; set; } = null; + + /// + /// Repository Event Provider ... + /// + /// + public IXBaseRepositoryEvents Events { get; set; } = null; + + /// + /// Repository Key Generator for Entity ... + /// + /// + public IXKeyGenerator KeyGenerator { get; set; } = null; + + /// + /// Repository Data Access Design Pattern ... + /// + /// + public IXBaseRepository Repository { get; set; } + } +} \ No newline at end of file diff --git a/MongoRepositories/XBaseMongoRepository.cs b/MongoRepositories/XBaseMongoRepository.cs index 83321f1..b6ae8be 100644 --- a/MongoRepositories/XBaseMongoRepository.cs +++ b/MongoRepositories/XBaseMongoRepository.cs @@ -8,7 +8,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using MongoDB.Driver; using MongoDB.Driver.Linq; -using Org.BouncyCastle.Asn1.Ocsp; using xCommons.Extensions; using xDataService.Configuration; using xDataService.Extensions; @@ -34,6 +33,7 @@ namespace xDataService.MongoRepositories public List> bulkCollection; public readonly IMongoCollection collection; private readonly IXKeyGenerator keyGenerator; + public readonly XDataBaseConfiguration dbConfiguration; public readonly XDataServiceConfiguration configuration; private readonly IXBaseRepositoryEvents baseRepositoryEvents; #endregion @@ -41,6 +41,7 @@ namespace xDataService.MongoRepositories // #region Constructor ... protected XBaseMongoRepository( + XDataBaseConfiguration dbConfiguration, XDataServiceConfiguration configuration, string collectionName = null, IXKeyGenerator keyGenerator = null, @@ -54,11 +55,12 @@ namespace xDataService.MongoRepositories .IsNullOrEmpty() ? typeof(T).Name : collectionName; + this.dbConfiguration = dbConfiguration; this.baseRepositoryEvents = baseRepositoryEvents; // - var client = new MongoClient(configuration.GetMongoDbURI()); - var database = client.GetDatabase(configuration.GetMongoDbDatabase()); + var client = new MongoClient(dbConfiguration.GetMongoDbURI()); + var database = client.GetDatabase(dbConfiguration.GetMongoDbDatabase()); // bulkCollection = new List>(); diff --git a/Providers/XGuidKeyGenerator.cs b/Providers/XGuidKeyGenerator.cs index 4df0ea2..16efd17 100644 --- a/Providers/XGuidKeyGenerator.cs +++ b/Providers/XGuidKeyGenerator.cs @@ -7,8 +7,12 @@ using xModels.Base; namespace xDataService.Providers { + /// + /// Default Guid Key Generator ... + /// + /// public class XGuidKeyGenerator : IXKeyGenerator - where TEntity : XBaseEntity + where TEntity : XBaseEntity { private readonly IXSequentialGuid sequentialGuid; diff --git a/Providers/XIntKeyGenerator.cs b/Providers/XIntKeyGenerator.cs index e73aa93..a80e7f6 100644 --- a/Providers/XIntKeyGenerator.cs +++ b/Providers/XIntKeyGenerator.cs @@ -8,8 +8,12 @@ using xModels.Base; namespace xDataService.Providers { + /// + /// Default Int Key Generator ... + /// + /// public class XIntKeyGenerator : IXKeyGenerator - where TEntity : XBaseEntity + where TEntity : XBaseEntity { public async Task GenerateKey( IXBaseRepository repository, diff --git a/Providers/XStringKeyGenerator.cs b/Providers/XStringKeyGenerator.cs index f47f68b..86c4c31 100644 --- a/Providers/XStringKeyGenerator.cs +++ b/Providers/XStringKeyGenerator.cs @@ -7,7 +7,13 @@ using xModels.Base; namespace xDataService.Providers { - public class XStringKeyGenerator : IXKeyGenerator, string> + /// + /// Default Guid Key Generator ... + /// + /// + + public class XStringKeyGenerator : IXKeyGenerator + where TEntity : XBaseEntity { private readonly IXSequentialGuid sequentialGuid; @@ -17,7 +23,7 @@ namespace xDataService.Providers } public async Task GenerateKey( - IXBaseRepository, string> repository, + IXBaseRepository repository, CancellationToken cancellationToken = default ) { diff --git a/xDataService.csproj b/xDataService.csproj index bc90a28..659bd2d 100644 --- a/xDataService.csproj +++ b/xDataService.csproj @@ -2,7 +2,7 @@ 1.0.0 - 8.0 + 12.0 Hadi Khazaee Asl SaherElm IT Center xDashboard.xDataService