435 lines
15 KiB
C#
435 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
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.Models;
|
|
using xDataService.Providers;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xDataService.DI
|
|
{
|
|
public static partial class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Retrive XDataService Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XDataServiceConfiguration GetXDataServiceConfiguration(
|
|
this IConfiguration source
|
|
)
|
|
{
|
|
//
|
|
var xDataServiceConfigSection = source
|
|
.GetSection(ConfigurationNodeNames.DATA_SERVICE_NODE);
|
|
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
|
|
|
|
//
|
|
// Reading Seeders ...
|
|
if (!result.IsNull() &&
|
|
result.Databases.HasChild())
|
|
{
|
|
//
|
|
result
|
|
.Databases
|
|
.ToList()
|
|
.ForEach(db =>
|
|
{
|
|
//
|
|
var seedItemsSectionName = $"{ConfigurationNodeNames.DATA_SERVICE_NODE}:{nameof(XDataServiceConfiguration.Databases)}:{db.Key}:{nameof(XDataBaseConfiguration.SeedItems)}";
|
|
var section = source.GetSection(seedItemsSectionName);
|
|
var sectionJson = source.GetSectionAsJson(seedItemsSectionName);
|
|
var sectionDict = sectionJson.FromJSON<Dictionary<string, List<object>>>();
|
|
if (!sectionDict.IsNull() &&
|
|
sectionDict.Values.HasChild())
|
|
{
|
|
//
|
|
sectionDict
|
|
.Keys
|
|
.ToList()
|
|
.ForEach(entity =>
|
|
{
|
|
//
|
|
// Setting Values to Result ...
|
|
result.Databases[db.Key].SeedItems[entity] = sectionDict[entity];
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
//
|
|
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 not provided ...");
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Register Handler Service ...
|
|
source.AddSingleton<XEntityRegisterarHandlerService>();
|
|
|
|
//
|
|
// 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,
|
|
lifeTime
|
|
]
|
|
);
|
|
|
|
//
|
|
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 =>
|
|
{
|
|
//
|
|
source.AddXRepository(
|
|
descriptor: r,
|
|
lifeTime: lifeTime
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
public static void AddXRepository(
|
|
this IServiceCollection source,
|
|
XRepositoryDescriptor descriptor,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
// Preparing Runtime Types ...
|
|
Type[] runtimeTypes = descriptor.GetType().GenericTypeArguments;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
typeof(XDataServiceHelper).InvokeGenericMethod(
|
|
methodName: "AddXRepository",
|
|
runtimeTypes: runtimeTypes,
|
|
args: [
|
|
source,
|
|
descriptor,
|
|
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,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!source.IsNull() &&
|
|
descriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
//
|
|
Log("Invalid Database Configuration ...");
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Repositories Exists ...
|
|
isValid = descriptor.HasRepositories();
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Loop through Repositories ...
|
|
descriptor.Repositories
|
|
.ToList()
|
|
.ForEach(r =>
|
|
{
|
|
//
|
|
source.UseXRepository(
|
|
descriptor: r,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use a Repository Middlewares by Providing it's Descriptor ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="descriptor"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXRepository(
|
|
this IApplicationBuilder source,
|
|
XRepositoryDescriptor descriptor,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
Log($"Start Using Repository of: {descriptor.Entity}");
|
|
|
|
//
|
|
var withPlayground = false;
|
|
if (isDevelopmentEnvironment)
|
|
{
|
|
withPlayground = true;
|
|
}
|
|
|
|
//
|
|
// Create an Scope for Services Acces ...
|
|
using (var scope = source.ApplicationServices.CreateScope())
|
|
{
|
|
//
|
|
// Inject XDataServiceConfiguration ForMake Sure DataService Registration ...
|
|
var dataServiceConfiguration = scope.ServiceProvider.GetService<XDataServiceConfiguration>();
|
|
var isValid = !dataServiceConfiguration.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Check Seeder Exists ...
|
|
// Execute Seeding Data Task if Exists ...
|
|
isValid = descriptor.HasSeeder();
|
|
if (isValid)
|
|
{
|
|
//
|
|
var seeder = (dynamic)scope.ServiceProvider.GetService(descriptor.SeederService);
|
|
isValid = seeder != null;
|
|
if (isValid)
|
|
{
|
|
//
|
|
Log($"Start Seeding {descriptor.Entity} ...");
|
|
|
|
//
|
|
// Seeding ...
|
|
seeder
|
|
.Seed()
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check GraphQL Support ...
|
|
isValid = descriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Use WebSockets ...
|
|
source.UseWebSockets();
|
|
|
|
//
|
|
// Inject GraphQL Type Helper ...
|
|
var helper = (dynamic)scope.ServiceProvider.GetService(descriptor.GraphTypeHelperService);
|
|
isValid = helper != null;
|
|
if (isValid)
|
|
{
|
|
//
|
|
var graphPath = $"{helper.GetGraphQLPath()}";
|
|
var graphBasePath = $"{dataServiceConfiguration.GraphQLBasePath}";
|
|
typeof(XDataServiceHelper).InvokeGenericMethod(
|
|
methodName: "UseXGraphQL",
|
|
runtimeTypes: [
|
|
descriptor.Entity,
|
|
descriptor.Key,
|
|
descriptor.GraphType,
|
|
descriptor.GraphTypeKey,
|
|
descriptor.GraphQuery,
|
|
descriptor.GraphTypeHelperService,
|
|
descriptor.GraphTypeHelperImplementation,
|
|
descriptor.GraphSchema
|
|
],
|
|
args: [
|
|
source,
|
|
graphBasePath,
|
|
graphPath,
|
|
withPlayground
|
|
]
|
|
);
|
|
|
|
//
|
|
Log($"Register GraphQL: {graphPath}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
#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}");
|
|
}
|
|
#endregion
|
|
}
|
|
} |