Files
xDataService/DI/XDIHelperExtension.cs
T
2026-05-09 22:21:40 +03:30

386 lines
14 KiB
C#

using System;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xCommons.Helpers;
using xDataService.Configuration;
using xDataService.Constants;
using xDataService.Extensions;
using xDataService.Helpers;
using xDataService.Interfaces;
using xDataService.Models;
using xExceptions.Constants;
namespace xDataService.DI
{
public static partial class XDIHelperExtension
{
/// <summary>
/// Retrive XDataService Configurations
/// </summary>
/// <param name="source"></param>
/// <param name="connectionName"></param>
/// <returns></returns>
public static XDataServiceConfiguration GetXDataServiceConfiguration(
this IConfiguration source
)
{
//
var xDataServiceConfigSection = source
.GetSection(ConfigurationNodeNames.DATA_SERVICE_NODE);
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
//
return result;
}
/// <summary>
/// Register XDataService Configuration ...
/// </summary>
/// <param name="source"></param>
/// <param name="configuration"></param>
public static void AddXDataServiceConfiguration(
this IServiceCollection source,
IConfiguration configuration
)
{
//
var config = configuration.GetXDataServiceConfiguration();
if (config.IsNullOrDefault())
{
//
Log("Configurations Not Founded ...");
XException.NotFound.Throw();
}
//
source.AddSingleton(config);
}
/// <summary>
/// Register XDataService Configuration ...
/// </summary>
/// <param name="source"></param>
/// <param name="configuration"></param>
public static void AddXDataServiceConfiguration(
this IServiceCollection source,
XDataServiceConfiguration configuration
)
{
//
if (configuration.IsNullOrDefault())
{
//
Log("Configurations Not Founded ...");
XException.NotFound.Throw();
}
//
source.AddSingleton(configuration);
}
/// <summary>
/// Register a Data Base using Descriptor ...
/// </summary>
/// <param name="source"></param>
/// <param name="configuration"></param>
/// <param name="descriptor"></param>
/// <param name="lifetime"></param>
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;
}
//
// Check Service Collection Validation ...
isValid =
!source.IsNull() &&
!configuration.IsNull();
if (!isValid)
{
//
Log("Invalid Service Provider or Configuration ...");
return;
}
//
// Get Registere Data Service Configuration ...
var xDataServiceConfiguration = source
.GetRegisteredService<XDataServiceConfiguration>();
isValid = !xDataServiceConfiguration.IsNullOrDefault();
if (!isValid)
{
//
// 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())
{
//
try
{
//
typeof(XDataServiceHelper).InvokeGenericMethod(
methodName: "AddXDbContext",
runtimeType: descriptor.Context,
args: [
source,
descriptor.Provider,
descriptor.ConnectionString,
lifetime,
descriptor.OptionsBuilder
]
);
//
Log($"DbContext: {descriptor.Name} Registered Successfully ...");
}
catch (Exception ex)
{
Log($"DbContext: {descriptor.Name} Registration failed due {ex.Message} ...");
}
}
//
// Register Repositories ...
if (!descriptor.Repositories.IsNull() &&
descriptor.Repositories.HasChild())
{
//
descriptor.Repositories.ToList().ForEach(r =>
{
//
// Preparing Runtime Types ...
Type[] runtimeTypes = r.GetType().GenericTypeArguments;
//
try
{
//
typeof(XDataServiceHelper).InvokeGenericMethod(
methodName: "AddXRepository",
runtimeTypes: runtimeTypes,
args: [
source,
r,
lifetime
]
);
//
Log($"Repository of: {runtimeTypes[0]}, Registered Successfully ...");
}
catch (Exception ex)
{
Log($"Repository of: {runtimeTypes[0]}, Registration failed due {ex.Message} ...");
}
});
}
}
public static void UseXDatabase(
this IApplicationBuilder source,
XDatabaseDescriptor descriptor
)
{
//
// Validate ...
var isValid =
!source.IsNull() &&
descriptor.IsValid();
if (!isValid)
{
//
Log("Invalid Database Configuration ...");
XException.InvalidArgs.Throw();
}
//
// Check Repositories Exists ...
isValid = descriptor.HasRepositories();
if (isValid)
{
//
// Create an Scope for Services Acces ...
using (var scope = source.ApplicationServices.CreateScope())
{
//
// Inject XDataServiceConfiguration ForMake Sure DataService Registration ...
var dataServiceConfiguration = scope.ServiceProvider.GetService<XDataServiceConfiguration>();
isValid = !dataServiceConfiguration.IsNullOrDefault();
if (isValid)
{
//
// Loop through Repositories ...
descriptor.Repositories
.ToList()
.ForEach(r =>
{
//
// Check GraphQL Support ...
isValid = r.HasGraphSupport();
if (isValid)
{
//
// Inject GraphQL Type Helper ...
var helper = scope.ServiceProvider.GetService(r.GraphTypeHelperService);
isValid = !helper.IsNullOrDefault();
if (!isValid)
{
//
Log($"unable to find GraphQLTypeHelper for Entiy: {r.Entity}");
XException.NotFound.Throw();
}
//
var methods = source.GetType().GetMethods();
isValid =
!methods.IsNull() &&
methods.HasChild();
if (isValid)
{
//
try
{
//
// UseGraphQL ...
var method = methods.First(m =>
m.IsGenericMethod &&
m.Name == "UseGraphQL" &&
m.GetGenericArguments().Length == 1 &&
m.GetParameters().Length == 1
);
var genericMethod = method.MakeGenericMethod(r.GraphSchema);
genericMethod.Invoke(null, ((dynamic)helper).GetGraphQLPath());
//
// UseGraphQLWebSockets ...
method = methods.First(m =>
m.IsGenericMethod &&
m.Name == "UseGraphQLWebSockets" &&
m.GetGenericArguments().Length == 1 &&
m.GetParameters().Length == 0
);
genericMethod = method.MakeGenericMethod(r.GraphSchema);
genericMethod.Invoke(null, null);
//
Log($"Register GraphQL Middleware for Entity {r.Entity} Successfully ...");
}
catch (Exception ex)
{
Log($"Registration GraphQL Middleware for Entity {r.Entity} failed due {ex.Message} ...");
}
}
}
});
}
}
}
}
//
#region Private ...
/// <summary>
/// a LogTag for xDataService ...
/// </summary>
private static string XLogTag = "xDataService";
/// <summary>
/// print a log in Console ...
/// </summary>
/// <param name="message"></param>
private static void Log(string message)
{
Console.WriteLine($"{XLogTag} => {message}");
}
/// <summary>
/// Do Seeding Initialization Data on DbContext
/// </summary>
/// <param name="app"></param>
private static void SeedData(
this IApplicationBuilder app
)
{
//
using (var scope = app.ApplicationServices.CreateScope())
{
//
var dbSeeder = scope.ServiceProvider.GetService<IXDbSeeder>();
Console.WriteLine($"XDataService: dbSeeder retrieved from DI is => {!dbSeeder.IsNull()}");
//
if (!dbSeeder.IsNull())
{
try
{
//
dbSeeder.Seed()
.GetAwaiter()
.GetResult();
}
catch (Exception ex)
{
//
Console.WriteLine(" ");
Console.WriteLine($"XDataService: Seeding Error: {ex.Message}");
XException.InvalidConfiguration.Throw();
}
}
}
}
#endregion
}
}