This commit is contained in:
2026-05-08 04:30:04 +03:30
parent afe5c74d09
commit 34afd95640
20 changed files with 1022 additions and 713 deletions
+22
View File
@@ -0,0 +1,22 @@
using xDataService.Constants;
namespace xDataService.Configuration
{
/// <summary>
/// Describe a Database ...
/// </summary>
public class XDataBaseConfiguration
{
/// <summary>
/// Provider Type ...
/// </summary>
/// <value></value>
public XDbProviders Provider { get; set; }
/// <summary>
/// Connection String which provide Requires Data to Connect to Db Provider ...
/// </summary>
/// <value></value>
public string ConnectionString { get; set; }
}
}
+17 -18
View File
@@ -1,15 +1,25 @@
using System.Collections.Generic;
using xDataService.Constants; using xDataService.Constants;
namespace xDataService.Configuration { namespace xDataService.Configuration
{
/// <summary> /// <summary>
/// Represent Configurations of DataService Module ... /// Represent Configurations of DataService Module ...
/// </summary> /// </summary>
public partial class XDataServiceConfiguration { public partial class XDataServiceConfiguration
{
/// <summary> /// <summary>
/// Provider Type ... /// the base path for providing GraphQL ...
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public XDbProviders Provider { get; set; } public string GraphQLBasePath { get; set; } = "/graphql";
/// <summary>
/// Data Bases Configuration ...
/// </summary>
/// <typeparam name="XDataBaseConfiguration"></typeparam>
/// <returns></returns>
public Dictionary<string, XDataBaseConfiguration> Databases { get; set; } = new Dictionary<string, XDataBaseConfiguration>();
/// <summary> /// <summary>
/// Enable Soft Delete Entities or Not ... /// Enable Soft Delete Entities or Not ...
@@ -17,12 +27,6 @@ namespace xDataService.Configuration {
/// <value></value> /// <value></value>
public bool EnableSoftDelete { get; set; } public bool EnableSoftDelete { get; set; }
/// <summary>
/// Connection String which provide Requires Data to Connect to Db Provider ...
/// </summary>
/// <value></value>
public string ConnectionString { get; set; }
/// <summary> /// <summary>
/// Enable Tracking of Entities ... /// Enable Tracking of Entities ...
/// Only Used on EFCore ... /// Only Used on EFCore ...
@@ -48,19 +52,14 @@ namespace xDataService.Configuration {
/// this is a way to provide Default Pagination Data on XQuery based requests ... /// this is a way to provide Default Pagination Data on XQuery based requests ...
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration (); public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration();
/// <summary>
/// the base path for providing GraphQL ...
/// </summary>
/// <value></value>
public string GraphQLBasePath { get; set; } = "/graphql";
} }
/// <summary> /// <summary>
/// this is a way to provide Default Pagination Data on XQuery based requests ... /// this is a way to provide Default Pagination Data on XQuery based requests ...
/// </summary> /// </summary>
public partial class PagingConfiguration { public partial class PagingConfiguration
{
/// <summary> /// <summary>
/// Default Page Size ... /// Default Page Size ...
/// </summary> /// </summary>
@@ -1,8 +0,0 @@
namespace xDataService.Configuration {
public partial class XDbProviderConfigurations {
/// <summary>
/// Default ConnectionString Name ...
/// </summary>
public const string DEFAULT_CONNECTION_NAME = "DataConnection";
}
}
+211 -517
View File
@@ -1,618 +1,312 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using GraphQL.Server; using System.Reflection;
using GraphQL.Server.Ui.Playground;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using MySql.EntityFrameworkCore.Extensions;
using xCommons.Extensions; using xCommons.Extensions;
using xCommons.Helpers;
using xDataService.Configuration; using xDataService.Configuration;
using xDataService.Constants; using xDataService.Constants;
using xDataService.Db; using xDataService.Db;
using xDataService.Extensions; using xDataService.Helpers;
using xDataService.Interfaces; using xDataService.Interfaces;
using xDataService.Models;
using xExceptions.Constants; using xExceptions.Constants;
using xModels.Base;
namespace xDataService.DI {
public static class XDIHelperExtension {
/// <summary>
/// Extract Connection String From IConfiguration
/// </summary>
/// <param name="config"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static string GetXConnectionString (
this IConfiguration config,
string connectionName = null
) {
//
if (connectionName.IsNullOrEmpty ()) {
connectionName = XDbProviderConfigurations.DEFAULT_CONNECTION_NAME;
}
//
return config.GetConnectionString (connectionName);
}
/// <summary>
/// Retrieve Data Provider Type from Configurations
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
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
{
/// <summary> /// <summary>
/// Retrive XDataService Configurations /// Retrive XDataService Configurations
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <param name="connectionName"></param> /// <param name="connectionName"></param>
/// <returns></returns> /// <returns></returns>
public static XDataServiceConfiguration GetXDataServiceConfiguration ( public static XDataServiceConfiguration GetXDataServiceConfiguration(
this IConfiguration source, this IConfiguration source
string connectionName = null )
) { {
// //
var xDataServiceConfigSection = source var xDataServiceConfigSection = source
.GetSection (ConfigurationNodeNames.DATA_SERVICE_NODE); .GetSection(ConfigurationNodeNames.DATA_SERVICE_NODE);
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration> (); var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
//
result.Provider = source.GetXDbProviderType ();
result.ConnectionString = source.GetXConnectionString (connectionName);
// //
return result; return result;
} }
/// <summary> /// <summary>
/// Register XDataService Configuration /// Register XDataService Configuration ...
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="source"></param>
/// <param name="configuration"></param> /// <param name="configuration"></param>
/// <param name="connectionName"></param> public static void AddXDataServiceConfiguration(
public static void AddXDataServiceConfiguration ( this IServiceCollection source,
this IServiceCollection services, IConfiguration configuration
IConfiguration configuration, )
string connectionName = null {
) {
// //
var dataServiceConfiguration = configuration var config = configuration.GetXDataServiceConfiguration();
.GetXDataServiceConfiguration (connectionName); if (config.IsNullOrDefault())
if (dataServiceConfiguration.IsNull ()) { {
dataServiceConfiguration = new XDataServiceConfiguration (); //
Log("Configurations Not Founded ...");
XException.NotFound.Throw();
} }
// //
services.AddSingleton<XDataServiceConfiguration> (dataServiceConfiguration); source.AddSingleton(config);
} }
/// <summary> /// <summary>
/// Register XDataService Configuration /// Register XDataService Configuration ...
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="source"></param>
/// <param name="configuration"></param> /// <param name="configuration"></param>
public static void AddXDataServiceConfiguration ( public static void AddXDataServiceConfiguration(
this IServiceCollection services, this IServiceCollection source,
XDataServiceConfiguration configuration XDataServiceConfiguration configuration
) {
//
if (configuration.IsNull ()) {
configuration = new XDataServiceConfiguration ();
}
//
services.AddSingleton<XDataServiceConfiguration> (configuration);
}
/// <summary>
/// Register XDataService on DI
/// Only Used when EFCore Provider configured to use ...
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
/// <param name="lifetime"></param>
/// <param name="connectionName"></param>
/// <param name="optionsBuilder"></param>
public static void AddXDataService<TDbContext, TDbSeeder> (
this IServiceCollection services,
IConfiguration config,
ServiceLifetime lifetime,
string connectionName = null,
Action<dynamic> optionsBuilder = null
) )
where TDbContext : XDbContext {
where TDbSeeder : IXDbSeeder {
// //
// Register DataService Configuration ... if (configuration.IsNullOrDefault())
if (services.GetRegisteredService<XDataServiceConfiguration> ().IsNull ()) { {
Console.WriteLine ($"XDataService: there is no provided DataService Config, try to register default ..."); //
services.AddXDataServiceConfiguration (config, connectionName); Log("Configurations Not Founded ...");
XException.NotFound.Throw();
} }
// //
// prevent from going forward if there is no Provider configured ... source.AddSingleton(configuration);
var providerType = config.GetXDbProviderType (); }
Console.WriteLine ($"XDataService: registered db provider type is => {providerType} ...");
if (providerType == XDbProviders.None) { public static void AddXDatabase(
this IServiceCollection source,
IConfiguration configuration,
XDatabaseDescriptor descriptor,
ServiceLifetime lifetime = ServiceLifetime.Scoped
)
{
//
// Validate Database Descriptor ...
var isValid =
!descriptor.IsNullOrDefault() &&
!descriptor.Name.IsNullOrEmpty();
if (!isValid)
{
//
Log("Invalid Database Descriptor ...");
return; return;
} }
// //
// Retrieve IXDataServiceHelper ... // Check Service Collection Validation ...
var dataServiceHelper = services.GetRegisteredService<IXDataServiceHelper> (); isValid =
if (!dataServiceHelper.IsNull ()) { !source.IsNull() &&
!configuration.IsNull();
if (!isValid)
{
// //
// Use Db Context Helper ... Log("Invalid Service Provider or Configuration ...");
Console.WriteLine ($"XDataService: use provided IXDbContextHelper ..."); return;
//
// Retrieve Connection String ...
var addContext = true;
var connectionString = config.GetXConnectionString (connectionName);
switch (providerType) {
//
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;
} }
// //
// Register DbContext in DI ... // Get Registere Data Service Configuration ...
if (addContext) { var xDataServiceConfiguration = source
dataServiceHelper.AddDbContext ( .GetRegisteredService<XDataServiceConfiguration>();
services, isValid = !xDataServiceConfiguration.IsNullOrDefault();
connectionString, if (!isValid)
providerType, {
//
// Extract Configuration from Configuration ...
xDataServiceConfiguration = configuration.GetXDataServiceConfiguration();
isValid = !xDataServiceConfiguration.IsNullOrDefault();
if (!isValid)
{
//
Log("DataService Configuration notProvided ...");
return;
}
//
// 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, lifetime,
optionsBuilder descriptor.OptionsBuilder
]
); );
// //
// Register Unit Of Works ... // source.AddXDbContext<TContext>(
services.Add (new ServiceDescriptor (typeof (IXUnitOfWorks<TDbContext>), typeof (XUnitOfWorks<TDbContext>), lifetime)); // lifetime: lifetime,
// provider: descriptor.Provider,
// optionsBuilder: descriptor.OptionsBuilder,
// connectionString: descriptor.ConnectionString
// );
} }
// //
// Comment this in related to Task no. 27 ... // Register Repositories ...
// Register IXSequentialGuid for handle XBaseGuidEntities ... if (!descriptor.Repositories.IsNull() &&
// services.AddSingleton<IXSequentialGuid, XSequentialGuid> (); descriptor.Repositories.HasChild())
{
// source.AddXDataRepositories(
// // );
// Register All Repository Patterns ...
AddRepositories<TDbContext, TDbSeeder> (services, config, lifetime, providerType);
} else {
Console.WriteLine ($"XDataService: there is no provided IXDbContextHelper, data service registration failed ...");
}
}
/// <summary>
/// Register XDataService on DI
/// Only Used when non EFCore Provider configured to use ...
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
/// <param name="lifetime"></param>
/// <param name="connectionName"></param>
public static void AddXDataService<TDbSeeder> (
this IServiceCollection services,
IConfiguration config,
ServiceLifetime lifetime,
string connectionName = null
)
where TDbSeeder : IXDbSeeder {
//
// Register DataService Configuration ...
if (services.GetRegisteredService<XDataServiceConfiguration> ().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) {
return;
}
//
// Retrieve IXDataServiceHelper ...
var dataServiceHelper = services.GetRegisteredService<IXDataServiceHelper> ();
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<TDbContext, TDbSeeder> instead of AddXDataService<TDbSeeder> ...");
XException.InvalidConfiguration.Throw ();
break;
//
case XDbProviders.MongoDB:
//
#region XBaseEntity Mappers ...
//
// Map ID as BsonId here ...
BsonClassMap.RegisterClassMap<XBaseEntity<Guid>> (cm => {
//
cm.AutoMap ();
cm.MapIdMember (c => c.Id);
});
BsonClassMap.RegisterClassMap<XBaseEntity<int>> (cm => {
//
cm.AutoMap ();
cm.MapIdMember (c => c.Id);
});
BsonClassMap.RegisterClassMap<XBaseEntity<string>> (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<IXSequentialGuid, XSequentialGuid> ();
//
// Register All Repository Patterns ...
AddRepositories<TDbSeeder> (services, config, lifetime, providerType);
} else {
Console.WriteLine ($"XDataService: there is no provided IXDbContextHelper, data service registration failed ...");
}
}
/// <summary>
/// Register XGraphQL service ...
/// </summary>
/// <param name="services"></param>
/// <param name="options"></param>
public static void AddXGraphQL (
this IServiceCollection services,
Action<GraphQLOptions> options = null
) {
//
var xGraphQLHelper = services.GetRegisteredService<IXGraphQLHelper> ();
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 ...");
}
}
/// <summary>
/// Use XDataService MiddleWare
/// </summary>
/// <param name="app"></param>
public static void UseXDataService (
this IApplicationBuilder app
) {
app.SeedData ();
}
/// <summary>
/// Use XGraphQL Middleware ...
/// </summary>
/// <param name="app"></param>
/// <param name="options"></param>
/// <param name="withPlayground"></param>
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<IXGraphQLHelper> ();
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 ... #region Private ...
/// <summary> /// <summary>
/// Register Repositories on DI as Services /// a LogTag for xDataService ...
/// </summary> /// </summary>
/// <param name="services"></param> private static string XLogTag = "xDataService";
/// <param name="config"></param>
/// <param name="lifetime"></param>
/// <param name="provider"></param>
private static void AddRepositories<TDbContext, TDbSeeder> (
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<TDbContext> (services, lifetime);
break;
case XDbProviders.MongoDB:
Console.WriteLine ($"XDataService: for Mongo Provider Types use AddXDataService<TDbSeeder> instead of AddXDataService<TDbContext, TDbSeeder> ...");
XException.InvalidConfiguration.Throw ();
break;
}
// /// <summary>
// Retrieve IXDataServiceHelper ... /// print a log in Console ...
var dataServiceHelper = services.GetRegisteredService<IXDataServiceHelper> (); /// </summary>
if (dataServiceHelper.IsNull ()) { /// <param name="message"></param>
// private static void Log(string message)
Console.WriteLine ($"XDataService: there is no provided IXDataServiceHelper, db seeder registration failed ..."); {
return; Console.WriteLine($"{XLogTag} => {message}");
}
//
// Add DbSeeder Configuration ...
dataServiceHelper.AddDbSeederConfiguration (services, config);
//
// Add Db Seeder ...
dataServiceHelper.AddDbSeeder<TDbSeeder> (services, config, lifetime);
} }
/// <summary> /// <summary>
/// Register Repositories on DI as Services /// Register DbContext ...
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="source"></param>
/// <param name="config"></param>
/// <param name="lifetime"></param>
/// <param name="provider"></param> /// <param name="provider"></param>
private static void AddRepositories<TDbSeeder> ( /// <param name="connectionString"></param>
IServiceCollection services, /// <param name="lifetime"></param>
IConfiguration config, /// <param name="optionsBuilder"></param>
ServiceLifetime lifetime, /// <typeparam name="TContext"></typeparam>
XDbProviders provider private static void AddXDbContext<TContext>(
this IServiceCollection source,
XDbProviders provider,
string connectionString,
ServiceLifetime lifetime = ServiceLifetime.Scoped,
Action<dynamic> optionsBuilder = null
) )
where TDbSeeder : IXDbSeeder { where TContext : XDbContext
{
// //
// Add Repositories Based On Provider Here ... if (provider == XDbProviders.None)
switch (provider) { {
// //
Log("Invalid Db Provider ...");
XException.InvalidArgs.Throw();
}
//
switch (provider)
{
//
// MySQL ...
case XDbProviders.MySQL: case XDbProviders.MySQL:
//
source.AddDbContext<TContext>(cfg =>
{
cfg.UseMySQL(connectionString, optionsBuilder);
}, lifetime);
break;
//
// SQLite ...
case XDbProviders.SQLite: case XDbProviders.SQLite:
//
source.AddDbContext<TContext>(cfg =>
{
cfg.UseSqlite(connectionString, optionsBuilder);
}, lifetime);
break;
//
// SQLServer ...
case XDbProviders.SQLServer: case XDbProviders.SQLServer:
Console.WriteLine ($"XDataService: for EF Provider Types use AddXDataService<TDbContext, TDbSeeder> instead of AddXDataService<TDbSeeder> ..."); //
XException.InvalidConfiguration.Throw (); source.AddDbContext<TContext>(cfg =>
{
cfg.UseSqlServer(connectionString, optionsBuilder);
}, lifetime);
break; break;
// //
case XDbProviders.MongoDB: case XDbProviders.MongoDB:
AddMongoRepositories (services, lifetime); // There is notRequired to Register DBConext forMongo DB ...
break; break;
} }
//
// Retrieve IXDataServiceHelper ...
var dataServiceHelper = services.GetRegisteredService<IXDataServiceHelper> ();
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<TDbSeeder> (services, config, lifetime);
}
/// <summary>
/// Add Entity Framework Repositories
/// </summary>
/// <param name="services"></param>
/// <param name="lifetime"></param>
private static void AddEFRepositories<TDbContext> (
this IServiceCollection services,
ServiceLifetime lifetime
)
where TDbContext : XDbContext {
//
var repoServices = new List<ServiceDescriptor> ();
//
var dataServiceConfig = services.GetRegisteredService<XDataServiceConfiguration> ();
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<IXDataServiceHelper> ();
if (!dataServiceHelper.IsNull ()) {
//
// Register Repositories ...
dataServiceHelper.AddRepositories (services, lifetime);
//
// Register KeyGenerators ...
dataServiceHelper.AddKeyGenerators (services);
}
}
/// <summary>
/// Add MongoDb Repositories
/// </summary>
/// <param name="services"></param>
/// <param name="lifetime"></param>
private static void AddMongoRepositories (
this IServiceCollection services,
ServiceLifetime lifetime
) {
//
var repoServices = new List<ServiceDescriptor> ();
//
var dataServiceConfig = services.GetRegisteredService<XDataServiceConfiguration> ();
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<IXDataServiceHelper> ();
if (!dataServiceHelper.IsNull ()) {
//
// Register Repositories ...
dataServiceHelper.AddRepositories (services, lifetime);
//
// Register KeyGenerators ...
dataServiceHelper.AddKeyGenerators (services);
}
} }
/// <summary> /// <summary>
/// Do Seeding Initialization Data on DbContext /// Do Seeding Initialization Data on DbContext
/// </summary> /// </summary>
/// <param name="app"></param> /// <param name="app"></param>
private static void SeedData ( private static void SeedData(
this IApplicationBuilder app this IApplicationBuilder app
) { )
{
// //
using (var scope = app.ApplicationServices.CreateScope ()) { using (var scope = app.ApplicationServices.CreateScope())
{
// //
var dbSeeder = scope.ServiceProvider.GetService<IXDbSeeder> (); var dbSeeder = scope.ServiceProvider.GetService<IXDbSeeder>();
Console.WriteLine ($"XDataService: dbSeeder retrieved from DI is => {!dbSeeder.IsNull()}"); Console.WriteLine($"XDataService: dbSeeder retrieved from DI is => {!dbSeeder.IsNull()}");
// //
if (!dbSeeder.IsNull ()) { if (!dbSeeder.IsNull())
try { {
try
{
// //
dbSeeder.Seed () dbSeeder.Seed()
.GetAwaiter () .GetAwaiter()
.GetResult (); .GetResult();
} catch (Exception ex) { }
catch (Exception ex)
{
// //
Console.WriteLine (" "); Console.WriteLine(" ");
Console.WriteLine ($"XDataService: Seeding Error: {ex.Message}"); Console.WriteLine($"XDataService: Seeding Error: {ex.Message}");
XException.InvalidConfiguration.Throw (); XException.InvalidConfiguration.Throw();
} }
} }
} }
@@ -39,7 +39,7 @@ namespace xDataService.Extensions {
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <returns></returns> /// <returns></returns>
public static string GetMongoDbURI (this XDataServiceConfiguration source) { public static string GetMongoDbURI (this XDataBaseConfiguration source) {
// //
var parts = source.GetConnectionParts (); var parts = source.GetConnectionParts ();
var result = parts var result = parts
@@ -56,7 +56,7 @@ namespace xDataService.Extensions {
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <returns></returns> /// <returns></returns>
public static string GetMongoDbDatabase (this XDataServiceConfiguration source) { public static string GetMongoDbDatabase (this XDataBaseConfiguration source) {
// //
var parts = source.GetConnectionParts (); var parts = source.GetConnectionParts ();
var result = parts var result = parts
@@ -70,7 +70,7 @@ namespace xDataService.Extensions {
// //
#region Private ... #region Private ...
private static string[] GetConnectionParts (this XDataServiceConfiguration source) { private static string[] GetConnectionParts (this XDataBaseConfiguration source) {
// //
var result = source.ConnectionString.Split (';'); var result = source.ConnectionString.Split (';');
+100 -78
View File
@@ -9,164 +9,186 @@ using xDataService.Interfaces;
using xDataService.Models; using xDataService.Models;
using xModels.Base; using xModels.Base;
namespace xDataService.GraphQL { namespace xDataService.GraphQL
public abstract class XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> : ObjectGraphType, IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> {
where TEntity : XBaseEntity<TKey> public abstract class XBaseGraphQLQuery : ObjectGraphType, IXBaseGraphQLQuery { }
where TGraph : IGraphType
where TGraphKey : IGraphType {
//
private readonly XDataServiceConfiguration configuration;
private readonly IXBaseRepository<TEntity, TKey> repository;
private readonly IXBaseGraphQLTypeHelper<TEntity, TKey> helper;
public abstract class XBaseGraphQLQuery<TEntity, TKey> : XBaseGraphQLQuery, IXBaseGraphQLQuery<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
// //
public XBaseGraphQLQuery ( protected readonly XDataServiceConfiguration configuration;
protected readonly IXBaseRepository<TEntity, TKey> repository;
protected readonly IXBaseGraphQLTypeHelper<TEntity, TKey> helper;
public XBaseGraphQLQuery(
XDataServiceConfiguration configuration, XDataServiceConfiguration configuration,
IXBaseRepository<TEntity, TKey> repository, IXBaseRepository<TEntity, TKey> repository,
IXBaseGraphQLTypeHelper<TEntity, TKey> helper IXBaseGraphQLTypeHelper<TEntity, TKey> helper
) { )
{
// //
this.helper = helper; this.helper = helper;
this.repository = repository; this.repository = repository;
this.configuration = configuration; this.configuration = configuration;
// //
Name = GetType ().Name; Name = GetType().Name;
}
}
public abstract class XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> : XBaseGraphQLQuery<TEntity, TKey>, IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
where TEntity : XBaseEntity<TKey>
where TGraph : IGraphType
where TGraphKey : IGraphType
{
//
public XBaseGraphQLQuery(
XDataServiceConfiguration configuration,
IXBaseRepository<TEntity, TKey> repository,
IXBaseGraphQLTypeHelper<TEntity, TKey> helper
) : base(
helper: helper,
repository: repository,
configuration: configuration
)
{
// //
#region Retrieve ... #region Retrieve ...
// //
// Get ... // Get ...
FieldAsync<TGraph> ( FieldAsync<TGraph>(
name: helper.GetInQuerySingleName (), name: helper.GetInQuerySingleName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.GetIdArgument<TGraphKey> (), XGraphQLHelper.GetIdArgument<TGraphKey>(),
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async context => resolve: async context =>
await repository await repository
.GetAsync ( .GetAsync(
includeBuilder: null, includeBuilder: null,
id: context.GetIdArgument<TKey> (), id: context.GetIdArgument<TKey>(),
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
.ToDynamicObject () .ToDynamicObject()
); );
// //
// GetAll ... // GetAll ...
FieldAsync<ListGraphType<TGraph>> ( FieldAsync<ListGraphType<TGraph>>(
name: helper.GetInQueryCollectionName (), name: helper.GetInQueryCollectionName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async context => resolve: async context =>
await repository await repository
.GetAllAsync ( .GetAllAsync(
orderBuilder: null, orderBuilder: null,
includeBuilder: null, includeBuilder: null,
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
.ToDynamicObject () .ToDynamicObject()
); );
// //
// FindOne ... // FindOne ...
FieldAsync<TGraph> ( FieldAsync<TGraph>(
name: helper.GetFindOneName (), name: helper.GetFindOneName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.SearchQueryArgument, XGraphQLHelper.SearchQueryArgument,
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async (context) => { resolve: async (context) =>
{
// //
var searchQuery = context.GetSearchQueryArgument (); var searchQuery = context.GetSearchQueryArgument();
Expression<Func<TEntity, bool>> whereClase = pe => pe Expression<Func<TEntity, bool>> whereClase = pe => pe
.PropValuesContains (searchQuery); .PropValuesContains(searchQuery);
// //
return await repository return await repository
.FindOneAsync ( .FindOneAsync(
includeBuilder: null, includeBuilder: null,
predicate: whereClase, predicate: whereClase,
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
.ToDynamicObject (); .ToDynamicObject();
} }
); );
// //
// FindMany ... // FindMany ...
FieldAsync<ListGraphType<TGraph>> ( FieldAsync<ListGraphType<TGraph>>(
name: helper.GetFindManyName (), name: helper.GetFindManyName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.SearchQueryArgument, XGraphQLHelper.SearchQueryArgument,
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async (context) => { resolve: async (context) =>
{
// //
var searchQuery = context.GetSearchQueryArgument (); var searchQuery = context.GetSearchQueryArgument();
Expression<Func<TEntity, bool>> whereClase = pe => pe Expression<Func<TEntity, bool>> whereClase = pe => pe
.PropValuesContains (searchQuery); .PropValuesContains(searchQuery);
// //
return await repository return await repository
.FindManyAsync ( .FindManyAsync(
orderBuilder: null, orderBuilder: null,
includeBuilder: null, includeBuilder: null,
predicate: whereClase, predicate: whereClase,
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
.ToDynamicObject (); .ToDynamicObject();
} }
); );
// //
// Query ... // Query ...
FieldAsync<XGraphQueryResult<TEntity, TGraph>> ( FieldAsync<XGraphQueryResult<TEntity, TGraph>>(
name: helper.GetQueryName (), name: helper.GetQueryName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.QueryArgument, XGraphQLHelper.QueryArgument,
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async context =>
await repository
.QueryAsync (
predicate: null,
orderBuilder: null,
includeBuilder: null,
query: context.GetQueryArgument (),
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument ()
)
.ToDynamicObject ()
);
//
// Count ...
FieldAsync<IntGraphType> (
name: helper.GetCountName (),
arguments: new QueryArguments (
XGraphQLHelper.IgnoreSoftDeletedArgument
),
resolve: async context => resolve: async context =>
await repository await repository
.CountAsync ( .QueryAsync(
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () predicate: null,
orderBuilder: null,
includeBuilder: null,
query: context.GetQueryArgument(),
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
)
.ToDynamicObject()
);
//
// Count ...
FieldAsync<IntGraphType>(
name: helper.GetCountName(),
arguments: new QueryArguments(
XGraphQLHelper.IgnoreSoftDeletedArgument
),
resolve: async context =>
await repository
.CountAsync(
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
); );
// //
// Exists ... // Exists ...
FieldAsync<BooleanGraphType> ( FieldAsync<BooleanGraphType>(
name: helper.GetExistsName (), name: helper.GetExistsName(),
arguments: new QueryArguments ( arguments: new QueryArguments(
XGraphQLHelper.GetIdArgument<TGraphKey> (), XGraphQLHelper.GetIdArgument<TGraphKey>(),
XGraphQLHelper.IgnoreSoftDeletedArgument XGraphQLHelper.IgnoreSoftDeletedArgument
), ),
resolve : async context => resolve: async context =>
await repository.IsExistsAsync ( await repository.IsExistsAsync(
id: context.GetIdArgument<TKey> (), id: context.GetIdArgument<TKey>(),
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument () ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
) )
); );
#endregion #endregion
+74 -22
View File
@@ -3,62 +3,114 @@ using xDataService.Configuration;
using xDataService.Interfaces; using xDataService.Interfaces;
using xModels.Base; using xModels.Base;
namespace xDataService.GraphQL { namespace xDataService.GraphQL
public abstract class XBaseGraphQLTypeHelper<TEntity, TKey> : IXBaseGraphQLTypeHelper<TEntity, TKey> {
where TEntity : XBaseEntity<TKey> { public abstract class XBaseGraphQLTypeHelper : IXBaseGraphQLTypeHelper
{
// //
private readonly XDataServiceConfiguration configuration; protected readonly XDataServiceConfiguration configuration;
// //
public XBaseGraphQLTypeHelper ( public XBaseGraphQLTypeHelper(
XDataServiceConfiguration configuration = null XDataServiceConfiguration configuration
) { )
{
this.configuration = configuration; this.configuration = configuration;
} }
// public abstract string GetInQuerySingleName();
public abstract string GetInQueryCollectionName ();
public abstract string GetInQuerySingleName (); public abstract string GetInQueryCollectionName();
// //
public string GetFindOneName () { #region Actions ...
return $"find{GetInQuerySingleName ().ToNormalString().Capitalize()}"; public virtual string GetCountName()
{
return string.Empty;
} }
public string GetFindManyName () { public virtual string GetExistsName()
return $"find{GetInQueryCollectionName ().ToNormalString().Capitalize()}"; {
return string.Empty;
} }
public string GetQueryName () { 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<TEntity, TKey> : XBaseGraphQLTypeHelper, IXBaseGraphQLTypeHelper<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
//
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()}"; return $"query{GetInQueryCollectionName().ToNormalString().Capitalize()}";
} }
public string GetCountName () { public override string GetCountName()
{
return $"count{GetInQueryCollectionName().ToNormalString().Capitalize()}"; return $"count{GetInQueryCollectionName().ToNormalString().Capitalize()}";
} }
public string GetExistsName () { public override string GetExistsName()
{
return $"exists{GetInQuerySingleName().ToNormalString().Capitalize()}"; return $"exists{GetInQuerySingleName().ToNormalString().Capitalize()}";
} }
public string GetGraphQLPath (string baseGraphPath = null) { public override string GetGraphQLPath(string baseGraphPath = null)
{
// //
baseGraphPath = baseGraphPath.IsNullOrEmpty () ? baseGraphPath = baseGraphPath.IsNullOrEmpty() ?
configuration.IsNull () || configuration.GraphQLBasePath.IsNullOrEmpty () ? configuration.IsNull() || configuration.GraphQLBasePath.IsNullOrEmpty() ?
"" : "" :
configuration.GraphQLBasePath : configuration.GraphQLBasePath :
baseGraphPath; baseGraphPath;
// //
var basePath = baseGraphPath var basePath = baseGraphPath
.EndsWith ("/") ? .EndsWith("/") ?
baseGraphPath baseGraphPath
.Substring (0, baseGraphPath.Length - 1) : .Substring(0, baseGraphPath.Length - 1) :
baseGraphPath; baseGraphPath;
// //
return $"{basePath}/{GetInQueryCollectionName().ToNormalString()}"; return $"{basePath}/{GetInQueryCollectionName().ToNormalString()}";
} }
#endregion
} }
} }
+79
View File
@@ -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
{
/// <summary>
/// Register DbContext ...
/// </summary>
/// <param name="source"></param>
/// <param name="provider"></param>
/// <param name="connectionString"></param>
/// <param name="lifetime"></param>
/// <param name="optionsBuilder"></param>
/// <typeparam name="TContext"></typeparam>
public static void AddXDbContext<TContext>(
IServiceCollection source,
XDbProviders provider,
string connectionString,
ServiceLifetime lifetime = ServiceLifetime.Scoped,
Action<dynamic> optionsBuilder = null
)
where TContext : XDbContext
{
//
if (provider == XDbProviders.None)
{
//
// Log("Invalid Db Provider ...");
XException.InvalidArgs.Throw();
}
//
switch (provider)
{
//
// MySQL ...
case XDbProviders.MySQL:
//
source.AddDbContext<TContext>(cfg =>
{
cfg.UseMySQL(connectionString, optionsBuilder);
}, lifetime);
break;
//
// SQLite ...
case XDbProviders.SQLite:
//
source.AddDbContext<TContext>(cfg =>
{
cfg.UseSqlite(connectionString, optionsBuilder);
}, lifetime);
break;
//
// SQLServer ...
case XDbProviders.SQLServer:
//
source.AddDbContext<TContext>(cfg =>
{
cfg.UseSqlServer(connectionString, optionsBuilder);
}, lifetime);
break;
//
case XDbProviders.MongoDB:
// There is notRequired to Register DBConext forMongo DB ...
break;
}
}
}
}
+11 -3
View File
@@ -1,9 +1,17 @@
using GraphQL.Types; using GraphQL.Types;
using xModels.Base; using xModels.Base;
namespace xDataService.Interfaces { namespace xDataService.Interfaces
public interface IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> {
public interface IXBaseGraphQLQuery { }
public interface IXBaseGraphQLQuery<TEntity, TKey> : IXBaseGraphQLQuery
where TEntity : XBaseEntity<TKey>
{ }
public interface IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> : IXBaseGraphQLQuery<TEntity, TKey>
where TEntity : XBaseEntity<TKey> where TEntity : XBaseEntity<TKey>
where TGraph : IGraphType where TGraph : IGraphType
where TGraphKey : IGraphType { } where TGraphKey : IGraphType
{ }
} }
+17 -11
View File
@@ -1,21 +1,27 @@
using xModels.Base; using xModels.Base;
namespace xDataService.Interfaces { namespace xDataService.Interfaces
public interface IXBaseGraphQLTypeHelper<TEntity, TKey> {
where TEntity : XBaseEntity<TKey> { public interface IXBaseGraphQLTypeHelper
string GetInQuerySingleName (); {
string GetInQueryCollectionName (); 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<TEntity, TKey> : IXBaseGraphQLTypeHelper
where TEntity : XBaseEntity<TKey>
{ }
} }
+3 -1
View File
@@ -10,13 +10,15 @@ using xModels.Dtos;
namespace xDataService.Interfaces namespace xDataService.Interfaces
{ {
public interface IXBaseRepository : IDisposable { }
/// <summary> /// <summary>
/// Base Repository Pattern Contracts in XDashboard's Data Service ... /// Base Repository Pattern Contracts in XDashboard's Data Service ...
/// use for Data Manipulation ... /// use for Data Manipulation ...
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <typeparam name="TKey"></typeparam> /// <typeparam name="TKey"></typeparam>
public interface IXBaseRepository<T, TKey> : IDisposable public interface IXBaseRepository<T, TKey> : IXBaseRepository
where T : XBaseEntity<TKey> where T : XBaseEntity<TKey>
{ {
// //
+113
View File
@@ -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
{
/// <summary>
/// Data Base Descriptor ...
/// </summary>
public interface IXDatabaseDescriptor
{
//
#region Props ...
/// <summary>
/// Database Name ...
/// </summary>
/// <value></value>
string Name { get; set; }
/// <summary>
/// Database Provider ...
/// </summary>
/// <value></value>
XDbProviders Provider { get; set; }
/// <summary>
/// Db Context Type ...
/// </summary>
/// <value></value>
Type Context { get; set; }
/// <summary>
/// Database Connecion String ...
/// </summary>
/// <value></value>
string ConnectionString { get; set; }
/// <summary>
/// Data Service Configuration ...
/// </summary>
/// <value></value>
XDataBaseConfiguration Configuration { get; set; }
/// <summary>
/// Repositories Descriptions ...
/// </summary>
/// <value></value>
IList<XRepositoryDescriptor> Repositories { get; set; }
/// <summary>
/// Mongo Convention Packs ...
/// </summary>
ConventionPack ConventionPacks { get; set; }
/// <summary>
/// DbContext Options Builder ...
/// </summary>
/// <value></value>
Action<dynamic> OptionsBuilder { get; set; }
#endregion
//
#region Configure ...
/// <summary>
/// Configure Database Descriptor using Registered Services ...
/// </summary>
/// <param name="services"></param>
void Configure(
IServiceCollection services
);
/// <summary>
/// Configure Database Descriptor using IConfiguration ...
/// </summary>
/// <param name="configuration"></param>
void Configure(
IConfiguration configuration
);
/// <summary>
/// Configure Database Descriptor using Database Configuration ...
/// </summary>
/// <param name="configuration"></param>
void Configure(
XDataBaseConfiguration configuration
);
/// <summary>
/// Configure Database Descriptor using Provider and Connection String ...
/// </summary>
/// <param name="provider"></param>
/// <param name="connectionString"></param>
void Configure(
XDbProviders provider,
string connectionString
);
#endregion
}
/// <summary>
/// Data Base Descriptor ...
/// </summary>
/// <typeparam name="TContext"></typeparam>
public interface IXDatabaseDescriptor<TContext> : IXDatabaseDescriptor
where TContext : XDbContext
{ }
}
+17 -5
View File
@@ -2,11 +2,23 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using xModels.Base; using xModels.Base;
namespace xDataService.Interfaces { namespace xDataService.Interfaces
public interface IXKeyGenerator<TEntity, TKey> {
where TEntity : XBaseEntity<TKey> { /// <summary>
bool IsEmpty (TKey id); /// Non Generic Key Generator Interface ...
Task<TKey> GenerateKey ( /// </summary>
public interface IXKeyGenerator { }
/// <summary>
/// Typed Base Key Generator ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public interface IXKeyGenerator<TEntity, TKey> : IXKeyGenerator
where TEntity : XBaseEntity<TKey>
{
bool IsEmpty(TKey id);
Task<TKey> GenerateKey(
IXBaseRepository<TEntity, TKey> repository, IXBaseRepository<TEntity, TKey> repository,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
+229
View File
@@ -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
{
/// <summary>
/// Data Base Descriptor ...
/// </summary>
public abstract class XDatabaseDescriptor : IXDatabaseDescriptor
{
//
#region Props ...
/// <summary>
/// Database Name ...
/// </summary>
/// <value></value>
public virtual string Name { get; set; }
/// <summary>
/// Database Provider ...
/// </summary>
/// <value></value>
public virtual XDbProviders Provider { get; set; }
/// <summary>
/// Db Context...
/// </summary>
/// <value></value>
public virtual Type Context { get; set; } = null;
/// <summary>
/// Database Connecion String ...
/// </summary>
/// <value></value>
public virtual string ConnectionString { get; set; }
/// <summary>
/// Data Service Configuration ...
/// </summary>
/// <value></value>
public virtual XDataBaseConfiguration Configuration { get; set; }
/// <summary>
/// Repositories Descriptions ...
/// </summary>
/// <value></value>
public virtual IList<XRepositoryDescriptor> Repositories { get; set; } = null;
/// <summary>
/// Mongo Convention Packs ...
/// </summary>
public ConventionPack ConventionPacks { get; set; } = null;
/// <summary>
/// DbContext Options Builder ...
/// </summary>
/// <value></value>
public Action<dynamic> OptionsBuilder { get; set; } = null;
#endregion
//
#region Constructor ...
/// <summary>
/// Constructor of Descriptor ...
/// </summary>
/// <param name="name"></param>
/// <param name="configuration"></param>
/// <param name="repositories"></param>
public XDatabaseDescriptor(
string name,
IList<XRepositoryDescriptor> repositories = null
)
{
//
Name = name;
Repositories = repositories;
}
#endregion
//
#region Configure ...
/// <summary>
/// Configure Database Descriptor using Registered Services ...
/// </summary>
/// <param name="services"></param>
public void Configure(
IServiceCollection services
)
{
//
bool isValid = !Name.IsNullOrEmpty();
if (!isValid)
{
return;
}
//
var xDataServiceConfiguration = services.GetRegisteredService<XDataServiceConfiguration>();
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);
}
/// <summary>
/// Configure Database Descriptor using IConfiguration ...
/// </summary>
/// <param name="configuration"></param>
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);
}
/// <summary>
/// Configure Database Descriptor using Database Configuration ...
/// </summary>
/// <param name="configuration"></param>
public void Configure(
XDataBaseConfiguration configuration
)
{
//
Configuration = configuration;
Provider = configuration.Provider;
ConnectionString = configuration.ConnectionString;
}
/// <summary>
/// Configure Database Descriptor using Provider and Connection String ...
/// </summary>
/// <param name="provider"></param>
/// <param name="connectionString"></param>
public void Configure(
XDbProviders provider,
string connectionString
)
{
//
Provider = provider;
ConnectionString = connectionString;
Configuration = new XDataBaseConfiguration
{
Provider = provider,
ConnectionString = connectionString
};
}
#endregion
}
/// <summary>
/// Data Base Descriptor ...
/// </summary>
/// <typeparam name="TContext"></typeparam>
public abstract class XDatabaseDescriptor<TContext> : XDatabaseDescriptor, IXDatabaseDescriptor<TContext>
where TContext : XDbContext
{
/// <summary>
/// Constructor of Descriptor ...
/// </summary>
/// <param name="name"></param>
/// <param name="configuration"></param>
/// <param name="context"></param>
/// <param name="repositories"></param>
public XDatabaseDescriptor(
string name,
IList<XRepositoryDescriptor> repositories = null
) : base(
name: name,
repositories: repositories
)
{
Context = typeof(TContext);
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using GraphQL.Types;
using xDataService.GraphQL;
using xDataService.Interfaces;
using xModels.Base;
namespace xDataService.Models
{
/// <summary>
/// a Global non Generic Repository Descriptor ...
/// </summary>
public class XRepositoryDescriptor { }
/// <summary>
/// a Repository Descriptor ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public class XRepositoryDescriptor<TEntity, TKey> : XRepositoryDescriptor
where TEntity : XBaseEntity<TKey>
{
/// <summary>
/// Entity Type GraphQL Schema ...
/// </summary>
/// <value></value>
public Schema GraphSchema { get; set; } = null;
/// <summary>
/// Entity GraphQL Type Helper ...
/// </summary>
/// <value></value>
public IXBaseGraphQLTypeHelper GraphTypeHelper { get; set; } = null;
/// <summary>
/// Entity GrapQL Query ...
/// </summary>
/// <value></value>
public IXBaseGraphQLQuery<TEntity, TKey> GraphQuery { get; set; } = null;
/// <summary>
/// Entity GraphQL Type ...
/// </summary>
/// <value></value>
public XBaseGraphObjectType<TEntity, TKey> GraphType { get; set; } = null;
/// <summary>
/// Repository Event Provider ...
/// </summary>
/// <value></value>
public IXBaseRepositoryEvents<TEntity> Events { get; set; } = null;
/// <summary>
/// Repository Key Generator for Entity ...
/// </summary>
/// <value></value>
public IXKeyGenerator<TEntity, TKey> KeyGenerator { get; set; } = null;
/// <summary>
/// Repository Data Access Design Pattern ...
/// </summary>
/// <value></value>
public IXBaseRepository<TEntity, TKey> Repository { get; set; }
}
}
+5 -3
View File
@@ -8,7 +8,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query;
using MongoDB.Driver; using MongoDB.Driver;
using MongoDB.Driver.Linq; using MongoDB.Driver.Linq;
using Org.BouncyCastle.Asn1.Ocsp;
using xCommons.Extensions; using xCommons.Extensions;
using xDataService.Configuration; using xDataService.Configuration;
using xDataService.Extensions; using xDataService.Extensions;
@@ -34,6 +33,7 @@ namespace xDataService.MongoRepositories
public List<WriteModel<T>> bulkCollection; public List<WriteModel<T>> bulkCollection;
public readonly IMongoCollection<T> collection; public readonly IMongoCollection<T> collection;
private readonly IXKeyGenerator<T, TKey> keyGenerator; private readonly IXKeyGenerator<T, TKey> keyGenerator;
public readonly XDataBaseConfiguration dbConfiguration;
public readonly XDataServiceConfiguration configuration; public readonly XDataServiceConfiguration configuration;
private readonly IXBaseRepositoryEvents<T> baseRepositoryEvents; private readonly IXBaseRepositoryEvents<T> baseRepositoryEvents;
#endregion #endregion
@@ -41,6 +41,7 @@ namespace xDataService.MongoRepositories
// //
#region Constructor ... #region Constructor ...
protected XBaseMongoRepository( protected XBaseMongoRepository(
XDataBaseConfiguration dbConfiguration,
XDataServiceConfiguration configuration, XDataServiceConfiguration configuration,
string collectionName = null, string collectionName = null,
IXKeyGenerator<T, TKey> keyGenerator = null, IXKeyGenerator<T, TKey> keyGenerator = null,
@@ -54,11 +55,12 @@ namespace xDataService.MongoRepositories
.IsNullOrEmpty() ? .IsNullOrEmpty() ?
typeof(T).Name : typeof(T).Name :
collectionName; collectionName;
this.dbConfiguration = dbConfiguration;
this.baseRepositoryEvents = baseRepositoryEvents; this.baseRepositoryEvents = baseRepositoryEvents;
// //
var client = new MongoClient(configuration.GetMongoDbURI()); var client = new MongoClient(dbConfiguration.GetMongoDbURI());
var database = client.GetDatabase(configuration.GetMongoDbDatabase()); var database = client.GetDatabase(dbConfiguration.GetMongoDbDatabase());
// //
bulkCollection = new List<WriteModel<T>>(); bulkCollection = new List<WriteModel<T>>();
+4
View File
@@ -7,6 +7,10 @@ using xModels.Base;
namespace xDataService.Providers namespace xDataService.Providers
{ {
/// <summary>
/// Default Guid Key Generator ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class XGuidKeyGenerator<TEntity> : IXKeyGenerator<TEntity, Guid> public class XGuidKeyGenerator<TEntity> : IXKeyGenerator<TEntity, Guid>
where TEntity : XBaseEntity<Guid> where TEntity : XBaseEntity<Guid>
{ {
+4
View File
@@ -8,6 +8,10 @@ using xModels.Base;
namespace xDataService.Providers namespace xDataService.Providers
{ {
/// <summary>
/// Default Int Key Generator ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class XIntKeyGenerator<TEntity> : IXKeyGenerator<TEntity, int> public class XIntKeyGenerator<TEntity> : IXKeyGenerator<TEntity, int>
where TEntity : XBaseEntity<int> where TEntity : XBaseEntity<int>
{ {
+8 -2
View File
@@ -7,7 +7,13 @@ using xModels.Base;
namespace xDataService.Providers namespace xDataService.Providers
{ {
public class XStringKeyGenerator : IXKeyGenerator<XBaseEntity<string>, string> /// <summary>
/// Default Guid Key Generator ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class XStringKeyGenerator<TEntity> : IXKeyGenerator<TEntity, string>
where TEntity : XBaseEntity<string>
{ {
private readonly IXSequentialGuid sequentialGuid; private readonly IXSequentialGuid sequentialGuid;
@@ -17,7 +23,7 @@ namespace xDataService.Providers
} }
public async Task<string> GenerateKey( public async Task<string> GenerateKey(
IXBaseRepository<XBaseEntity<string>, string> repository, IXBaseRepository<TEntity, string> repository,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
) )
{ {
+1 -1
View File
@@ -2,7 +2,7 @@
<!-- Runtime Definitions --> <!-- Runtime Definitions -->
<PropertyGroup> <PropertyGroup>
<Version>1.0.0</Version> <Version>1.0.0</Version>
<LangVersion>8.0</LangVersion> <LangVersion>12.0</LangVersion>
<Authors>Hadi Khazaee Asl</Authors> <Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company> <Company>SaherElm IT Center</Company>
<PackageId>xDashboard.xDataService</PackageId> <PackageId>xDashboard.xDataService</PackageId>