101581 lines
3.1 MiB
Plaintext
101581 lines
3.1 MiB
Plaintext
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiConversationEntityConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiConversationEntityConfiguration : XBaseEntityTypeConfiguration<XAiConversation, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XAiConversation> builder)
|
|
{
|
|
builder.ToTable(XAiModelsConstants.XAiConversationTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiConversationMappingAction.cs
|
|
|
|
using System;
|
|
using AutoMapper;
|
|
using xAiModels.Interfaces;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xIdentityService.Extensions;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiConversationMappingAction : IMappingAction<XAiConversation, XAiConversationDto>
|
|
{
|
|
private readonly IXIdentityProvider identityProvider;
|
|
private readonly IXAiProjectTitleResourceProvider projectTitleResourceProvider;
|
|
private readonly IXAiConversationTitleResourceProvider conversationTitleResourceProvider;
|
|
private readonly IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider;
|
|
|
|
public XAiConversationMappingAction(
|
|
IXIdentityProvider identityProvider,
|
|
IXAiProjectTitleResourceProvider projectTitleResourceProvider,
|
|
IXAiConversationTitleResourceProvider conversationTitleResourceProvider,
|
|
IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider
|
|
)
|
|
{
|
|
this.identityProvider = identityProvider;
|
|
this.projectTitleResourceProvider = projectTitleResourceProvider;
|
|
this.conversationTitleResourceProvider = conversationTitleResourceProvider;
|
|
this.projectDescriptionResourceProvider = projectDescriptionResourceProvider;
|
|
}
|
|
|
|
public void Process(
|
|
XAiConversation source,
|
|
XAiConversationDto destination,
|
|
ResolutionContext context
|
|
)
|
|
{
|
|
//
|
|
// Retrieve Owner ...
|
|
var device = identityProvider.GetDevice();
|
|
var ownerUserInfo = identityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: source.OwnerId
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
var owner = ownerUserInfo.ToXPersonDto();
|
|
|
|
//
|
|
// Setting Owner ...
|
|
destination.Owner = owner;
|
|
|
|
// Retrieve Project Info ...
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiMessageEntityConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiMessageEntityConfiguration : XBaseEntityTypeConfiguration<XAiMessage, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XAiMessage> builder)
|
|
{
|
|
builder.ToTable(XAiModelsConstants.XAiMessageTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiMessageMappingAction.cs
|
|
|
|
using System;
|
|
using AutoMapper;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xIdentityService.Extensions;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiMessageMappingAction : IMappingAction<XAiMessage, XAiMessageDto>
|
|
{
|
|
private readonly IXIdentityProvider identityProvider;
|
|
|
|
public XAiMessageMappingAction(
|
|
IXIdentityProvider identityProvider
|
|
)
|
|
{
|
|
this.identityProvider = identityProvider;
|
|
}
|
|
|
|
public void Process(
|
|
XAiMessage source,
|
|
XAiMessageDto destination,
|
|
ResolutionContext context
|
|
)
|
|
{
|
|
//
|
|
// Retrieve Owner ...
|
|
var device = identityProvider.GetDevice();
|
|
var ownerUserInfo = identityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: source.OwnerId
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
var owner = ownerUserInfo.ToXPersonDto();
|
|
|
|
//
|
|
// Setting Owner ...
|
|
destination.Owner = owner;
|
|
|
|
//
|
|
// Retrieve Owner ...
|
|
// Retrieve Conversation ...
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiProjectEntityConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiProjectEntityConfiguration : XBaseEntityTypeConfiguration<XAiProject, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XAiProject> builder)
|
|
{
|
|
builder.ToTable(XAiModelsConstants.XAiProjectTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\Entities\XAiProjectMappingAction.cs
|
|
|
|
using System;
|
|
using AutoMapper;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xIdentityService.Extensions;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xAiModels.Configurations.Entities
|
|
{
|
|
public class XAiProjectMappingAction : IMappingAction<XAiProject, XAiProjectDto>
|
|
{
|
|
private readonly IXIdentityProvider identityProvider;
|
|
|
|
public XAiProjectMappingAction(
|
|
IXIdentityProvider identityProvider
|
|
)
|
|
{
|
|
this.identityProvider = identityProvider;
|
|
}
|
|
|
|
public void Process(
|
|
XAiProject source,
|
|
XAiProjectDto destination,
|
|
ResolutionContext context
|
|
)
|
|
{
|
|
//
|
|
// Retrieve Owner ...
|
|
var device = identityProvider.GetDevice();
|
|
var ownerUserInfo = identityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: source.OwnerId
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
var owner = ownerUserInfo.ToXPersonDto();
|
|
|
|
//
|
|
// Setting Owner ...
|
|
destination.Owner = owner;
|
|
|
|
//
|
|
// Retrieve Owner ...
|
|
// Retrieve Title Resources ...
|
|
// Retrieve Description Resources ...
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\XAiApiConfiguration.cs
|
|
|
|
using xAiModels.Constants;
|
|
using xAiModels.Models;
|
|
|
|
namespace xAiModels.Configurations
|
|
{
|
|
public class XAiApiConfiguration
|
|
{
|
|
/// <summary>
|
|
/// Model Providers ...
|
|
/// </summary>
|
|
public XAiModelDescriptor[] Models { get; set; } = [];
|
|
|
|
/// <summary>
|
|
/// Each User must Has a Default Project, this is Title Resource Identifier ...
|
|
/// </summary>
|
|
public string DefaultProjectTitleResource { get; set; } = XAiModelsConstants.DefaultXAiProjectTitleResourceID;
|
|
|
|
/// <summary>
|
|
/// Each User must Has a Default Project, this is Description Resource Identifier ...
|
|
/// </summary>
|
|
public string DefaultProjectDescriptionResource { get; set; } = XAiModelsConstants.DefaultXAiProjectDescriptionResourceID;
|
|
|
|
/// <summary>
|
|
/// Each User must Has a Default Conversation, this is Title Resource Identifier ... ...
|
|
/// </summary>
|
|
public string DefaultConversationTitleResource { get; set; } = XAiModelsConstants.DefaultXAiConversationTitleResourceID;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Configurations\XAiModelMappersProfile.cs
|
|
|
|
using AutoMapper;
|
|
using xAiModels.Configurations.Entities;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
|
|
namespace xAiModels.Configurations
|
|
{
|
|
public class XAiModelMappersProfile : Profile
|
|
{
|
|
public XAiModelMappersProfile()
|
|
{
|
|
//
|
|
// XAiMessage ...
|
|
CreateMap<XAiMessage, XAiMessageDto>()
|
|
.AfterMap<XAiMessageMappingAction>();
|
|
|
|
//
|
|
// XAiProject ...
|
|
CreateMap<XAiProject, XAiProjectDto>()
|
|
.AfterMap<XAiProjectMappingAction>();
|
|
|
|
//
|
|
// XAiConversation ...
|
|
CreateMap<XAiConversation, XAiConversationDto>()
|
|
.AfterMap<XAiConversationMappingAction>();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xAiModels.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames
|
|
{
|
|
public const string AI_API_NODE = "AiApiConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Constants\XAiChatRole.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xAiModels.Constants
|
|
{
|
|
public struct XAiChatRoles
|
|
{
|
|
public const string None = "none";
|
|
public const string User = "user";
|
|
public const string Tool = "tool";
|
|
public const string System = "system";
|
|
public const string Assistant = "assistant";
|
|
}
|
|
|
|
public enum XAiChatRole
|
|
{
|
|
[StringValue(XAiChatRoles.None)]
|
|
None,
|
|
[StringValue(XAiChatRoles.User)]
|
|
User,
|
|
[StringValue(XAiChatRoles.Tool)]
|
|
Tool,
|
|
[StringValue(XAiChatRoles.System)]
|
|
System,
|
|
[StringValue(XAiChatRoles.Assistant)]
|
|
Assistant,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Constants\XAiModelProviderType.cs
|
|
|
|
namespace xAiModels.Constants
|
|
{
|
|
/// <summary>
|
|
/// Specifiy Provider Type ...
|
|
/// </summary>
|
|
public enum XAiModelProviderType
|
|
{
|
|
None,
|
|
Ollama,
|
|
DeepSeek,
|
|
HuggingFace
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Constants\XAiModelsConstants.cs
|
|
|
|
namespace xAiModels.Constants
|
|
{
|
|
public struct XAiModelsConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XAiModelsDILogTag = "XAiModels";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XAiMessageTable = "AiMessages";
|
|
public const string XAiProjectTable = "AiProjects";
|
|
public const string XAiConversationTable = "AiConversations";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XAiMessageSingleName = "aiMessage";
|
|
public const string XAiProjectSingleName = "aiProject";
|
|
public const string XAiConversationSignleName = "aiConversation";
|
|
|
|
public const string XAiMessageCollectionName = "aiMessages";
|
|
public const string XAiProjectCollectionName = "AiProjectsa";
|
|
public const string XAiConversationCollectionName = "aiConversations";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XAiMessageDtoHub = "aiMessageDto";
|
|
public const string XAiMessageEntityHub = "aiMessageEntity";
|
|
|
|
public const string XAiProjectDtoHub = "aiProjectDto";
|
|
public const string XAiProjectEntityHub = "aiProjectEntity";
|
|
|
|
public const string XAiConversationDtoHub = "aiConversationDto";
|
|
public const string XAiConversationEntityHub = "aiConversationEntity";
|
|
|
|
//
|
|
// Resource Provider Identifiers ...
|
|
public const string XAiProjectTitleIdentifier = "AiPrjT";
|
|
public const string XAiProjectDescriptionIdentifier = "AiPrjD";
|
|
public const string XAiConversationTitleIdentifier = "AiCnvrT";
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXAiMessageEFRepositoryDescriptor = "GetXAiMessageEFRepositoryDescriptor";
|
|
public const string GetXAiProjectEFRepositoryDescriptor = "GetXAiProjectEFRepositoryDescriptor";
|
|
public const string GetXAiConversationEFRepositoryDescriptor = "GetXAiConversationEFRepositoryDescriptor";
|
|
|
|
//
|
|
public const string DefaultXAiProjectTitleResourceID = "XAiPrjT";
|
|
public const string DefaultXAiConversationTitleResourceID = "XAiCnvT";
|
|
public const string DefaultXAiProjectDescriptionResourceID = "XAiPrjD";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xAiModels.Providers.Dtos;
|
|
using xAiModels.Providers.Entities;
|
|
using xCommons.Extensions;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xPushService.Helpers;
|
|
using xPushService.DI;
|
|
using xDataService.DI;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Helpers;
|
|
using xCommons.Helpers;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Interfaces;
|
|
using xAiModels.Providers;
|
|
using xAiModels.Constants;
|
|
|
|
namespace xAiModels.DI
|
|
{
|
|
/// <summary>
|
|
/// Service Registration Extensions Classes ...
|
|
/// </summary>
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXAiDataService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddAiDataService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXAiDataService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddAiDataService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XSubCategoryService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXAiDataService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
// XAiMessage ...
|
|
pushHelper.AddHub<XAiMessageDtoHub>(XAiModelsConstants.XAiMessageDtoHub);
|
|
pushHelper.AddHub<XAiMessageEntityHub>(XAiModelsConstants.XAiMessageEntityHub);
|
|
|
|
//
|
|
// XAiProject ...
|
|
pushHelper.AddHub<XAiProjectDtoHub>(XAiModelsConstants.XAiProjectDtoHub);
|
|
pushHelper.AddHub<XAiProjectEntityHub>(XAiModelsConstants.XAiProjectEntityHub);
|
|
|
|
//
|
|
// XAiConversation ...
|
|
pushHelper.AddHub<XAiConversationDtoHub>(XAiModelsConstants.XAiConversationDtoHub);
|
|
pushHelper.AddHub<XAiConversationEntityHub>(XAiModelsConstants.XAiConversationEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XAiConversation Repository Descriptor ...
|
|
if (!aiConversationDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: aiConversationDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Using XAiMessage Repository Descriptor ...
|
|
if (!aiMessageDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: aiMessageDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Using XAiProject Repository Descriptor ...
|
|
if (!aiProjectDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: aiProjectDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Create an Scope for Services Acces ...
|
|
// Handle Seeding Category/SubCategory Resources ...
|
|
// TODO: Enable Seeding if Required ...
|
|
// using (var scope = app.ApplicationServices.CreateScope())
|
|
// {
|
|
// //
|
|
// // Retrieve Configuratuions ...
|
|
// var aiMessageProvider = scope.ServiceProvider.GetService<IXAiMessageServiceProvider>();
|
|
// var aiProjectProvider = scope.ServiceProvider.GetService<IXAiProjectServiceProvider>();
|
|
// var aiConversationProvider = scope.ServiceProvider.GetService<IXAiConversationServiceProvider>();
|
|
// var configuration = scope.ServiceProvider.GetService<XAiDataServiceServiceConfiguration>();
|
|
// if (!configuration.IsNullOrDefault() &&
|
|
// !categoryProvider.IsNullOrDefault() &&
|
|
// !subaiConversationDescriptor.IsNullOrDefault()
|
|
// )
|
|
// {
|
|
// //
|
|
// // Logging ...
|
|
// Log("Start Seeding ...");
|
|
|
|
// //
|
|
// // Count Data in Category ...
|
|
// var hasCategory = (categoryProvider.Count().GetAwaiter().GetResult()) > 0;
|
|
// var hasSubCategory = (subCategoryProvider.Count().GetAwaiter().GetResult()) > 0;
|
|
|
|
// //
|
|
// // Seed Category Resources ...
|
|
// var canSeed =
|
|
// !hasCategory &&
|
|
// configuration.Categories.HasChild();
|
|
// if (canSeed)
|
|
// {
|
|
// //
|
|
// // Loop through Provided items ...
|
|
// foreach (var cat in configuration.Categories)
|
|
// {
|
|
// //
|
|
// try
|
|
// {
|
|
// //
|
|
// Log($"Start Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} ...");
|
|
|
|
// //
|
|
// categoryProvider.Refresh(
|
|
// resource: cat,
|
|
// userInfo: null,
|
|
// connectionId: null,
|
|
// cancellationToken: default
|
|
// )
|
|
// .GetAwaiter()
|
|
// .GetResult();
|
|
|
|
// //
|
|
// Log($"Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} Finished Successfully ...");
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// Log($"Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} Failed due: {ex.Message} ...");
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// // Seed SubCategory Resources ...
|
|
// canSeed =
|
|
// !hasSubCategory &&
|
|
// configuration.SubCategories.HasChild();
|
|
// if (canSeed)
|
|
// {
|
|
// //
|
|
// // Loop through Provided items ...
|
|
// foreach (var subcat in configuration.SubCategories)
|
|
// {
|
|
// //
|
|
// try
|
|
// {
|
|
// //
|
|
// Log($"Start Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} ...");
|
|
|
|
// //
|
|
// subCategoryProvider.Refresh(
|
|
// userInfo: null,
|
|
// resource: subcat,
|
|
// connectionId: null,
|
|
// cancellationToken: default
|
|
// )
|
|
// .GetAwaiter()
|
|
// .GetResult();
|
|
|
|
// //
|
|
// Log($"Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} Finished Successfully ...");
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// Log($"Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} Failed due: {ex.Message} ...");
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// Log("Finish Seeding ...");
|
|
// }
|
|
// }
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor aiMessageDescriptor = null;
|
|
private static XRepositoryDescriptor aiProjectDescriptor = null;
|
|
private static XRepositoryDescriptor aiConversationDescriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XAiModelsConstants.XAiModelsDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddAiDataService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch (repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
// XAiMessage ...
|
|
aiMessageDescriptor = typeof(XAiModelsHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XAiModelsConstants.GetXAiMessageEFRepositoryDescriptor
|
|
);
|
|
|
|
//
|
|
// XAiProject ...
|
|
aiProjectDescriptor = typeof(XAiModelsHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XAiModelsConstants.GetXAiProjectEFRepositoryDescriptor
|
|
);
|
|
|
|
//
|
|
// XAiConversation ...
|
|
aiConversationDescriptor = typeof(XAiModelsHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XAiModelsConstants.GetXAiConversationEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
//
|
|
// XAiMessage ...
|
|
aiMessageDescriptor = XAiModelsHelper.GetXAiMessageMongoRepositoryDescriptor();
|
|
|
|
//
|
|
// XAiProject ...
|
|
aiProjectDescriptor = XAiModelsHelper.GetXAiProjectMongoRepositoryDescriptor();
|
|
|
|
//
|
|
// XAiConversation ...
|
|
aiConversationDescriptor = XAiModelsHelper.GetXAiConversationMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
//
|
|
// XAiMessage ...
|
|
aiMessageDescriptor = XAiModelsHelper.GetXAiMessageInMemoryRepositoryDescriptor();
|
|
|
|
//
|
|
// XAiProject ...
|
|
aiProjectDescriptor = XAiModelsHelper.GetXAiProjectInMemoryRepositoryDescriptor();
|
|
|
|
//
|
|
// XAiConversation ...
|
|
aiConversationDescriptor = XAiModelsHelper.GetXAiConversationInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
#region Register Repository Descriptor ...
|
|
//
|
|
// XAiMessage ...
|
|
if (!aiMessageDescriptor.IsNull())
|
|
{
|
|
//
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: aiMessageDescriptor
|
|
);
|
|
}
|
|
|
|
//
|
|
// XAiProject ...
|
|
if (!aiProjectDescriptor.IsNull())
|
|
{
|
|
//
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: aiProjectDescriptor
|
|
);
|
|
}
|
|
|
|
//
|
|
// XAiConversation ...
|
|
if (!aiConversationDescriptor.IsNull())
|
|
{
|
|
//
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: aiConversationDescriptor
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Register Services ...
|
|
//
|
|
#region AiMessage ...
|
|
//
|
|
// Models ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiMessageServiceProvider), typeof(XAiMessageServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiMessageRepositoryService), typeof(XAiMessageRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiMessageRepositoryProvider), typeof(XAiMessageRepositoryProvider), lifeTime)
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region AiProject ...
|
|
//
|
|
// Models ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiProjectServiceProvider), typeof(XAiProjectServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiProjectRepositoryService), typeof(XAiProjectRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiProjectRepositoryProvider), typeof(XAiProjectRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Resource Providers ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiProjectTitleResourceProvider), typeof(XAiProjectTitleResourceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiProjectDescriptionResourceProvider), typeof(XAiProjectDescriptionResourceProvider), lifeTime)
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region AiConversation ...
|
|
//
|
|
// Models ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiConversationServiceProvider), typeof(XAiConversationServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiConversationRepositoryService), typeof(XAiConversationRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiConversationRepositoryProvider), typeof(XAiConversationRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Resource Providers ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXAiConversationTitleResourceProvider), typeof(XAiConversationTitleResourceProvider), lifeTime)
|
|
);
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Extensions\ChatResponseExtensions.cs
|
|
|
|
using Microsoft.Extensions.AI;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiModels.Extensions
|
|
{
|
|
public static class ChatResponseExtensions
|
|
{
|
|
/// <summary>
|
|
/// Validate a Chat Response ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this ChatResponse source)
|
|
{
|
|
//
|
|
var result =
|
|
source is not null &&
|
|
!source.IsNullOrDefault() &&
|
|
!string.IsNullOrWhiteSpace(source.Text) &&
|
|
source.FinishReason == ChatFinishReason.Stop;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Extensions\ChatRoleExtensions.cs
|
|
|
|
using Microsoft.Extensions.AI;
|
|
using xAiModels.Constants;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiModels.Extensions
|
|
{
|
|
/// <summary>
|
|
/// Extensions for ChatRole ...
|
|
/// </summary>
|
|
public static class ChatRoleExtensions
|
|
{
|
|
/// <summary>
|
|
/// Normalize an String to Propper Chat Role Value ...
|
|
/// <see cref="XAiChatRoles"/>>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetChatRoleTitle(this string source)
|
|
{
|
|
//
|
|
var result = XAiChatRoles.None;
|
|
|
|
//
|
|
if (source.ToNormalString() == XAiChatRoles.None.ToNormalString())
|
|
{
|
|
result = XAiChatRoles.None;
|
|
}
|
|
else if (source.ToNormalString() == XAiChatRoles.User.ToNormalString())
|
|
{
|
|
result = XAiChatRoles.User;
|
|
}
|
|
else if (source.ToNormalString() == XAiChatRoles.Tool.ToNormalString())
|
|
{
|
|
result = XAiChatRoles.Tool;
|
|
}
|
|
else if (source.ToNormalString() == XAiChatRoles.System.ToNormalString())
|
|
{
|
|
result = XAiChatRoles.System;
|
|
}
|
|
else if (source.ToNormalString() == XAiChatRoles.Assistant.ToNormalString())
|
|
{
|
|
result = XAiChatRoles.Assistant;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Chat Role Title from Chat Role Class ...
|
|
/// <see cref="XAiChatRoles"/>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetRole(this ChatRole source)
|
|
{
|
|
//
|
|
var result = source.Value
|
|
.GetChatRoleTitle();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Chat Role Class Based on role Title ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static ChatRole ToChatRole(this string source)
|
|
{
|
|
//
|
|
var role = source.GetChatRoleTitle();
|
|
ChatRole result = new ChatRole(role);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Chat Role Class Based on role Title ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static ChatRole ToChatRole(this XAiChatRole source)
|
|
{
|
|
//
|
|
var role = source.GetStringValue();
|
|
ChatRole result = new ChatRole(role);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract Chat Role Enum from Chat Role ...
|
|
/// <see cref="ChatRole"/>
|
|
/// <see cref="XAiChatRole"/>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XAiChatRole ToChatRole(this ChatRole source)
|
|
{
|
|
//
|
|
var role = source
|
|
.GetRole()
|
|
.GetChatRoleTitle();
|
|
|
|
//
|
|
XAiChatRole result = XAiChatRole.User;
|
|
|
|
//
|
|
if (role == XAiChatRoles.User)
|
|
{
|
|
result = XAiChatRole.User;
|
|
}
|
|
else if (role == XAiChatRoles.Tool)
|
|
{
|
|
result = XAiChatRole.Tool;
|
|
}
|
|
else if (role == XAiChatRoles.System)
|
|
{
|
|
result = XAiChatRole.System;
|
|
}
|
|
else if (role == XAiChatRoles.Assistant)
|
|
{
|
|
result = XAiChatRole.Assistant;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate an String as Chat Role ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this string source)
|
|
{
|
|
//
|
|
var result =
|
|
source != XAiChatRoles.None &&
|
|
source.ToNormalString() != XAiChatRoles.None.ToNormalString();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Role ...
|
|
/// <see cref="XAiChatRole"/>>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this XAiChatRole source)
|
|
{
|
|
//
|
|
var result = source != XAiChatRole.None;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Role ...
|
|
/// <see cref="ChatRole"/>>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this ChatRole source)
|
|
{
|
|
//
|
|
var role = source.ToChatRole();
|
|
var result = role.IsValid();
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Extensions\XAiApiConfigurationExtensions.cs
|
|
|
|
using System.Linq;
|
|
using xAiModels.Configurations;
|
|
using xAiModels.Models;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiModels.Extensions
|
|
{
|
|
public static class XAiApiConfigurationExtensions
|
|
{
|
|
/// <summary>
|
|
/// Validate Api Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this XAiApiConfiguration source)
|
|
{
|
|
return
|
|
!source.IsNullOrDefault() &&
|
|
source.Models.HasChild();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Default Model Descriptor ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XAiModelDescriptor GetDefaultModel(this XAiApiConfiguration source)
|
|
{
|
|
//
|
|
XAiModelDescriptor result = null;
|
|
|
|
//
|
|
if (source.IsValid())
|
|
{
|
|
result = source.Models.First();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Helpers\XAiModelsHelper.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Entities;
|
|
using xAiModels.Providers.GraphQL;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Helpers
|
|
{
|
|
public static class XAiModelsHelper
|
|
{
|
|
//
|
|
#region XAiConversation ...
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationEFRepository<TContext>,
|
|
TContext
|
|
> GetXAiConversationEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationEFRepository<TContext>,
|
|
TContext,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
> GetXAiConversationEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XAiConversation, Guid>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationEFRepository<TContext>,
|
|
TContext,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationMongoRepository
|
|
> GetXAiConversationMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationMongoRepository,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
> GetXAiConversationMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiConversation, Guid>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationMongoRepository,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationInMemoryRepository
|
|
> GetXAiConversationInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationInMemoryRepository,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
> GetXAiConversationInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiConversation, Guid>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiConversation,
|
|
Guid,
|
|
IXAiConversationKeyGenerator,
|
|
XAiConversationKeyGenerator,
|
|
IXAiConversationRepositoryEvents,
|
|
XAiConversationRepositoryEvents,
|
|
XAiConversationGraphType,
|
|
GuidGraphType,
|
|
XAiConversationGraphQuery,
|
|
IXAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphQLTypeHelper,
|
|
XAiConversationGraphSchema,
|
|
IXAiConversationRepository,
|
|
XAiConversationInMemoryRepository,
|
|
IXAiConversationSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region XAiMessage ...
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageEFRepository<TContext>,
|
|
TContext
|
|
> GetXAiMessageEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageEFRepository<TContext>,
|
|
TContext,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
> GetXAiMessageEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XAiMessage, Guid>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageEFRepository<TContext>,
|
|
TContext,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageMongoRepository
|
|
> GetXAiMessageMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageMongoRepository,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
> GetXAiMessageMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiMessage, Guid>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageMongoRepository,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageInMemoryRepository
|
|
> GetXAiMessageInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageInMemoryRepository,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
> GetXAiMessageInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiMessage, Guid>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiMessage,
|
|
Guid,
|
|
IXAiMessageKeyGenerator,
|
|
XAiMessageKeyGenerator,
|
|
IXAiMessageRepositoryEvents,
|
|
XAiMessageRepositoryEvents,
|
|
XAiMessageGraphType,
|
|
GuidGraphType,
|
|
XAiMessageGraphQuery,
|
|
IXAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphQLTypeHelper,
|
|
XAiMessageGraphSchema,
|
|
IXAiMessageRepository,
|
|
XAiMessageInMemoryRepository,
|
|
IXAiMessageSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region XAiProject ...
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectEFRepository<TContext>,
|
|
TContext
|
|
> GetXAiProjectEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectEFRepository<TContext>,
|
|
TContext,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
> GetXAiProjectEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XAiProject, Guid>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectEFRepository<TContext>,
|
|
TContext,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectMongoRepository
|
|
> GetXAiProjectMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectMongoRepository,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
> GetXAiProjectMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiProject, Guid>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectMongoRepository,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectInMemoryRepository
|
|
> GetXAiProjectInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectInMemoryRepository,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
> GetXAiProjectInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XAiProject, Guid>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XAiProject,
|
|
Guid,
|
|
IXAiProjectKeyGenerator,
|
|
XAiProjectKeyGenerator,
|
|
IXAiProjectRepositoryEvents,
|
|
XAiProjectRepositoryEvents,
|
|
XAiProjectGraphType,
|
|
GuidGraphType,
|
|
XAiProjectGraphQuery,
|
|
IXAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphQLTypeHelper,
|
|
XAiProjectGraphSchema,
|
|
IXAiProjectRepository,
|
|
XAiProjectInMemoryRepository,
|
|
IXAiProjectSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiConversationDtoHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiConversationDtoHub : IXBaseDtoHub<XAiConversation, XAiConversationDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiConversationRepositoryService.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiConversationRepositoryService : IXBaseRepositoryService<XAiConversation, XAiConversationDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiConversationServiceProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiConversationServiceProvider : IXBaseDtoProvider<XAiConversation, XAiConversationDto, Guid, XAiConversationDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiMessageDtoHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiMessageDtoHub : IXBaseDtoHub<XAiMessage, XAiMessageDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiMessageRepositoryService.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiMessageRepositoryService : IXBaseRepositoryService<XAiMessage, XAiMessageDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiMessageServiceProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiMessageServiceProvider : IXBaseDtoProvider<XAiMessage, XAiMessageDto, Guid, XAiMessageDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiProjectDtoHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiProjectDtoHub : IXBaseDtoHub<XAiProject, XAiProjectDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiProjectRepositoryService.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiProjectRepositoryService : IXBaseRepositoryService<XAiProject, XAiProjectDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Dtos\IXAiProjectServiceProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Dtos
|
|
{
|
|
public interface IXAiProjectServiceProvider : IXBaseDtoProvider<XAiProject, XAiProjectDto, Guid, XAiProjectDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationEntityHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationEntityHub : IXBaseEntityHub<XAiConversation, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XAiConversation, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationKeyGenerator.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationKeyGenerator : IXKeyGenerator<XAiConversation, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationRepository : IXBaseRepository<XAiConversation, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationRepositoryEvents.cs
|
|
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationRepositoryEvents : IXBaseRepositoryEvents<XAiConversation>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationRepositoryProvider : IXBaseEntityProvider<XAiConversation, Guid, XAiConversationEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiConversationSeeder.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiConversationSeeder : IXBaseDbSeeder<XAiConversation, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageEntityHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageEntityHub : IXBaseEntityHub<XAiMessage, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XAiMessage, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageKeyGenerator.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageKeyGenerator : IXKeyGenerator<XAiMessage, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageRepository : IXBaseRepository<XAiMessage, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageRepositoryEvents.cs
|
|
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageRepositoryEvents : IXBaseRepositoryEvents<XAiMessage>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageRepositoryProvider : IXBaseEntityProvider<XAiMessage, Guid, XAiMessageEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiMessageSeeder.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiMessageSeeder : IXBaseDbSeeder<XAiMessage, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectEntityHub.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectEntityHub : IXBaseEntityHub<XAiProject, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XAiProject, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectKeyGenerator.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectKeyGenerator : IXKeyGenerator<XAiProject, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectRepository : IXBaseRepository<XAiProject, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectRepositoryEvents.cs
|
|
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectRepositoryEvents : IXBaseRepositoryEvents<XAiProject>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xAiModels.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectRepositoryProvider : IXBaseEntityProvider<XAiProject, Guid, XAiProjectEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\Entities\IXAiProjectSeeder.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces.Entities
|
|
{
|
|
public interface IXAiProjectSeeder : IXBaseDbSeeder<XAiProject, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\IXAiConversationTitleResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces
|
|
{
|
|
public interface IXAiConversationTitleResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\IXAiDataProvider.cs
|
|
|
|
namespace xAiModels.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// All Data Manipulation Requirements ...
|
|
/// </summary>
|
|
public interface IXAiDataProvider
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\IXAiProjectDescriptionResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces
|
|
{
|
|
public interface IXAiProjectDescriptionResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Interfaces\IXAiProjectTitleResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xAiModels.Interfaces
|
|
{
|
|
public interface IXAiProjectTitleResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Dtos\XAiConversationDto.cs
|
|
|
|
using System;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xAiModels.Models.Dtos
|
|
{
|
|
/// <summary>
|
|
/// Conversation Describe ...
|
|
/// </summary>
|
|
public class XAiConversationDto : XBaseGuidIDEntityDto
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Owner Info ...
|
|
/// </summary>
|
|
public virtual XPersonDto Owner { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Conversation Title Resource ID ...
|
|
/// </summary>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// All Exists Title Locale Resources ...
|
|
/// </summary>
|
|
public virtual XLocaleResourceDto[] TitleLocales { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Project ID ...
|
|
/// </summary>
|
|
public Guid ProjectId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Project Title Resource ID ...
|
|
/// </summary>
|
|
public virtual string ProjectTitle { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Project Description Resource ID ...
|
|
/// </summary>
|
|
public virtual string ProjectDescription { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Project Title Locale Resources ...
|
|
/// </summary>
|
|
public virtual XLocaleResourceDto[] ProjectTitleLocales { get; set; }
|
|
|
|
/// <summary>
|
|
/// Project Description Locale Resources ...
|
|
/// </summary>
|
|
public virtual XLocaleResourceDto[] ProjectDescriptionLocales { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Dtos\XAiMessageDto.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xAiModels.Constants;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xAiModels.Models.Dtos
|
|
{
|
|
public class XAiMessageDto : XBaseGuidIDEntityDto
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Owner Info ...
|
|
/// </summary>
|
|
public virtual XPersonDto Owner { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Message of Chat ...
|
|
/// </summary>
|
|
public string Content { get; set; }
|
|
|
|
/// <summary>
|
|
/// Role of Message ...
|
|
/// </summary>
|
|
public XAiChatRole Role { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Conversation Id ...
|
|
/// </summary>
|
|
public Guid ConversationId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Conversation Info ...
|
|
/// </summary>
|
|
public virtual XAiConversationDto Conversation { get; set; } = null;
|
|
|
|
//
|
|
#region Meta Data Property ...
|
|
private string _metadata;
|
|
|
|
/// <summary>
|
|
/// Meta Data of Message ...
|
|
/// </summary>
|
|
public IDictionary<string, object> Metadata { get; private set; } = null;
|
|
|
|
/// <summary>
|
|
/// Meta Data of MEssage in Json ...
|
|
/// </summary>
|
|
public string MeatDatas
|
|
{
|
|
//
|
|
get => _metadata;
|
|
|
|
//
|
|
set
|
|
{
|
|
//
|
|
// Converts Json String to Dictionary ...
|
|
if (!value.IsNullOrEmpty())
|
|
{
|
|
Metadata = value.FromJSON<IDictionary<string, object>>();
|
|
}
|
|
|
|
//
|
|
_metadata = value;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Dtos\XAiProjectDto.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xAiModels.Models.Dtos
|
|
{
|
|
/// <summary>
|
|
/// Describe a Project ...
|
|
/// </summary>
|
|
public class XAiProjectDto : XBaseGuidIDEntityDto
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Owner Info ...
|
|
/// </summary>
|
|
public virtual XPersonDto Owner { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Title of Project ...
|
|
/// </summary>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of Project ...
|
|
/// </summary>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// a Prompt for Project Start ...
|
|
/// </summary>
|
|
public string Prompt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Conversations ...
|
|
/// </summary>
|
|
public virtual IList<XAiConversationDto> Conversations { get; set; } = [];
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Entities\XAiConversation.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
|
|
namespace xAiModels.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Conversation Describe ...
|
|
/// </summary>
|
|
public class XAiConversation : XBaseGuidIDEntity
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Title of Conversation ...
|
|
/// </summary>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Project ID ...
|
|
/// </summary>
|
|
[Required]
|
|
public Guid ProjectId { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Entities\XAiMessage.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xAiModels.Constants;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
|
|
namespace xAiModels.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Message Model of Ai ...
|
|
/// </summary>
|
|
public class XAiMessage : XBaseGuidIDEntity
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Message of Chat ...
|
|
/// </summary>
|
|
[Required]
|
|
public string Content { get; set; }
|
|
|
|
/// <summary>
|
|
/// Role of Message ...
|
|
/// </summary>
|
|
public XAiChatRole Role { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Conversation Id ...
|
|
/// </summary>
|
|
[StringLength(255)]
|
|
public Guid ConversationId { get; set; }
|
|
|
|
//
|
|
#region Meta Data Property ...
|
|
private string _metadata;
|
|
|
|
/// <summary>
|
|
/// Meta Data of Message ...
|
|
/// </summary>
|
|
[NotMapped]
|
|
public IDictionary<string, object> Metadata { get; private set; } = null;
|
|
|
|
/// <summary>
|
|
/// Meta Data of MEssage in Json ...
|
|
/// </summary>
|
|
public string MeatDatas
|
|
{
|
|
//
|
|
get => _metadata;
|
|
|
|
//
|
|
set
|
|
{
|
|
//
|
|
// Converts Json String to Dictionary ...
|
|
if (!value.IsNullOrEmpty())
|
|
{
|
|
Metadata = value.FromJSON<IDictionary<string, object>>();
|
|
}
|
|
|
|
//
|
|
_metadata = value;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\Entities\XAiProject.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
|
|
namespace xAiModels.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Describe a Project ...
|
|
/// </summary>
|
|
public class XAiProject : XBaseGuidIDEntity
|
|
{
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Title of Project ...
|
|
/// </summary>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of Project ...
|
|
/// </summary>
|
|
[StringLength(1000)]
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// a Prompt for Project Start ...
|
|
/// </summary>
|
|
public string Prompt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Created Time ...
|
|
/// </summary>
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updated Time ...
|
|
/// </summary>
|
|
public DateTime UpdatedAt { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Models\XAiModelDescriptor.cs
|
|
|
|
using xAiModels.Constants;
|
|
|
|
namespace xAiModels.Models
|
|
{
|
|
/// <summary>
|
|
/// Describe a Provided Model ...
|
|
/// </summary>
|
|
public class XAiModelDescriptor
|
|
{
|
|
/// <summary>
|
|
/// Provider Name ...
|
|
/// </summary>
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// LLM Provider Url ...
|
|
/// </summary>
|
|
public string Url { get; set; }
|
|
|
|
/// <summary>
|
|
/// Model Name ...
|
|
/// </summary>
|
|
public string LLM { get; set; }
|
|
|
|
/// <summary>
|
|
/// Api Key for Connection ...
|
|
/// </summary>
|
|
public string ApiKey { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specified Model Provider Type ...
|
|
/// </summary>
|
|
public XAiModelProviderType Provider { get; set; } = XAiModelProviderType.Ollama;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiConversationDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiConversationDtoHub : XBaseDtoHub<XAiConversation, XAiConversationDto, Guid>, IXAiConversationDtoHub
|
|
{
|
|
public XAiConversationDtoHub(
|
|
ILogger<XAiConversationDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiConversationRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiConversationRepositoryService : XBaseRepositoryService<XAiConversation, XAiConversationDto, Guid>, IXAiConversationRepositoryService
|
|
{
|
|
public XAiConversationRepositoryService(
|
|
IXAiConversationRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiConversationServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiConversationServiceProvider : XBaseDtoProvider<XAiConversation, XAiConversationDto, Guid, XAiConversationDtoHub>, IXAiConversationServiceProvider
|
|
{
|
|
public XAiConversationServiceProvider(
|
|
IHubContext<XAiConversationDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXAiConversationRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiMessageDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiMessageDtoHub : XBaseDtoHub<XAiMessage, XAiMessageDto, Guid>, IXAiMessageDtoHub
|
|
{
|
|
public XAiMessageDtoHub(
|
|
ILogger<XAiMessageDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiMessageRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiMessageRepositoryService : XBaseRepositoryService<XAiMessage, XAiMessageDto, Guid>, IXAiMessageRepositoryService
|
|
{
|
|
public XAiMessageRepositoryService(
|
|
IXAiMessageRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiMessageServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiMessageServiceProvider : XBaseDtoProvider<XAiMessage, XAiMessageDto, Guid, XAiMessageDtoHub>, IXAiMessageServiceProvider
|
|
{
|
|
public XAiMessageServiceProvider(
|
|
IHubContext<XAiMessageDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXAiMessageRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiProjectDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiProjectDtoHub : XBaseDtoHub<XAiProject, XAiProjectDto, Guid>, IXAiProjectDtoHub
|
|
{
|
|
public XAiProjectDtoHub(
|
|
ILogger<XAiProjectDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiProjectRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiProjectRepositoryService : XBaseRepositoryService<XAiProject, XAiProjectDto, Guid>, IXAiProjectRepositoryService
|
|
{
|
|
public XAiProjectRepositoryService(
|
|
IXAiProjectRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Dtos\XAiProjectServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Dtos;
|
|
using xAiModels.Models.Dtos;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Dtos
|
|
{
|
|
public class XAiProjectServiceProvider : XBaseDtoProvider<XAiProject, XAiProjectDto, Guid, XAiProjectDtoHub>, IXAiProjectServiceProvider
|
|
{
|
|
public XAiProjectServiceProvider(
|
|
IHubContext<XAiProjectDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXAiProjectRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationEFRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationEFRepository<TContext> : XBaseEFRepository<XAiConversation, Guid, TContext>, IXAiConversationRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XAiConversationEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXAiConversationKeyGenerator keyGenerator = null,
|
|
IXAiConversationRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationEntityHub : XBaseEntityHub<XAiConversation, Guid>, IXAiConversationEntityHub
|
|
{
|
|
public XAiConversationEntityHub(
|
|
ILogger<XAiConversationEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationInMemoryRepository : XBaseInMemoryRepository<XAiConversation, Guid>, IXAiConversationRepository
|
|
{
|
|
public XAiConversationInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiConversationKeyGenerator keyGenerator = null,
|
|
IXAiConversationRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationKeyGenerator.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationKeyGenerator : XGuidKeyGenerator<XAiConversation>, IXAiConversationKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationMongoRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationMongoRepository : XBaseMongoRepository<XAiConversation, Guid>, IXAiConversationRepository
|
|
{
|
|
public XAiConversationMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXAiConversationKeyGenerator keyGenerator = null,
|
|
IXAiConversationRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationRepositoryEvents.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationRepositoryEvents : XBaseRepositoryEvents<XAiConversation>, IXAiConversationRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiConversationRepositoryProvider : XBaseEntityProvider<XAiConversation, Guid, XAiConversationEntityHub>, IXAiConversationRepositoryProvider
|
|
{
|
|
public XAiConversationRepositoryProvider(
|
|
IHubContext<XAiConversationEntityHub> hub,
|
|
IXAiConversationRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiConversationSeederBase.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public abstract class XAiConversationSeederBase : XBaseDbSeeder<XAiConversation, Guid>, IXAiConversationSeeder
|
|
{
|
|
protected XAiConversationSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXAiConversationRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageEFRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageEFRepository<TContext> : XBaseEFRepository<XAiMessage, Guid, TContext>, IXAiMessageRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XAiMessageEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXAiMessageKeyGenerator keyGenerator = null,
|
|
IXAiMessageRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageEntityHub : XBaseEntityHub<XAiMessage, Guid>, IXAiMessageEntityHub
|
|
{
|
|
public XAiMessageEntityHub(
|
|
ILogger<XAiMessageEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageInMemoryRepository : XBaseInMemoryRepository<XAiMessage, Guid>, IXAiMessageRepository
|
|
{
|
|
public XAiMessageInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiMessageKeyGenerator keyGenerator = null,
|
|
IXAiMessageRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageKeyGenerator.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageKeyGenerator : XGuidKeyGenerator<XAiMessage>, IXAiMessageKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageMongoRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageMongoRepository : XBaseMongoRepository<XAiMessage, Guid>, IXAiMessageRepository
|
|
{
|
|
public XAiMessageMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXAiMessageKeyGenerator keyGenerator = null,
|
|
IXAiMessageRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageRepositoryEvents.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageRepositoryEvents : XBaseRepositoryEvents<XAiMessage>, IXAiMessageRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiMessageRepositoryProvider : XBaseEntityProvider<XAiMessage, Guid, XAiMessageEntityHub>, IXAiMessageRepositoryProvider
|
|
{
|
|
public XAiMessageRepositoryProvider(
|
|
IHubContext<XAiMessageEntityHub> hub,
|
|
IXAiMessageRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiMessageSeederBase.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public abstract class XAiMessageSeederBase : XBaseDbSeeder<XAiMessage, Guid>, IXAiMessageSeeder
|
|
{
|
|
protected XAiMessageSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXAiMessageRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectEFRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectEFRepository<TContext> : XBaseEFRepository<XAiProject, Guid, TContext>, IXAiProjectRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XAiProjectEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXAiProjectKeyGenerator keyGenerator = null,
|
|
IXAiProjectRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectEntityHub : XBaseEntityHub<XAiProject, Guid>, IXAiProjectEntityHub
|
|
{
|
|
public XAiProjectEntityHub(
|
|
ILogger<XAiProjectEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectInMemoryRepository : XBaseInMemoryRepository<XAiProject, Guid>, IXAiProjectRepository
|
|
{
|
|
public XAiProjectInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiProjectKeyGenerator keyGenerator = null,
|
|
IXAiProjectRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectKeyGenerator.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectKeyGenerator : XGuidKeyGenerator<XAiProject>, IXAiProjectKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectMongoRepository.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectMongoRepository : XBaseMongoRepository<XAiProject, Guid>, IXAiProjectRepository
|
|
{
|
|
public XAiProjectMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXAiProjectKeyGenerator keyGenerator = null,
|
|
IXAiProjectRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectRepositoryEvents.cs
|
|
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectRepositoryEvents : XBaseRepositoryEvents<XAiProject>, IXAiProjectRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public class XAiProjectRepositoryProvider : XBaseEntityProvider<XAiProject, Guid, XAiProjectEntityHub>, IXAiProjectRepositoryProvider
|
|
{
|
|
public XAiProjectRepositoryProvider(
|
|
IHubContext<XAiProjectEntityHub> hub,
|
|
IXAiProjectRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\Entities\XAiProjectSeederBase.cs
|
|
|
|
using System;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers.Entities
|
|
{
|
|
public abstract class XAiProjectSeederBase : XBaseDbSeeder<XAiProject, Guid>, IXAiProjectSeeder
|
|
{
|
|
protected XAiProjectSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXAiProjectRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiConversationGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiConversationGraphQLTypeHelper : XBaseGraphQLTypeHelper<XAiConversation, Guid>, IXAiConversationGraphQLTypeHelper
|
|
{
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XAiModelsConstants.XAiConversationCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XAiModelsConstants.XAiConversationSignleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiConversationGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiConversationGraphQuery : XBaseGraphQLQuery<XAiConversation, Guid, XAiConversationGraphType, GuidGraphType>
|
|
{
|
|
public XAiConversationGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiConversationRepository repository,
|
|
IXAiConversationGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiConversationGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiConversationGraphSchema : Schema
|
|
{
|
|
public XAiConversationGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XAiConversationGraphQuery)services.GetService(typeof(XAiConversationGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiConversationGraphType.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiConversationGraphType : XBaseGraphObjectType<XAiConversation, Guid>
|
|
{
|
|
public XAiConversationGraphType() : base()
|
|
{
|
|
Field(x => x.Title);
|
|
Field(x => x.OwnerId);
|
|
Field(x => x.CreatedOn);
|
|
Field(x => x.UpdatedAt);
|
|
Field(x => x.ProjectId);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiMessageGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiMessageGraphQLTypeHelper : XBaseGraphQLTypeHelper<XAiMessage, Guid>, IXAiMessageGraphQLTypeHelper
|
|
{
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XAiModelsConstants.XAiMessageCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XAiModelsConstants.XAiMessageSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiMessageGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiMessageGraphQuery : XBaseGraphQLQuery<XAiMessage, Guid, XAiMessageGraphType, GuidGraphType>
|
|
{
|
|
public XAiMessageGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiMessageRepository repository,
|
|
IXAiMessageGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiMessageGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiMessageGraphSchema : Schema
|
|
{
|
|
public XAiMessageGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XAiMessageGraphQuery)services.GetService(typeof(XAiMessageGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiMessageGraphType.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiMessageGraphType: XBaseGraphObjectType<XAiMessage, Guid>
|
|
{
|
|
public XAiMessageGraphType() : base()
|
|
{
|
|
Field(x => x.Role);
|
|
Field(x => x.OwnerId);
|
|
Field(x => x.Content);
|
|
Field(x => x.Metadata);
|
|
Field(x => x.CreatedOn);
|
|
Field(x => x.UpdatedAt);
|
|
Field(x => x.ConversationId);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiProjectGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiProjectGraphQLTypeHelper : XBaseGraphQLTypeHelper<XAiProject, Guid>, IXAiProjectGraphQLTypeHelper
|
|
{
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XAiModelsConstants.XAiProjectCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XAiModelsConstants.XAiProjectSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiProjectGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiProjectGraphQuery : XBaseGraphQLQuery<XAiProject, Guid, XAiProjectGraphType, GuidGraphType>
|
|
{
|
|
public XAiProjectGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXAiProjectRepository repository,
|
|
IXAiProjectGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiProjectGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiProjectGraphSchema : Schema
|
|
{
|
|
public XAiProjectGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XAiProjectGraphQuery)services.GetService(typeof(XAiProjectGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\GraphQL\XAiProjectGraphType.cs
|
|
|
|
using System;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xAiModels.Providers.GraphQL
|
|
{
|
|
public class XAiProjectGraphType : XBaseGraphObjectType<XAiProject, Guid>
|
|
{
|
|
public XAiProjectGraphType() : base()
|
|
{
|
|
Field(x => x.Title);
|
|
Field(x => x.OwnerId);
|
|
Field(x => x.Prompt);
|
|
Field(x => x.CreatedOn);
|
|
Field(x => x.UpdatedAt);
|
|
Field(x => x.Description);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiConversationEntityRegisterar.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xAiModels.Configurations.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiConversationEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XAiConversationEntityRegisterar()
|
|
: base(nameof(XAiConversationEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XAiConversation, Guid>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XAiConversationEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiConversationTitleResourceProvider.cs
|
|
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiConversationTitleResourceProvider : XBaseItemResourceProvider, IXAiConversationTitleResourceProvider
|
|
{
|
|
public XAiConversationTitleResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XAiModelsConstants.XAiConversationTitleIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiDataProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xAiModels.Interfaces;
|
|
using xAiModels.Interfaces.Entities;
|
|
using xAiModels.Providers.Dtos;
|
|
using xAiModels.Providers.Entities;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
/// <summary>
|
|
/// All Data Manipulation Requirements ...
|
|
/// </summary>
|
|
public class XAiDataProvider : IXAiDataProvider
|
|
{
|
|
private readonly IHubContext<XAiMessageDtoHub> messageDtoHub;
|
|
private readonly IHubContext<XAiProjectDtoHub> projectDtoHub;
|
|
private readonly IXAiMessageRepository messageRepositoryService;
|
|
private readonly IXAiProjectRepository projectRepositoryService;
|
|
private readonly IHubContext<XAiMessageEntityHub> messageEntityHub;
|
|
private readonly IHubContext<XAiProjectEntityHub> projectEntityHub;
|
|
private readonly IXAiConversationRepository conversationRepository;
|
|
private readonly IHubContext<XAiConversationDtoHub> conversationDtoHub;
|
|
private readonly IHubContext<XAiConversationEntityHub> conversationEntityHub;
|
|
private readonly IXAiProjectTitleResourceProvider projectTitleResourceProvider;
|
|
private readonly IXAiConversationTitleResourceProvider conversationTitleResourceProvider;
|
|
private readonly IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider;
|
|
|
|
public XAiDataProvider(
|
|
IHubContext<XAiMessageDtoHub> messageDtoHub,
|
|
IHubContext<XAiProjectDtoHub> projectDtoHub,
|
|
IXAiMessageRepository messageRepositoryService,
|
|
IXAiProjectRepository projectRepositoryService,
|
|
IHubContext<XAiMessageEntityHub> messageEntityHub,
|
|
IHubContext<XAiProjectEntityHub> projectEntityHub,
|
|
IXAiConversationRepository conversationRepository,
|
|
IHubContext<XAiConversationDtoHub> conversationDtoHub,
|
|
IHubContext<XAiConversationEntityHub> conversationEntityHub,
|
|
IXAiProjectTitleResourceProvider projectTitleResourceProvider,
|
|
IXAiConversationTitleResourceProvider conversationTitleResourceProvider,
|
|
IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider
|
|
)
|
|
{
|
|
this.messageDtoHub = messageDtoHub;
|
|
this.projectDtoHub = projectDtoHub;
|
|
this.projectEntityHub = projectEntityHub;
|
|
this.messageEntityHub = messageEntityHub;
|
|
this.conversationDtoHub = conversationDtoHub;
|
|
this.conversationEntityHub = conversationEntityHub;
|
|
this.conversationRepository = conversationRepository;
|
|
this.messageRepositoryService = messageRepositoryService;
|
|
this.projectRepositoryService = projectRepositoryService;
|
|
this.projectTitleResourceProvider = projectTitleResourceProvider;
|
|
this.conversationTitleResourceProvider = conversationTitleResourceProvider;
|
|
this.projectDescriptionResourceProvider = projectDescriptionResourceProvider;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiMessageEntityRegisterar.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xAiModels.Configurations.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiMessageEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XAiMessageEntityRegisterar()
|
|
: base(nameof(XAiMessageEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XAiMessage, Guid>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XAiMessageEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiProjectDescriptionResourceProvider.cs
|
|
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiProjectDescriptionResourceProvider : XBaseItemResourceProvider, IXAiProjectDescriptionResourceProvider
|
|
{
|
|
public XAiProjectDescriptionResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XAiModelsConstants.XAiProjectDescriptionIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiProjectEntityRegisterar.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xAiModels.Configurations.Entities;
|
|
using xAiModels.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiProjectEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XAiProjectEntityRegisterar()
|
|
: base(nameof(XAiProjectEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XAiProject, Guid>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XAiProjectEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiModels\Providers\XAiProjectTitleResourceProvider.cs
|
|
|
|
using xAiModels.Constants;
|
|
using xAiModels.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xAiModels.Providers
|
|
{
|
|
public class XAiProjectTitleResourceProvider : XBaseItemResourceProvider, IXAiProjectTitleResourceProvider
|
|
{
|
|
public XAiProjectTitleResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XAiModelsConstants.XAiProjectTitleIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Configurations\XAIServiceConfiguration.cs
|
|
|
|
namespace xAiService.Configurations
|
|
{
|
|
public partial class XAIServiceConfiguration
|
|
{
|
|
public string Url { get; set; }
|
|
public string XPoweredValue { get; set; }
|
|
public int DefaultClientTimeout { get; set; } = 360;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xAiService.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames
|
|
{
|
|
public const string AI_SERVICE_NODE = "AIServiceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiApiConstants.cs
|
|
|
|
namespace xAiService.Constants
|
|
{
|
|
public struct XAiApiQueryParams
|
|
{
|
|
public const string Prompt = "prompt";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiApiEndpoint.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xAiService.Constants
|
|
{
|
|
public enum XAiApiEndpoint
|
|
{
|
|
[StringValue("AskAI")]
|
|
Ask,
|
|
[StringValue("AskAIStream")]
|
|
Stream,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xAiService.Configurations;
|
|
using xAiService.Constants;
|
|
using xAiService.Extensions;
|
|
using xAiService.Interfaces;
|
|
using xAiService.Services;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xAiService.DI
|
|
{
|
|
public static partial class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Extract AI Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XAIServiceConfiguration GetXAIServiceConfiguration(this IConfiguration source)
|
|
{
|
|
//
|
|
XAIServiceConfiguration result = null;
|
|
|
|
//
|
|
var section = source.GetSection(ConfigurationNodeNames.AI_SERVICE_NODE);
|
|
if (!section.IsNull())
|
|
{
|
|
result = section.Get<XAIServiceConfiguration>();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add AI Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXAIServiceConfiguration(
|
|
this IServiceCollection source,
|
|
XAIServiceConfiguration configuration
|
|
)
|
|
{
|
|
source.AddSingleton<XAIServiceConfiguration>(configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adding XAiService ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXAIService(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var config = configuration.GetXAIServiceConfiguration();
|
|
AddAIService(
|
|
services,
|
|
config,
|
|
lifeTime
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adding XAiService ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXAIService(
|
|
this IServiceCollection services,
|
|
XAIServiceConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
AddAIService(
|
|
services,
|
|
configuration,
|
|
lifeTime
|
|
);
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = "XFileService";
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adding Ai Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddAIService(
|
|
this IServiceCollection services,
|
|
XAIServiceConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Singleton
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("AddAIService failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("AddAIService failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Check Dependencies Exists ...
|
|
var isDependenciesPassed = true;
|
|
if (!isDependenciesPassed)
|
|
{
|
|
//
|
|
Log("AddAIService failed due Dependencies Issues, not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Configurations ...
|
|
var isConfigurationExists =
|
|
!configuration.IsNull() &&
|
|
configuration.IsValid();
|
|
if (!isConfigurationExists)
|
|
{
|
|
//
|
|
Log("AddAIService failed due InValid Service Configuration or not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Register Configurations ...
|
|
services.AddXAIServiceConfiguration(configuration);
|
|
|
|
//
|
|
// Register Services ...
|
|
services.Add(new ServiceDescriptor(typeof(IXAiService), typeof(XAiService), lifeTime));
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Extensions\ConfigurationExtensions.cs
|
|
|
|
using xAiService.Configurations;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiService.Extensions
|
|
{
|
|
public static class ModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Validate XAiServiceConfiguration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this XAIServiceConfiguration source)
|
|
{
|
|
//
|
|
bool result =
|
|
!source.IsNull() &&
|
|
!source.Url.IsNullOrEmpty() &&
|
|
source.Url.IsValidUrl();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Extensions\PromptExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xAiService.Models.Dtos;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiService.Extensions
|
|
{
|
|
public static class PromptExtensions
|
|
{
|
|
/// <summary>
|
|
/// Get Template Params Filled Prompt ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="params"></param>
|
|
/// <returns></returns>
|
|
public static string GetMessage(
|
|
this XPromptDto source,
|
|
IDictionary<string, string> @params = null
|
|
)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault() &&
|
|
!source.Prompt.IsNullOrEmpty()
|
|
)
|
|
{
|
|
result = source.Prompt;
|
|
}
|
|
|
|
//
|
|
// Check Params Conditions ...
|
|
if (!source.Params.IsNullOrDefault() &&
|
|
source.Params.HasChild() &&
|
|
!@params.IsNullOrDefault() &&
|
|
@params.HasChild()
|
|
)
|
|
{
|
|
//
|
|
// Select Params ...
|
|
var existsParams = source.Params
|
|
.Where(p => @params.Any(pr => pr.Key == p.Name))
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
// Replace Selected Params ...
|
|
existsParams
|
|
.ForEach(pk =>
|
|
{
|
|
result = result.Replace(pk.Param, @params[pk.Name]);
|
|
});
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Helpers\XPromptHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using xAiService.Models.Dtos;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiService.Helpers
|
|
{
|
|
public static class XPromptHelper
|
|
{
|
|
/// <summary>
|
|
/// Holds Initialized Prompts ...
|
|
/// </summary>
|
|
private static XPromptsDto prompts;
|
|
|
|
/// <summary>
|
|
/// Initialize Prompt Helper ...
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <exception cref="Exception"></exception>
|
|
/// <exception cref="InvalidDataException"></exception>
|
|
public static void Initialize(string path = "prompts.json")
|
|
{
|
|
//
|
|
// Create full Path and Check File Exists ...
|
|
var fullPath = Path.Combine(AppContext.BaseDirectory, path);
|
|
if (!File.Exists(fullPath))
|
|
{
|
|
throw new Exception($"Prompts Resources not found: {fullPath}");
|
|
}
|
|
|
|
//
|
|
// Read File as Json Text ...
|
|
var json = File.ReadAllText(fullPath);
|
|
var options = new JsonSerializerOptions
|
|
{
|
|
AllowTrailingCommas = true,
|
|
PropertyNameCaseInsensitive = true,
|
|
ReadCommentHandling = JsonCommentHandling.Skip,
|
|
Converters =
|
|
{
|
|
new JsonStringEnumConverter(
|
|
namingPolicy: null,
|
|
allowIntegerValues: false
|
|
)
|
|
}
|
|
};
|
|
|
|
//
|
|
// Serialized Root Object ...
|
|
var root = JsonSerializer.Deserialize<XPromptsDto>(json, options);
|
|
if (!root.IsNullOrDefault())
|
|
{
|
|
prompts = new XPromptsDto { Prompts = root.Prompts };
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Allowed Prompts as Enumerable ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static IEnumerable<XPromptDto> GetPrompts()
|
|
{
|
|
return prompts!.Prompts.AsEnumerable();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Prompt ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
public static XPromptDto GetPrompt(string name)
|
|
{
|
|
//
|
|
return GetPrompts()
|
|
.FirstOrDefault(p => p.Name == name);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Interfaces\IXAiService.cs
|
|
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.AI;
|
|
using xAiService.Configurations;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xAiService.Interfaces
|
|
{
|
|
public interface IXAiService : IXBaseIdentityHttpProvider
|
|
{
|
|
/// <summary>
|
|
/// XAiService Configurations ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
XAIServiceConfiguration Configuration { get; }
|
|
|
|
//
|
|
#region Text Actions ...
|
|
/// <summary>
|
|
/// Generated Response ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public Task<ChatResponse> GetResponseAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Generated Response ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public Task<string> GetTextResponseAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Generate Text Response Stream ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<Stream> GetTextReponseStreamAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Interfaces\IXAiServiceControllerBase.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace xAiService.Interfaces
|
|
{
|
|
public interface IXAiServiceControllerBase
|
|
{
|
|
Task<ActionResult<string>> Ask(
|
|
[FromQuery] string prompt,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult> AskStream(
|
|
[FromQuery] string prompt,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Models\Dtos\XPromptsDto.cs
|
|
|
|
namespace xAiService.Models.Dtos
|
|
{
|
|
/// <summary>
|
|
/// Described Prompts in app ...
|
|
/// </summary>
|
|
public class XPromptsDto
|
|
{
|
|
public XPromptDto[] Prompts { get; set; } = [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Single Prompt Description ...
|
|
/// </summary>
|
|
public class XPromptDto
|
|
{
|
|
/// <summary>
|
|
/// Prompt Name ...
|
|
/// </summary>
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Prompt Template Message ...
|
|
/// </summary>
|
|
public string Prompt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Prompt Description ...
|
|
/// </summary>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// Describe Prompt Params ...
|
|
/// </summary>
|
|
public virtual XPromptParamDto[] Params { get; set; } = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prompt Param used to Fill dynamic Datas to Specified Prompts ...
|
|
/// </summary>
|
|
public class XPromptParamDto
|
|
{
|
|
/// <summary>
|
|
/// Param Name ...
|
|
/// </summary>
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Parma Identifier ...
|
|
/// </summary>
|
|
public string Param { get; set; }
|
|
|
|
/// <summary>
|
|
/// Param Description ...
|
|
/// </summary>
|
|
public string Description { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Services\XAiService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.AI;
|
|
using Microsoft.Extensions.Logging;
|
|
using xAiService.Configurations;
|
|
using xAiService.Constants;
|
|
using xAiService.Interfaces;
|
|
using xCommons.Providers;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Providers;
|
|
|
|
namespace xAiService.Services
|
|
{
|
|
public class XAiService : XBaseIdentityHttpProvider, IXAiService
|
|
{
|
|
/// <summary>
|
|
/// XAiService Configurations ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XAIServiceConfiguration Configuration { get; }
|
|
|
|
public XAiService(
|
|
ILogger<XAiService> logger,
|
|
IXTokenProvider tokenProvider,
|
|
IXIdentityProvider identityProvider,
|
|
XAIServiceConfiguration configuration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
configuration.Url,
|
|
logger,
|
|
configuration.XPoweredValue,
|
|
configuration.DefaultClientTimeout,
|
|
tokenProvider,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
|
|
//
|
|
#region Text Actions ...
|
|
/// <summary>
|
|
/// Generated Response ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public Task<ChatResponse> GetResponseAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generated Response ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetTextResponseAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(prompt);
|
|
|
|
//
|
|
var client = GetRestClient(userInfo);
|
|
var request = GetRestRequet(
|
|
endpoint: XAiApiEndpoint.Ask,
|
|
addXPoweredValue: true,
|
|
queryStrings: new Dictionary<string, string>
|
|
{
|
|
{ XAiApiQueryParams.Prompt, prompt }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<string>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Text Response Stream ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<Stream> GetTextReponseStreamAsync(
|
|
string prompt,
|
|
XUserClaimsInfoDto userInfo,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(prompt)
|
|
.AddNotNull(userInfo)
|
|
.AddNotZero(userInfo.ExpiresAt)
|
|
.AddNotEmpty(userInfo.AccessToken)
|
|
.AddNotEmpty(userInfo.RefreshToken)
|
|
.ValidateGroup();
|
|
|
|
//
|
|
var tokens = ToTokenResponse(userInfo);
|
|
var result = await StreamData(
|
|
tokens: tokens,
|
|
addXPoweredValue: true,
|
|
endpoint: XAiApiEndpoint.Stream,
|
|
cancellationToken: cancellationToken,
|
|
queryStrings: new Dictionary<string, string>
|
|
{
|
|
{ XAiApiQueryParams.Prompt, prompt }
|
|
}
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Configurations\Entities\XCategoryEntityConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Configurations.Entities
|
|
{
|
|
public class XCategoryEntityConfiguration : XBaseEntityTypeConfiguration<XCategory, int>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XCategory> builder)
|
|
{
|
|
builder.ToTable(XCategoryServiceConstants.XCategoryTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Configurations\Entities\XSubCategoryEntityConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Configurations.Entities
|
|
{
|
|
public class XSubCategoryEntityConfiguration : XBaseEntityTypeConfiguration<XSubCategory, int>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XSubCategory> builder)
|
|
{
|
|
builder.ToTable(XCategoryServiceConstants.XSubCategoryTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Configurations\XCategoryServiceConfiguration.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
|
|
namespace xCategoryService.Configurations
|
|
{
|
|
/// <summary>
|
|
/// a Configuration Class for Providing Data to Configure XCategoryService ...
|
|
/// </summary>
|
|
public class XCategoryServiceConfiguration
|
|
{
|
|
/// <summary>
|
|
/// a List of Categories for Seeding ...
|
|
/// </summary>
|
|
public XCategoryResourceDto[] Categories { get; set; } = [];
|
|
|
|
/// <summary>
|
|
/// a List of SubCategories for Seeding ...
|
|
/// </summary>
|
|
public XSubCategoryResourceDto[] SubCategories { get; set; } = [];
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xCategoryService.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames
|
|
{
|
|
public const string CATEGORY_SERVICE_NODE = "CategoryServiceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Constants\XCategoryServiceConstants.cs
|
|
|
|
namespace xCategoryService.Constants
|
|
{
|
|
public struct XCategoryServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XCategoryServiceDILogTag = "XCategoryService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XCategoryTable = "Categories";
|
|
public const string XSubCategoryTable = "SubCategories";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XCategorySingleName = "category";
|
|
public const string XCategoryCollectionName = "categories";
|
|
public const string XSubCategorySingleName = "subCategory";
|
|
public const string XSubCategoryCollectionName = "subCategories";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XCategoryDtoHub = "categoryDto";
|
|
public const string XCategoryEntityHub = "categoryEntity";
|
|
public const string XSubCategoryDtoHub = "subCategoryDto";
|
|
public const string XSubCategoryEntityHub = "subCategoryEntity";
|
|
|
|
//
|
|
// Custome Constants ...
|
|
public const string SubCategoryReference = "SubCat";
|
|
public const string CategoryTitleResourceIdentifier = "CatT";
|
|
public const string CategoryDescriptionResourceIdentifier = "CatD";
|
|
public const string SubCategoryTitleResourceIdentifier = "SubCatT";
|
|
public const string SubCategoryDescriptionResourceIdentifier = "SubCatD";
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXCategoryEFRepositoryDescriptor = "GetXCategoryEFRepositoryDescriptor";
|
|
public const string GetXSubCategoryEFRepositoryDescriptor = "GetXSubCategoryEFRepositoryDescriptor";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XCategoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xPushService.Controllers;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XCategoryProviderControllerBase : XBaseProvidedController<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategoryProviderController
|
|
{
|
|
private readonly IXCategoryProvider provider;
|
|
|
|
protected XCategoryProviderControllerBase(
|
|
ILogger<XCategoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryProvider provider,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
[NonAction]
|
|
[HttpGet("{id}")]
|
|
public override async Task<ActionResult<XCategoryDto>> Get(
|
|
[FromRoute] int id,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Get(
|
|
id: id,
|
|
useDefaultIncludes: useDefaultIncludes,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("")]
|
|
public override async Task<ActionResult<IEnumerable<XCategoryDto>>> GetAll(
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.GetAll(
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Find/One")]
|
|
public override async Task<ActionResult<XCategoryDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.FindOne(
|
|
query: query,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Find/Many")]
|
|
public override async Task<ActionResult<IEnumerable<XCategoryDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.FindMany(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Query")]
|
|
public override async Task<ActionResult<XQueryResult<XCategoryDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Query(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Query/Owned")]
|
|
public override async Task<ActionResult<XQueryResult<XCategoryDto>>> QueryOwned(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.QueryOwned(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpPost("")]
|
|
public override async Task<ActionResult<XCategoryDto>> Add(
|
|
[FromBody] XCategoryDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Add(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpPut("{id}")]
|
|
public override async Task<ActionResult<XCategoryDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XCategoryDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Update(
|
|
id: id,
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpDelete("{id}")]
|
|
public override async Task<ActionResult<XCategoryDto>> Remove(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Remove(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}/HasLocale")]
|
|
public virtual async Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(language);
|
|
|
|
//
|
|
var result = await provider.HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> GetResource(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Category Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> Add(
|
|
[FromBody] XCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotEmpty(language)
|
|
.AddNotEmpty(item.Title)
|
|
.AddNotEmpty(item.Description)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Add(
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Category Item for by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/AddResource")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> AddResource(
|
|
[FromBody] XCategoryResourceDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotNull(item.Titles)
|
|
.AddNotZeroChilds(item.Titles.Locales)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.AddResource(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> Remove(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Remove(
|
|
id: id,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Category Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotEmpty(language)
|
|
.AddNotEmpty(item.Title)
|
|
.AddNotEmpty(item.Description)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Update(
|
|
id: id,
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/Refresh")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> Refresh(
|
|
[FromBody] XCategoryResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(resource)
|
|
.AddNotNull(resource.Item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/All")]
|
|
public virtual async Task<ActionResult<IEnumerable<XCategoryResourceDto>>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetAllResources(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/One")]
|
|
public virtual async Task<ActionResult<XCategoryResourceDto>> FindOneResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindOneResource(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/Many")]
|
|
public virtual async Task<ActionResult<IEnumerable<XCategoryResourceDto>>> FindManyResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindManyResource(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query),
|
|
orderBuilder: x => x.OrderBy(y => y.Item.Id)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<XCategoryResourceDto>>> QueryResources(
|
|
[FromQuery] XQuery query = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.QueryResources(
|
|
query: query,
|
|
predicate: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Item.Id)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XCategoryRepositoryControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XCategoryRepositoryControllerBase : XBaseRepositoryController<XCategory, int>, IXBaseRepositoryController<XCategory, int>
|
|
{
|
|
protected XCategoryRepositoryControllerBase(
|
|
ILogger<XCategoryRepositoryControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryRepository repository,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repository,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XCategoryRepositoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XCategoryRepositoryProviderControllerBase : XBaseRepositoryProviderController<XCategory, int, XCategoryEntityHub>, IXBaseRepositoryProviderController<XCategory, int, XCategoryEntityHub>
|
|
{
|
|
protected XCategoryRepositoryProviderControllerBase(
|
|
ILogger<XCategoryRepositoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryRepositoryProvider provider,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XCategoryServiceControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XCategoryServiceControllerBase : XBaseServiceController<XCategory, XCategoryDto, int>, IXBaseServiceController<XCategory, XCategoryDto, int>
|
|
{
|
|
protected XCategoryServiceControllerBase(
|
|
ILogger<XCategoryServiceControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryRepositoryService repositoryService,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repositoryService,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XCategoryServiceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XCategoryServiceProviderControllerBase : XBaseServiceProviderController<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXBaseServiceProviderController<XCategory, XCategoryDto, int, XCategoryDtoHub>
|
|
{
|
|
protected XCategoryServiceProviderControllerBase(
|
|
ILogger<XCategoryServiceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryServiceProvider provider,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XSubCategoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xPushService.Controllers;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XSubCategoryProviderControllerBase : XBaseProvidedController<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXSubCategoryProviderController
|
|
{
|
|
private readonly IXSubCategoryProvider provider;
|
|
|
|
protected XSubCategoryProviderControllerBase(
|
|
ILogger<XSubCategoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryProvider provider,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
[NonAction]
|
|
[HttpGet("{id}")]
|
|
public override async Task<ActionResult<XSubCategoryDto>> Get(
|
|
[FromRoute] int id,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Get(
|
|
id: id,
|
|
useDefaultIncludes: useDefaultIncludes,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("")]
|
|
public override async Task<ActionResult<IEnumerable<XSubCategoryDto>>> GetAll(
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.GetAll(
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Find/One")]
|
|
public override async Task<ActionResult<XSubCategoryDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.FindOne(
|
|
query: query,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Find/Many")]
|
|
public override async Task<ActionResult<IEnumerable<XSubCategoryDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.FindMany(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Query")]
|
|
public override async Task<ActionResult<XQueryResult<XSubCategoryDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Query(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpGet("Query/Owned")]
|
|
public override async Task<ActionResult<XQueryResult<XSubCategoryDto>>> QueryOwned(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.QueryOwned(
|
|
query: query,
|
|
useDefaultOrders: useDefaultOrders,
|
|
cancellationToken: cancellationToken,
|
|
useDefaultIncludes: useDefaultIncludes
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpPost("")]
|
|
public override async Task<ActionResult<XSubCategoryDto>> Add(
|
|
[FromBody] XSubCategoryDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Add(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpPut("{id}")]
|
|
public override async Task<ActionResult<XSubCategoryDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XSubCategoryDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Update(
|
|
id: id,
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
[NonAction]
|
|
[HttpDelete("{id}")]
|
|
public override async Task<ActionResult<XSubCategoryDto>> Remove(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await base.Remove(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}/HasLocale")]
|
|
public virtual async Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(language);
|
|
|
|
//
|
|
var result = await provider.HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> GetResource(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Category Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> Add(
|
|
[FromBody] XSubCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotEmpty(language)
|
|
.AddNotEmpty(item.Title)
|
|
.AddNotEmpty(item.Description)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Add(
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/AddResource")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> AddResource(
|
|
[FromBody] XSubCategoryResourceDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotNull(item.Titles)
|
|
.AddNotZeroChilds(item.Titles.Locales)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.AddResource(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> Remove(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Remove(
|
|
id: id,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Category Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("Resources/{id}")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XSubCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid ||
|
|
!id.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.AddNotEmpty(language)
|
|
.AddNotEmpty(item.Title)
|
|
.AddNotEmpty(item.Description)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Update(
|
|
id: id,
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/Refresh")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> Refresh(
|
|
[FromBody] XSubCategoryResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(resource)
|
|
.AddNotNull(resource.Item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Reading Requirements ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/All")]
|
|
public virtual async Task<ActionResult<IEnumerable<XSubCategoryResourceDto>>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetAllResources(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/One")]
|
|
public virtual async Task<ActionResult<XSubCategoryResourceDto>> FindOneResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindOneResource(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/Many")]
|
|
public virtual async Task<ActionResult<IEnumerable<XSubCategoryResourceDto>>> FindManyResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindManyResource(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query),
|
|
orderBuilder: x => x.OrderBy(y => y.Item.Id)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<XSubCategoryResourceDto>>> QueryResources(
|
|
[FromQuery] XQuery query = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.QueryResources(
|
|
query: query,
|
|
predicate: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Item.Id)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XSubCategoryRepositoryControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XSubCategoryRepositoryControllerBase : XBaseRepositoryController<XSubCategory, int>, IXBaseRepositoryController<XSubCategory, int>
|
|
{
|
|
protected XSubCategoryRepositoryControllerBase(
|
|
ILogger<XSubCategoryRepositoryControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryRepository repository,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repository,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XSubCategoryRepositoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XSubCategoryRepositoryProviderControllerBase : XBaseRepositoryProviderController<XSubCategory, int, XSubCategoryEntityHub>, IXBaseRepositoryProviderController<XSubCategory, int, XSubCategoryEntityHub>
|
|
{
|
|
protected XSubCategoryRepositoryProviderControllerBase(
|
|
ILogger<XSubCategoryRepositoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryRepositoryProvider provider,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XSubCategoryServiceControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XSubCategoryServiceControllerBase : XBaseServiceController<XSubCategory, XSubCategoryDto, int>, IXBaseServiceController<XSubCategory, XSubCategoryDto, int>
|
|
{
|
|
protected XSubCategoryServiceControllerBase(
|
|
ILogger<XSubCategoryServiceControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryRepositoryService repositoryService,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repositoryService,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Controllers\XSubCategoryServiceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Controllers
|
|
{
|
|
public abstract class XSubCategoryServiceProviderControllerBase : XBaseServiceProviderController<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXBaseServiceProviderController<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>
|
|
{
|
|
protected XSubCategoryServiceProviderControllerBase(
|
|
ILogger<XSubCategoryServiceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryServiceProvider provider,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCategoryService.Configurations;
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Helpers;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Providers;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCategoryService.Providers.Entities;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
|
|
namespace xCategoryService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Extract Service Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XCategoryServiceConfiguration GetXCategoryServiceConfigurations(
|
|
this IConfiguration source
|
|
)
|
|
{
|
|
//
|
|
XCategoryServiceConfiguration result = null;
|
|
|
|
//
|
|
var section = source.GetSection(Constants.ConfigurationNodeNames.CATEGORY_SERVICE_NODE);
|
|
var sectionJson = source.GetSectionAsJson(Constants.ConfigurationNodeNames.CATEGORY_SERVICE_NODE);
|
|
if (!section.IsNull())
|
|
{
|
|
result = sectionJson.FromJSON<XCategoryServiceConfiguration>();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXCategoryServiceConfiguration(
|
|
this IServiceCollection source,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
// Extract Configuration Class ...
|
|
var config = configuration.GetXCategoryServiceConfigurations();
|
|
|
|
//
|
|
// Register Class as Service ...
|
|
source.AddXCategoryServiceConfiguration(config);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXCategoryServiceConfiguration(
|
|
this IServiceCollection source,
|
|
XCategoryServiceConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
// Normalize Configuration Class ...
|
|
if (configuration.IsNull())
|
|
{
|
|
configuration = new XCategoryServiceConfiguration();
|
|
}
|
|
|
|
//
|
|
// Register ...
|
|
source.AddSingleton(configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXCategoryService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddCategoryService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXCategoryService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddCategoryService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XSubCategoryService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXCategoryService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
// Category ...
|
|
pushHelper.AddHub<XCategoryDtoHub>(XCategoryServiceConstants.XCategoryDtoHub);
|
|
pushHelper.AddHub<XCategoryEntityHub>(XCategoryServiceConstants.XCategoryEntityHub);
|
|
|
|
//
|
|
// SubCategory ...
|
|
pushHelper.AddHub<XSubCategoryDtoHub>(XCategoryServiceConstants.XSubCategoryDtoHub);
|
|
pushHelper.AddHub<XSubCategoryEntityHub>(XCategoryServiceConstants.XSubCategoryEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XCategory Repository Descriptor ...
|
|
if (!categoryDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: categoryDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Using XSubCategory Repository Descriptor ...
|
|
if (!subCategoryDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: subCategoryDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Create an Scope for Services Acces ...
|
|
// Handle Seeding Category/SubCategory Resources ...
|
|
using (var scope = app.ApplicationServices.CreateScope())
|
|
{
|
|
//
|
|
// Retrieve Configuratuions ...
|
|
var categoryProvider = scope.ServiceProvider.GetService<IXCategoryProvider>();
|
|
var subCategoryProvider = scope.ServiceProvider.GetService<IXSubCategoryProvider>();
|
|
var configuration = scope.ServiceProvider.GetService<XCategoryServiceConfiguration>();
|
|
if (!configuration.IsNullOrDefault() &&
|
|
!categoryProvider.IsNullOrDefault() &&
|
|
!subCategoryDescriptor.IsNullOrDefault()
|
|
)
|
|
{
|
|
//
|
|
// Logging ...
|
|
Log("Start Seeding ...");
|
|
|
|
//
|
|
// Count Data in Category ...
|
|
var hasCategory = categoryProvider.Count().GetAwaiter().GetResult() > 0;
|
|
var hasSubCategory = subCategoryProvider.Count().GetAwaiter().GetResult() > 0;
|
|
|
|
//
|
|
// Seed Category Resources ...
|
|
var canSeed =
|
|
!hasCategory &&
|
|
configuration.Categories.HasChild();
|
|
if (canSeed)
|
|
{
|
|
//
|
|
// Loop through Provided items ...
|
|
foreach (var cat in configuration.Categories)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
Log($"Start Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} ...");
|
|
|
|
//
|
|
categoryProvider.Refresh(
|
|
resource: cat,
|
|
userInfo: null,
|
|
connectionId: null,
|
|
cancellationToken: default
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
Log($"Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} Finished Successfully ...");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"Seeding Category: {cat.Titles.Locales.ToArray()[0].Value} Failed due: {ex.Message} ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Seed SubCategory Resources ...
|
|
canSeed =
|
|
!hasSubCategory &&
|
|
configuration.SubCategories.HasChild();
|
|
if (canSeed)
|
|
{
|
|
//
|
|
// Loop through Provided items ...
|
|
foreach (var subcat in configuration.SubCategories)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
Log($"Start Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} ...");
|
|
|
|
//
|
|
subCategoryProvider.Refresh(
|
|
userInfo: null,
|
|
resource: subcat,
|
|
connectionId: null,
|
|
cancellationToken: default
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
Log($"Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} Finished Successfully ...");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log($"Seeding SubCategory: {subcat.Titles.Locales.ToArray()[0].Value} Failed due: {ex.Message} ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
Log("Finish Seeding ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor categoryDescriptor = null;
|
|
private static XRepositoryDescriptor subCategoryDescriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XCategoryServiceConstants.XCategoryServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddCategoryService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch (repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
// Category ...
|
|
categoryDescriptor = typeof(XCategoryServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XCategoryServiceConstants.GetXCategoryEFRepositoryDescriptor
|
|
);
|
|
|
|
//
|
|
// SubCategory ...
|
|
subCategoryDescriptor = typeof(XCategoryServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XCategoryServiceConstants.GetXSubCategoryEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
//
|
|
// Category ...
|
|
categoryDescriptor = XCategoryServiceHelper.GetXCategoryMongoRepositoryDescriptor();
|
|
|
|
//
|
|
// SubCategory ...
|
|
subCategoryDescriptor = XCategoryServiceHelper.GetXSubCategoryMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
//
|
|
// Category ...
|
|
categoryDescriptor = XCategoryServiceHelper.GetXCategoryInMemoryRepositoryDescriptor();
|
|
|
|
//
|
|
// SubCategory ...
|
|
subCategoryDescriptor = XCategoryServiceHelper.GetXSubCategoryInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Register Category Repository Descriptor ...
|
|
if (!categoryDescriptor.IsNull())
|
|
{
|
|
//
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: categoryDescriptor
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register SubCategory Repository Descriptor ...
|
|
if (!subCategoryDescriptor.IsNull())
|
|
{
|
|
//
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: subCategoryDescriptor
|
|
);
|
|
}
|
|
|
|
//
|
|
#region Register Services ...
|
|
//
|
|
#region Category ...
|
|
//
|
|
// Models ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryServiceProvider), typeof(XCategoryServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryRepositoryService), typeof(XCategoryRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryRepositoryProvider), typeof(XCategoryRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Resource Providers ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryTitleResourceProvider), typeof(XCategoryTitleResourceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryDescriptionResourceProvider), typeof(XCategoryDescriptionResourceProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Reference Providers ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategorySubCategoryReferenceProvider), typeof(XCategorySubCategoryReferenceProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Provider ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryProvider), typeof(XCategoryProvider), lifeTime)
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory ...
|
|
//
|
|
// Models ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryServiceProvider), typeof(XSubCategoryServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryRepositoryService), typeof(XSubCategoryRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryRepositoryProvider), typeof(XSubCategoryRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Resource Providers ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryTitleResourceProvider), typeof(XSubCategoryTitleResourceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryDescriptionResourceProvider), typeof(XSubCategoryDescriptionResourceProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Provider ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXSubCategoryProvider), typeof(XSubCategoryProvider), lifeTime)
|
|
);
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
// Register Service Main Provider ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXCategoryService), typeof(XCategoryService), lifeTime)
|
|
);
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Extensions\XCategoryResourceExtensions.cs
|
|
|
|
using System.Linq;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCategoryService.Extensions
|
|
{
|
|
/// <summary>
|
|
/// Extensions Method Related to XCategoryResourceDto ...
|
|
/// </summary>
|
|
public static class XCategoryResourceExtensions
|
|
{
|
|
/// <summary>
|
|
/// Extract Available Languages ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string[] ExtractLanguages(
|
|
this XCategoryResourceDto source
|
|
)
|
|
{
|
|
//
|
|
var result = new string[] { };
|
|
|
|
//
|
|
// Validate ...
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
source.Titles.Locales.Select(x => x.Language)
|
|
.Union(source.Descriptions.Locales.Select(x => x.Language))
|
|
.Distinct()
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Has Locale or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="language"></param>
|
|
/// <returns></returns>
|
|
public static bool HasLocale(
|
|
this XCategoryResourceDto source,
|
|
string language
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!language.IsNullOrEmpty() &&
|
|
!source.IsNullOrDefault() &&
|
|
source.Titles.Locales
|
|
.Any(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Item Translation ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="language"></param>
|
|
/// <returns></returns>
|
|
public static XCategoryDto GetTranslate(
|
|
this XCategoryResourceDto source,
|
|
string language
|
|
)
|
|
{
|
|
//
|
|
XCategoryDto result = null;
|
|
|
|
//
|
|
var isValid = source
|
|
.HasLocale(language);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var titleLocale = source.Titles.Locales
|
|
.FirstOrDefault(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
var descriptionLocale = source.Descriptions.Locales
|
|
.FirstOrDefault(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
isValid = !titleLocale.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = source.Item;
|
|
result.Title = titleLocale.Value;
|
|
result.Description =
|
|
descriptionLocale.IsNullOrDefault()
|
|
? string.Empty
|
|
: descriptionLocale.Value;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Extensions\XModelExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
|
|
namespace xCategoryService.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XCategory source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XCategoryDto source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XCategory UpdateReferences(
|
|
this XCategory source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XCategory result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XCategoryDto UpdateReferences(
|
|
this XCategoryDto source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XCategoryDto result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Extensions\XSubCategoryResourceExtensions.cs
|
|
|
|
using System.Linq;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCategoryService.Extensions
|
|
{
|
|
/// <summary>
|
|
/// Extensions Method Related to XSubCategoryResourceDto ...
|
|
/// </summary>
|
|
public static class XSubCategoryResourceExtensions
|
|
{
|
|
/// <summary>
|
|
/// Extract Available Languages ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string[] ExtractLanguages(
|
|
this XSubCategoryResourceDto source
|
|
)
|
|
{
|
|
//
|
|
var result = new string[] { };
|
|
|
|
//
|
|
// Validate ...
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
source.Titles.Locales.Select(x => x.Language)
|
|
.Union(source.Descriptions.Locales.Select(x => x.Language))
|
|
.Distinct()
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Has Locale or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="language"></param>
|
|
/// <returns></returns>
|
|
public static bool HasLocale(
|
|
this XSubCategoryResourceDto source,
|
|
string language
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!language.IsNullOrEmpty() &&
|
|
!source.IsNullOrDefault() &&
|
|
source.Titles.Locales
|
|
.Any(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Item Translation ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="language"></param>
|
|
/// <returns></returns>
|
|
public static XSubCategoryDto GetTranslate(
|
|
this XSubCategoryResourceDto source,
|
|
string language
|
|
)
|
|
{
|
|
//
|
|
XSubCategoryDto result = null;
|
|
|
|
//
|
|
var isValid = source
|
|
.HasLocale(language);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var titleLocale = source.Titles.Locales
|
|
.FirstOrDefault(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
var descriptionLocale = source.Descriptions.Locales
|
|
.FirstOrDefault(l => l.Language
|
|
.Equals(
|
|
language,
|
|
System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
isValid = !titleLocale.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = source.Item;
|
|
result.Title = titleLocale.Value;
|
|
result.Description =
|
|
descriptionLocale.IsNullOrDefault()
|
|
? string.Empty
|
|
: descriptionLocale.Value;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Helpers\XCategoryServiceHelper.cs
|
|
|
|
using GraphQL.Types;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Entities;
|
|
using xCategoryService.Providers.GraphQL;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Helpers
|
|
{
|
|
public static class XCategoryServiceHelper
|
|
{
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
//
|
|
#region Category
|
|
public static XEFRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryEFRepository<TContext>,
|
|
TContext
|
|
> GetXCategoryEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryEFRepository<TContext>,
|
|
TContext,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXCategoryEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XCategory, int>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryEFRepository<TContext>,
|
|
TContext,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory
|
|
public static XEFRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryEFRepository<TContext>,
|
|
TContext
|
|
> GetXSubCategoryEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryEFRepository<TContext>,
|
|
TContext,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXSubCategoryEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XSubCategory, int>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryEFRepository<TContext>,
|
|
TContext,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
//
|
|
#region Category
|
|
public static XMongoRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryMongoRepository
|
|
> GetXCategoryMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryMongoRepository,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXCategoryMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XCategory, int>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryMongoRepository,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory
|
|
public static XMongoRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryMongoRepository
|
|
> GetXSubCategoryMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryMongoRepository,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXSubCategoryMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XSubCategory, int>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryMongoRepository,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
//
|
|
#region Category
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryInMemoryRepository
|
|
> GetXCategoryInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryInMemoryRepository,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXCategoryInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XCategory, int>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XCategory,
|
|
int,
|
|
IXCategoryKeyGenerator,
|
|
XCategoryKeyGenerator,
|
|
IXCategoryRepositoryEvents,
|
|
XCategoryRepositoryEvents,
|
|
XCategoryGraphType,
|
|
IntGraphType,
|
|
XCategoryGraphQuery,
|
|
IXCategoryGraphQLTypeHelper,
|
|
XCategoryGraphQLTypeHelper,
|
|
XCategoryGraphSchema,
|
|
IXCategoryRepository,
|
|
XCategoryInMemoryRepository,
|
|
IXCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryInMemoryRepository
|
|
> GetXSubCategoryInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryInMemoryRepository,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
> GetXSubCategoryInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XSubCategory, int>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XSubCategory,
|
|
int,
|
|
IXSubCategoryKeyGenerator,
|
|
XSubCategoryKeyGenerator,
|
|
IXSubCategoryRepositoryEvents,
|
|
XSubCategoryRepositoryEvents,
|
|
XSubCategoryGraphType,
|
|
IntGraphType,
|
|
XSubCategoryGraphQuery,
|
|
IXSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphQLTypeHelper,
|
|
XSubCategoryGraphSchema,
|
|
IXSubCategoryRepository,
|
|
XSubCategoryInMemoryRepository,
|
|
IXSubCategorySeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXCategoryDtoHub.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXCategoryDtoHub : IXBaseDtoHub<XCategory, XCategoryDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXCategoryRepositoryService.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXCategoryRepositoryService : IXBaseRepositoryService<XCategory, XCategoryDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXCategoryServiceProvider.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXCategoryServiceProvider : IXBaseDtoProvider<XCategory, XCategoryDto, int, XCategoryDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXSubCategoryDtoHub.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXSubCategoryDtoHub : IXBaseDtoHub<XSubCategory, XSubCategoryDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXSubCategoryRepositoryService.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXSubCategoryRepositoryService : IXBaseRepositoryService<XSubCategory, XSubCategoryDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Dtos\IXSubCategoryServiceProvider.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Dtos
|
|
{
|
|
public interface IXSubCategoryServiceProvider : IXBaseDtoProvider<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryEntityHub.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryEntityHub : IXBaseEntityHub<XCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryGraphQLTypeHelper.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryKeyGenerator.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryKeyGenerator : IXKeyGenerator<XCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryRepository.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryRepository : IXBaseRepository<XCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryRepositoryEvents.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryRepositoryEvents : IXBaseRepositoryEvents<XCategory>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategoryRepositoryProvider.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategoryRepositoryProvider : IXBaseEntityProvider<XCategory, int, XCategoryEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXCategorySeeder.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXCategorySeeder : IXBaseDbSeeder<XCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryEntityHub.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryEntityHub : IXBaseEntityHub<XSubCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryGraphQLTypeHelper.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XSubCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryKeyGenerator.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryKeyGenerator : IXKeyGenerator<XSubCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryRepository.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryRepository : IXBaseRepository<XSubCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryRepositoryEvents.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryRepositoryEvents : IXBaseRepositoryEvents<XSubCategory>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategoryRepositoryProvider.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategoryRepositoryProvider : IXBaseEntityProvider<XSubCategory, int, XSubCategoryEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\Entities\IXSubCategorySeeder.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces.Entities
|
|
{
|
|
public interface IXSubCategorySeeder : IXBaseDbSeeder<XSubCategory, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXBaseCategoryProvider.cs
|
|
|
|
using xCategoryService.Models.Dtos;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXBaseCategoryProvider<TKey> : IXBaseReferencedProvider<XCategoryDto, TKey>
|
|
{}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategoryDescriptionResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXCategoryDescriptionResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategoryProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXCategoryProvider : IXBaseProvided<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategorySubCategoryReferenceProvider
|
|
{
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> HasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> GetResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> Add(
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> AddResource(
|
|
XCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> Remove(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> Update(
|
|
int id,
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> Refresh(
|
|
XCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XCategoryResourceDto>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> FindOneResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XCategoryResourceDto>> FindManyResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XCategoryResourceDto>> QueryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<XCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategoryProviderController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXCategoryProviderController : IXBaseProvidedController<XCategory, XCategoryDto, int, XCategoryDtoHub>
|
|
{
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}/HasLocale")]
|
|
Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}")]
|
|
Task<ActionResult<XCategoryResourceDto>> GetResource(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources")]
|
|
Task<ActionResult<XCategoryResourceDto>> Add(
|
|
[FromBody] XCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/AddResource")]
|
|
Task<ActionResult<XCategoryResourceDto>> AddResource(
|
|
[FromBody] XCategoryResourceDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Resources/{id}")]
|
|
Task<ActionResult<XCategoryResourceDto>> Remove(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("Resources/{id}")]
|
|
Task<ActionResult<XCategoryResourceDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/Refresh")]
|
|
Task<ActionResult<XCategoryResourceDto>> Refresh(
|
|
[FromBody] XCategoryResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/All")]
|
|
Task<ActionResult<IEnumerable<XCategoryResourceDto>>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/One")]
|
|
Task<ActionResult<XCategoryResourceDto>> FindOneResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/Many")]
|
|
Task<ActionResult<IEnumerable<XCategoryResourceDto>>> FindManyResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Query")]
|
|
Task<ActionResult<XQueryResult<XCategoryResourceDto>>> QueryResources(
|
|
[FromQuery] XQuery query = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Models.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// Completely Exported Service ...
|
|
/// </summary>
|
|
public interface IXCategoryService
|
|
{
|
|
//
|
|
#region Category Provider ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> CategoryHasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> GetCategoryResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> AddCategory(
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> AddCategoryResource(
|
|
XCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> RemoveCategory(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> UpdateCategory(
|
|
int id,
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> RefreshCategory(
|
|
XCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XCategoryResourceDto>> GetAllCategoryResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XCategoryResourceDto> FindOneCategoryResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XCategoryResourceDto>> FindManyCategoryResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XCategoryResourceDto>> QueryCategoryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<XCategoryResourceDto> GetAllCategoryResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory Provider ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> SubCategoryHasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> GetSubCategoryResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> AddSubCategory(
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> AddSubCategoryResource(
|
|
XSubCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> RemoveSubCategory(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> UpdateSubCategory(
|
|
int id,
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> RefreshSubCategory(
|
|
XSubCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XSubCategoryResourceDto>> GetAllSubCategoryResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> FindOneSubCategoryResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XSubCategoryResourceDto>> FindManySubCategoryResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XSubCategoryResourceDto>> QuerySubCategoryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<XSubCategoryResourceDto> GetAllSubCategoryResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategorySubCategoryReferenceProvider.cs
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Service for SubCategory Referencing on Category ...
|
|
/// </summary>
|
|
public interface IXCategorySubCategoryReferenceProvider : IXBaseCategoryProvider<int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXCategoryTitleResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXCategoryTitleResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXSubCategoryDescriptionResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXSubCategoryDescriptionResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXSubCategoryProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXSubCategoryProvider : IXBaseProvided<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>
|
|
{
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> HasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> GetResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> Add(
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> AddResource(
|
|
XSubCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> Remove(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> Update(
|
|
int id,
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> Refresh(
|
|
XSubCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XSubCategoryResourceDto>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XSubCategoryResourceDto> FindOneResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XSubCategoryResourceDto>> FindManyResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XSubCategoryResourceDto>> QueryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<XSubCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXSubCategoryProviderController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXSubCategoryProviderController : IXBaseProvidedController<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>
|
|
{
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}/HasLocale")]
|
|
Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/{id}")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> GetResource(
|
|
[FromRoute] int id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> Add(
|
|
[FromBody] XSubCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/AddResource")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> AddResource(
|
|
[FromBody] XSubCategoryResourceDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Resources/{id}")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> Remove(
|
|
[FromRoute] int id,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("Resources/{id}")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> Update(
|
|
[FromRoute] int id,
|
|
[FromBody] XSubCategoryDto item,
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resources/Refresh")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> Refresh(
|
|
[FromBody] XSubCategoryResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/All")]
|
|
Task<ActionResult<IEnumerable<XSubCategoryResourceDto>>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/One")]
|
|
Task<ActionResult<XSubCategoryResourceDto>> FindOneResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Find/Many")]
|
|
Task<ActionResult<IEnumerable<XSubCategoryResourceDto>>> FindManyResource(
|
|
[FromQuery] string query,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resources/Query")]
|
|
Task<ActionResult<XQueryResult<XSubCategoryResourceDto>>> QueryResources(
|
|
[FromQuery] XQuery query = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Interfaces\IXSubCategoryTitleResourceProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xCategoryService.Interfaces
|
|
{
|
|
public interface IXSubCategoryTitleResourceProvider : IXItemResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Dtos\XCategoryDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xCategoryService.Models.Dtos
|
|
{
|
|
public class XCategoryDto : XBaseIntIDEntityDto
|
|
{
|
|
/// <summary>
|
|
/// Title of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// References List String Representation ...
|
|
/// each SubCategory Referenced to Category ID which List here ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Dtos\XCategoryResourceDto.cs
|
|
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xCategoryService.Models.Dtos
|
|
{
|
|
/// <summary>
|
|
/// Represent a Category by all of it's Resources ...
|
|
/// </summary>
|
|
public class XCategoryResourceDto : XBaseDto
|
|
{
|
|
/// <summary>
|
|
/// Category Dto Item for Add or Update ...
|
|
/// </summary>
|
|
public XCategoryDto Item { get; set; }
|
|
|
|
/// <summary>
|
|
/// Exists Category Titles ...
|
|
/// </summary>
|
|
public XResourceDto Titles { get; set; }
|
|
|
|
/// <summary>
|
|
/// Exists Category Description ...
|
|
/// </summary>
|
|
public XResourceDto Descriptions { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Dtos\XSubCategoryDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xCategoryService.Models.Dtos
|
|
{
|
|
public class XSubCategoryDto : XBaseIntIDEntityDto
|
|
{
|
|
/// <summary>
|
|
/// Title of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// References List String Representation ...
|
|
/// each SubCategory Referenced to Category ID which List here ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Dtos\XSubCategoryResourceDto.cs
|
|
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xCategoryService.Models.Dtos
|
|
{
|
|
public class XSubCategoryResourceDto : XBaseDto
|
|
{
|
|
/// <summary>
|
|
/// SubCategory Dto Item for Add or Update ...
|
|
/// </summary>
|
|
public XSubCategoryDto Item { get; set; }
|
|
|
|
/// <summary>
|
|
/// Exists SubCategory Titles ...
|
|
/// </summary>
|
|
public XResourceDto Titles { get; set; }
|
|
|
|
/// <summary>
|
|
/// Exists SubCategory Description ...
|
|
/// </summary>
|
|
public XResourceDto Descriptions { get; set; }
|
|
|
|
/// <summary>
|
|
/// Exists Category Resource Dto for Add or Update Category or
|
|
/// Related Categopry ...
|
|
/// </summary>
|
|
public XCategoryResourceDto Category { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Entities\XCategory.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xCategoryService.Models.Entities
|
|
{
|
|
public class XCategory : XBaseIntIDEntity
|
|
{
|
|
/// <summary>
|
|
/// Title of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// References List String Representation ...
|
|
/// each SubCategory Referenced to Category ID which List here ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Models\Entities\XSubCategory.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xCategoryService.Models.Entities
|
|
{
|
|
public class XSubCategory : XBaseIntIDEntity
|
|
{
|
|
/// <summary>
|
|
/// Title of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description of SubCategory ...
|
|
/// this is a Resource Title ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// References List String Representation ...
|
|
/// each SubCategory Referenced to Category ID which List here ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XCategoryDtoHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XCategoryDtoHub : XBaseDtoHub<XCategory, XCategoryDto, int>, IXCategoryDtoHub
|
|
{
|
|
public XCategoryDtoHub(
|
|
ILogger<XCategoryDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XCategoryRepositoryService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XCategoryRepositoryService : XBaseRepositoryService<XCategory, XCategoryDto, int>, IXCategoryRepositoryService
|
|
{
|
|
public XCategoryRepositoryService(
|
|
IXCategoryRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XCategoryServiceProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XCategoryServiceProvider : XBaseDtoProvider<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategoryServiceProvider
|
|
{
|
|
public XCategoryServiceProvider(
|
|
IHubContext<XCategoryDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXCategoryRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XSubCategoryDtoHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XSubCategoryDtoHub : XBaseDtoHub<XSubCategory, XSubCategoryDto, int>, IXSubCategoryDtoHub
|
|
{
|
|
public XSubCategoryDtoHub(
|
|
ILogger<XSubCategoryDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XSubCategoryRepositoryService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XSubCategoryRepositoryService : XBaseRepositoryService<XSubCategory, XSubCategoryDto, int>, IXSubCategoryRepositoryService
|
|
{
|
|
public XSubCategoryRepositoryService(
|
|
IXSubCategoryRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Dtos\XSubCategoryServiceProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Dtos
|
|
{
|
|
public class XSubCategoryServiceProvider : XBaseDtoProvider<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXSubCategoryServiceProvider
|
|
{
|
|
public XSubCategoryServiceProvider(
|
|
IHubContext<XSubCategoryDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXSubCategoryRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryEFRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryEFRepository<TContext> : XBaseEFRepository<XCategory, int, TContext>, IXCategoryRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XCategoryEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXCategoryKeyGenerator keyGenerator = null,
|
|
IXCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryEntityHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryEntityHub : XBaseEntityHub<XCategory, int>, IXCategoryEntityHub
|
|
{
|
|
public XCategoryEntityHub(
|
|
ILogger<XCategoryEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryInMemoryRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryInMemoryRepository : XBaseInMemoryRepository<XCategory, int>, IXCategoryRepository
|
|
{
|
|
public XCategoryInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXCategoryKeyGenerator keyGenerator = null,
|
|
IXCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryKeyGenerator.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryKeyGenerator : XIntKeyGenerator<XCategory>, IXCategoryKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryMongoRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryMongoRepository : XBaseMongoRepository<XCategory, int>, IXCategoryRepository
|
|
{
|
|
public XCategoryMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXCategoryKeyGenerator keyGenerator = null,
|
|
IXCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryRepositoryEvents.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryRepositoryEvents : XBaseRepositoryEvents<XCategory>, IXCategoryRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategoryRepositoryProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XCategoryRepositoryProvider : XBaseEntityProvider<XCategory, int, XCategoryEntityHub>, IXCategoryRepositoryProvider
|
|
{
|
|
public XCategoryRepositoryProvider(
|
|
IHubContext<XCategoryEntityHub> hub,
|
|
IXCategoryRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XCategorySeederBase.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public abstract class XCategorySeederBase : XBaseDbSeeder<XCategory, int>, IXCategorySeeder
|
|
{
|
|
protected XCategorySeederBase(
|
|
string entity,
|
|
string database,
|
|
IXCategoryRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryEFRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryEFRepository<TContext> : XBaseEFRepository<XSubCategory, int, TContext>, IXSubCategoryRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XSubCategoryEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXSubCategoryKeyGenerator keyGenerator = null,
|
|
IXSubCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryEntityHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryEntityHub : XBaseEntityHub<XSubCategory, int>, IXSubCategoryEntityHub
|
|
{
|
|
public XSubCategoryEntityHub(
|
|
ILogger<XSubCategoryEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryInMemoryRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryInMemoryRepository : XBaseInMemoryRepository<XSubCategory, int>, IXSubCategoryRepository
|
|
{
|
|
public XSubCategoryInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXSubCategoryKeyGenerator keyGenerator = null,
|
|
IXSubCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryKeyGenerator.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryKeyGenerator : XIntKeyGenerator<XSubCategory>, IXSubCategoryKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryMongoRepository.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryMongoRepository : XBaseMongoRepository<XSubCategory, int>, IXSubCategoryRepository
|
|
{
|
|
public XSubCategoryMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXSubCategoryKeyGenerator keyGenerator = null,
|
|
IXSubCategoryRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryRepositoryEvents.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryRepositoryEvents : XBaseRepositoryEvents<XSubCategory>, IXSubCategoryRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategoryRepositoryProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public class XSubCategoryRepositoryProvider : XBaseEntityProvider<XSubCategory, int, XSubCategoryEntityHub>, IXSubCategoryRepositoryProvider
|
|
{
|
|
public XSubCategoryRepositoryProvider(
|
|
IHubContext<XSubCategoryEntityHub> hub,
|
|
IXSubCategoryRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\Entities\XSubCategorySeederBase.cs
|
|
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers.Entities
|
|
{
|
|
public abstract class XSubCategorySeederBase : XBaseDbSeeder<XSubCategory, int>, IXSubCategorySeeder
|
|
{
|
|
protected XSubCategorySeederBase(
|
|
string entity,
|
|
string database,
|
|
IXSubCategoryRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XCategoryGraphQLTypeHelper.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XCategoryGraphQLTypeHelper : XBaseGraphQLTypeHelper<XCategory, int>, IXCategoryGraphQLTypeHelper
|
|
{
|
|
public XCategoryGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XCategoryServiceConstants.XCategoryCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XCategoryServiceConstants.XCategorySingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XCategoryGraphQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XCategoryGraphQuery : XBaseGraphQLQuery<XCategory, int, XCategoryGraphType, IntGraphType>
|
|
{
|
|
public XCategoryGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXCategoryRepository repository,
|
|
IXCategoryGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XCategoryGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XCategoryGraphSchema : Schema
|
|
{
|
|
public XCategoryGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XCategoryGraphQuery)services.GetService(typeof(XCategoryGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XCategoryGraphType.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XCategoryGraphType : XBaseGraphObjectType<XCategory, int>
|
|
{
|
|
public XCategoryGraphType() : base()
|
|
{
|
|
Field(x => x.Title);
|
|
Field(x => x.Description);
|
|
Field(x => x.References);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XSubCategoryGraphQLTypeHelper.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XSubCategoryGraphQLTypeHelper : XBaseGraphQLTypeHelper<XSubCategory, int>, IXSubCategoryGraphQLTypeHelper
|
|
{
|
|
public XSubCategoryGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XCategoryServiceConstants.XSubCategoryCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XCategoryServiceConstants.XSubCategorySingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XSubCategoryGraphQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xCategoryService.Interfaces.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XSubCategoryGraphQuery : XBaseGraphQLQuery<XSubCategory, int, XSubCategoryGraphType, IntGraphType>
|
|
{
|
|
public XSubCategoryGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXSubCategoryRepository repository,
|
|
IXSubCategoryGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XSubCategoryGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XSubCategoryGraphSchema : Schema
|
|
{
|
|
public XSubCategoryGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XSubCategoryGraphQuery)services.GetService(typeof(XSubCategoryGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\GraphQL\XSubCategoryGraphType.cs
|
|
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.GraphQL;
|
|
|
|
namespace xCategoryService.Providers.GraphQL
|
|
{
|
|
public class XSubCategoryGraphType : XBaseGraphObjectType<XSubCategory, int>
|
|
{
|
|
public XSubCategoryGraphType() : base()
|
|
{
|
|
Field(x => x.Title);
|
|
Field(x => x.Description);
|
|
Field(x => x.References);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XBaseCategoryProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Extensions;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public abstract class XBaseCategoryProvider<TKey> : IXBaseCategoryProvider<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Provider Identifier ...
|
|
/// </summary>
|
|
public string Provider { get; }
|
|
|
|
/// <summary>
|
|
/// Tag Provider for Maipulating Tags ...
|
|
/// </summary>
|
|
public IXCategoryServiceProvider CategoryProvider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseCategoryProvider(
|
|
string providedFor,
|
|
IXCategoryServiceProvider categoryProvider
|
|
)
|
|
{
|
|
//
|
|
Provider = providedFor;
|
|
CategoryProvider = categoryProvider;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryDto> GetReference(
|
|
TKey providedForId,
|
|
int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (forIndex < 0)
|
|
{
|
|
forIndex = 0;
|
|
}
|
|
|
|
//
|
|
// Retrieve Last Index ...
|
|
var indexes = await GetReferencingIndexes(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var maxIndex = indexes.HasChild() ? indexes.Max() : -1;
|
|
if (forIndex > maxIndex)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var indexedIdentifier = GetIndexedProvidedID(
|
|
forIndex: forIndex,
|
|
providedForId: providedForId
|
|
);
|
|
var result = await CategoryProvider.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(indexedIdentifier)
|
|
);
|
|
if (result.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XCategoryDto>> GetAllReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = await CategoryProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XReference<TKey>>> GetAllReferencings(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
|
|
//
|
|
var result = (await CategoryProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
))
|
|
.Select(x => x.References)
|
|
.ToList()
|
|
.SelectMany(x => x.ParseXReferenceList<TKey>())
|
|
.Where(x => x.ProvidedFor == Provider && $"{x.ReferencedTo}" == $"{providedForId}")
|
|
.OrderBy(x => x.Index)
|
|
.AsEnumerable();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = (await CategoryProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
))
|
|
.Count();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XCategoryDto>> QueryReferences(
|
|
XQuery query,
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (query.IsNull() || providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = await CategoryProvider.QueryAsync(
|
|
query: query,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Id),
|
|
predicate: x => x.References.Contains(identifier)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = !model.IsNullOrDefault() &&
|
|
model.Id.IsValidIntId() &&
|
|
!providedForId.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Model Exists ...
|
|
result = await CategoryProvider.IsExistsAsync(model.Id);
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Model by Retrieving ...
|
|
model = await CategoryProvider.GetAsync(
|
|
id: model.Id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Retrieve all References ...
|
|
var references = await GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check isReferenced or not ...
|
|
result = references
|
|
.Any(r =>
|
|
r.Id == model.Id &&
|
|
r.GetReferences()
|
|
.Any(rf =>
|
|
rf.ProvidedFor == Provider &&
|
|
rf.ReferencedTo == $"{providedForId}"));
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Here means there is not any reference to ProvidedForId ...
|
|
int forIndex = await CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var modelReferences = model.GetReferences();
|
|
modelReferences.Add(new XReference<string>
|
|
{
|
|
Index = forIndex,
|
|
ProvidedFor = Provider,
|
|
ReferencedTo = $"{providedForId}"
|
|
});
|
|
modelReferences = modelReferences
|
|
.OrderBy(r => r.Index)
|
|
.ToList();
|
|
model = model.UpdateReferences(modelReferences);
|
|
|
|
//
|
|
// Update Data Base ...
|
|
model = await CategoryProvider.UpdateAsync(
|
|
id: model.Id,
|
|
item: model,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
// Since other Validations Handled in Calling, we Ignore them here ...
|
|
var result =
|
|
!model.IsNull() &&
|
|
!reference.IsNullOrDefault() &&
|
|
reference.ProvidedFor == Provider &&
|
|
!reference.ReferencedTo.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
result = await AddReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!providedForId.IsNull() &&
|
|
!model.IsNullOrDefault() &&
|
|
model.Id.IsValidIntId();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Model ...
|
|
model = await CategoryProvider.GetAsync(
|
|
id: model.Id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Reading Referencing Indexes ...
|
|
var indexes = await GetReferencingIndexes(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Model Reference to ID ...
|
|
var referencesCount = await CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = referencesCount == 0;
|
|
if (result)
|
|
{
|
|
//
|
|
// There is not any Reference to Remove ...
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Model is Trully Referenced to ProvidedForId or not ...
|
|
var reference = model
|
|
.GetReferences()
|
|
.FirstOrDefault(r =>
|
|
r.ProvidedFor == Provider &&
|
|
r.ReferencedTo == $"{providedForId}");
|
|
result = !reference.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Remove Referenced Item from Model ...
|
|
var modelReferences = model
|
|
.GetReferences()
|
|
.Where(r =>
|
|
!(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo == $"{providedForId}"))
|
|
.ToList();
|
|
model = model.UpdateReferences(modelReferences);
|
|
|
|
//
|
|
// Update DataBase ...
|
|
model = await CategoryProvider.UpdateAsync(
|
|
item: model,
|
|
id: model.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = !model.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Get Max Exists Indexes ...
|
|
var maxIndex = indexes.Max();
|
|
|
|
//
|
|
// Here We Have to Re Arrange Indexed ...
|
|
if (reference.Index < maxIndex)
|
|
{
|
|
//
|
|
var startIndex = reference.Index + 1;
|
|
for (int i = startIndex; i <= maxIndex; i++)
|
|
{
|
|
//
|
|
var dto = await GetReference(
|
|
forIndex: i,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!dto.IsNullOrDefault())
|
|
{
|
|
//
|
|
var dtoReferences = dto.GetReferences();
|
|
dtoReferences
|
|
.ToList()
|
|
.ForEach(iref =>
|
|
{
|
|
//
|
|
if (
|
|
iref.Index == i &&
|
|
iref.ProvidedFor == Provider &&
|
|
iref.ReferencedTo == reference.ReferencedTo
|
|
)
|
|
{
|
|
iref.Index = i - 1;
|
|
}
|
|
});
|
|
dto = dto.UpdateReferences(dtoReferences);
|
|
|
|
//
|
|
dto = await CategoryProvider.UpdateAsync(
|
|
item: dto,
|
|
id: dto.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (model.IsNullOrDefault() ||
|
|
reference.IsNullOrDefault() ||
|
|
reference.ReferencedTo.IsNull() ||
|
|
reference.ProvidedFor != Provider)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await RemoveReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReferences(
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = false;
|
|
var references = await GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!references.IsNull() && references.HasChild())
|
|
{
|
|
//
|
|
foreach (var reference in references)
|
|
{
|
|
//
|
|
// Remove Reference ...
|
|
var itemReferences = reference.GetReferences()
|
|
.Where(r =>
|
|
r.ProvidedFor != Provider ||
|
|
(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo != $"{providedForId}"))
|
|
.ToList();
|
|
var updatedModel = reference.UpdateReferences(itemReferences);
|
|
updatedModel = await CategoryProvider.UpdateAsync(
|
|
saveChanges: true,
|
|
item: updatedModel,
|
|
id: updatedModel.Id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!updatedModel.IsNullOrDefault())
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private string GetProvidedID(
|
|
TKey providedForId,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = $"{Provider}{splitter}{providedForId}";
|
|
return result;
|
|
}
|
|
|
|
private string GetIndexedProvidedID(
|
|
TKey providedForId,
|
|
int forIndex,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{forIndex}";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private async Task<IEnumerable<int>> GetReferencingIndexes(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new List<int>();
|
|
var referencings = await GetAllReferencings(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!referencings.IsNull() &&
|
|
referencings.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
referencings
|
|
.OrderBy(r => r.Index)
|
|
.Select(r => r.Index)
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategoryDescriptionResourceProvider.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategoryDescriptionResourceProvider : XBaseItemResourceProvider, IXCategoryDescriptionResourceProvider
|
|
{
|
|
public XCategoryDescriptionResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XCategoryServiceConstants.CategoryDescriptionResourceIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategoryEntityRegisterar.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCategoryService.Configurations.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategoryEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XCategoryEntityRegisterar()
|
|
: base(nameof(XCategoryEntityRegisterar))
|
|
{
|
|
//
|
|
// Add XCategory Entity ...
|
|
AddEntity<XCategory, int>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XCategoryEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategoryProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xDataService.Extensions;
|
|
using xPushService.Constants;
|
|
using xPushService.Providers;
|
|
using xDataService.Configuration;
|
|
using xDataService.Models;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategoryProvider : XBaseProvided<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategoryProvider
|
|
{
|
|
private readonly IXCategoryServiceProvider provider;
|
|
private readonly XAppConfiguration appConfiguration;
|
|
private readonly XDataServiceConfiguration dataServiceConfiguration;
|
|
private readonly IXCategoryTitleResourceProvider titleResourceProvider;
|
|
private readonly IXCategoryDescriptionResourceProvider descriptionResourceProvider;
|
|
private readonly IXCategorySubCategoryReferenceProvider categorySubCategoryReferenceProvider;
|
|
|
|
public string Provider => categorySubCategoryReferenceProvider.Provider;
|
|
|
|
public XCategoryProvider(
|
|
XAppConfiguration appConfiguration,
|
|
IXCategoryServiceProvider provider,
|
|
XDataServiceConfiguration dataServiceConfiguration,
|
|
IXCategoryTitleResourceProvider titleResourceProvider,
|
|
IXCategoryDescriptionResourceProvider descriptionResourceProvider,
|
|
IXCategorySubCategoryReferenceProvider categorySubCategoryReferenceProvider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{
|
|
//
|
|
this.provider = provider;
|
|
this.appConfiguration = appConfiguration;
|
|
this.titleResourceProvider = titleResourceProvider;
|
|
this.dataServiceConfiguration = dataServiceConfiguration;
|
|
this.descriptionResourceProvider = descriptionResourceProvider;
|
|
this.categorySubCategoryReferenceProvider = categorySubCategoryReferenceProvider;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
public override bool IsOwned(
|
|
XCategoryDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XCategory item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> HasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
id.IsValidIntId() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Resource ...
|
|
var resource = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Result ...
|
|
var result =
|
|
!resource.IsNullOrDefault() &&
|
|
resource.Titles.Locales
|
|
.Any(x => x.Language
|
|
.Equals(language, System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> GetResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var titleResource = await titleResourceProvider.GetResource(
|
|
identifier: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider.GetResource(
|
|
identifier: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var result = new XCategoryResourceDto
|
|
{
|
|
Item = item,
|
|
Titles = titleResource,
|
|
Descriptions = descriptionResource
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> Add(
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
language =
|
|
!language.IsNullOrEmpty()
|
|
? language
|
|
: appConfiguration.DefaultLanguage;
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
try
|
|
{
|
|
//
|
|
var title = item.Title;
|
|
var description = item.Description;
|
|
|
|
//
|
|
// Add Item Pure for ID Generating ...
|
|
item = await base.Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: null, // Since here We dont want notification ...
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
id = item.Id;
|
|
var titleResource = await titleResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = title,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = description,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Update Category Dto ...
|
|
item.Title = titleResource.Resource;
|
|
item.Description = descriptionResource.Resource;
|
|
item = await base.Update(
|
|
id: id,
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Id ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Category Resourv=ce ...
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Sending Push Notification ...
|
|
isValid =
|
|
isValid &&
|
|
!result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Category by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> AddResource(
|
|
XCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!item.IsNullOrDefault() &&
|
|
!item.Titles.IsNullOrDefault() &&
|
|
item.Titles.Locales.HasChild() &&
|
|
!item.Titles.Locales.Any(il =>
|
|
il.Language.IsNullOrEmpty() ||
|
|
il.Value.IsNullOrEmpty());
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (item.Item.IsNullOrDefault())
|
|
{
|
|
item.Item = new XCategoryDto();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
try
|
|
{
|
|
//
|
|
// Add Category for ID Generation ...
|
|
item.Item = await base.Add(
|
|
item: item.Item,
|
|
userInfo: userInfo,
|
|
connectionId: null, // Since here We dont want notification ...
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !item.Item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
id = item.Item.Id;
|
|
|
|
//
|
|
foreach (var il in item.Titles.Locales)
|
|
{
|
|
//
|
|
var title = il.Value;
|
|
var language = il.Language;
|
|
|
|
//
|
|
var descriptionItem =
|
|
item.Descriptions.IsNullOrDefault() ||
|
|
!item.Descriptions.Locales.HasChild()
|
|
? null
|
|
: item.Descriptions.Locales
|
|
.FirstOrDefault(ides =>
|
|
ides.Language
|
|
.Equals(
|
|
language,
|
|
StringComparison.InvariantCultureIgnoreCase));
|
|
var description =
|
|
descriptionItem.IsNullOrDefault()
|
|
? string.Empty
|
|
: descriptionItem.Value;
|
|
|
|
//
|
|
// Try to Add Resources ...
|
|
var titleResource = await titleResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = title,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = description,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Update Category Dto if not ...
|
|
if (item.Item.Title.IsNullOrEmpty() ||
|
|
!item.Item.Title
|
|
.Equals(
|
|
titleResource.Resource,
|
|
StringComparison.InvariantCultureIgnoreCase)
|
|
)
|
|
{
|
|
//
|
|
item.Item.Title = titleResource.Resource;
|
|
item.Item.Description = descriptionResource.Resource;
|
|
item.Item = await base.Update(
|
|
id: id,
|
|
item: item.Item,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Id ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Category Resourv=ce ...
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Sending Push Notification ...
|
|
isValid =
|
|
isValid &&
|
|
!result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> Remove(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
isValid = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Locale if Provided ...
|
|
isValid =
|
|
language.IsNullOrEmpty() ||
|
|
await HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Remove All ...
|
|
|
|
//
|
|
// Titles ...
|
|
await titleResourceProvider.RemoveLocales(
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Descriptions ...
|
|
await descriptionResourceProvider.RemoveLocales(
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Remove Entity ...
|
|
await provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
isValid = true;
|
|
result.Titles.Locales = [];
|
|
result.Descriptions.Locales = [];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Remove Only One Locale, and if there is one, Remove all ...
|
|
|
|
//
|
|
// Remove Title if Exists ...
|
|
isValid = await titleResourceProvider.HasLocale(
|
|
identifier: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
await titleResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
language: language,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Remove Description if Exists ...
|
|
isValid = await descriptionResourceProvider.HasLocale(
|
|
identifier: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
language: language,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Retrieve Resource ...
|
|
result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Has Locales ...
|
|
isValid = result.Titles.Locales.HasChild();
|
|
if (!isValid)
|
|
{
|
|
//
|
|
// Remove Item ...
|
|
await provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result.Titles.Locales = [];
|
|
result.Descriptions.Locales = [];
|
|
}
|
|
|
|
//
|
|
isValid = true;
|
|
}
|
|
|
|
//
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Send Push ...
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action:
|
|
result.Titles.Locales.HasChild()
|
|
? "DeleteLocale"
|
|
: XBaseEntityHubAction.Delete.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> Update(
|
|
int id,
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
id.IsValidIntId() &&
|
|
!item.IsNullOrDefault() &&
|
|
!language.IsNullOrEmpty() &&
|
|
!item.Title.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Category Exists ...
|
|
isValid = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Locale Exists ...
|
|
isValid = await HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Category Dto for Validate Owining ...
|
|
var dto = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid =
|
|
!dto.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
(IsOwned(
|
|
item: dto,
|
|
userInfo: userInfo
|
|
) || HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Exists Item Resource ...
|
|
var resource = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var titleUpdated = false;
|
|
var descriptionUpdated = false;
|
|
|
|
//
|
|
// Update Title ...
|
|
resource.Titles.Locales
|
|
.ToList()
|
|
.ForEach(tl =>
|
|
{
|
|
//
|
|
if (tl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
//
|
|
titleUpdated = true;
|
|
tl.Value = item.Title;
|
|
}
|
|
});
|
|
|
|
//
|
|
// Update Description ...
|
|
resource.Descriptions.Locales
|
|
.ToList()
|
|
.ForEach(dl =>
|
|
{
|
|
//
|
|
if (dl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
//
|
|
descriptionUpdated = true;
|
|
dl.Value = item.Description;
|
|
}
|
|
});
|
|
|
|
//
|
|
// Validate Title and Description Updated ...
|
|
isValid = titleUpdated && descriptionUpdated;
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
resource = await Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return resource;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> Refresh(
|
|
XCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid =
|
|
!resource.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
var isDelete = false;
|
|
XCategoryResourceDto result = null;
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
XCategoryDto dto =
|
|
(resource.Item.IsNullOrDefault() ||
|
|
!resource.Item.Id.IsValidIntId())
|
|
? null
|
|
: await Get(
|
|
id: resource.Item.Id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var isExists = !dto.IsNullOrDefault();
|
|
|
|
//
|
|
// Do Referesh Based on Existance ...
|
|
var isNew =
|
|
!isExists &&
|
|
(resource.Item.IsNullOrDefault() ||
|
|
!resource.Item.Id.IsValidIntId());
|
|
if (isNew)
|
|
{
|
|
//
|
|
// Add ...
|
|
// In this Senario, for Add a Category by Providing Resource
|
|
// the item must clean, either Title and Description, and tge Locales Provided by Resource
|
|
// ust Contains Values ...
|
|
// the Add Starts by Titles and only Items Add Which has Titles, since Title is Mandatory
|
|
// and Description is Optional ...
|
|
isValid =
|
|
//
|
|
// Resource ...
|
|
(resource.Item.IsNullOrDefault() ||
|
|
(!resource.Item.Id.IsValidIntId() &&
|
|
resource.Item.Title.IsNullOrEmpty() &&
|
|
resource.Item.Description.IsNullOrEmpty())) &&
|
|
//
|
|
// Titles ...
|
|
!resource.Titles.IsNullOrDefault() &&
|
|
resource.Titles.Locales.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Add Temp Category ...
|
|
var unique = Guid.NewGuid();
|
|
var temp = new XCategoryDto
|
|
{
|
|
Title = $"TmpT_{unique}",
|
|
Description = $"TmpD_{unique}",
|
|
};
|
|
temp = await provider.AddAsync(
|
|
item: temp,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!temp.IsNullOrDefault() &&
|
|
temp.Id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
id = temp.Id;
|
|
|
|
//
|
|
// Update Title and Description ...
|
|
var titleResource = titleResourceProvider.GetResourceTitle(id);
|
|
var descriptionResource = descriptionResourceProvider.GetResourceTitle(id);
|
|
temp.Title = titleResource;
|
|
temp.Description = descriptionResource;
|
|
temp = await provider.UpdateAsync(
|
|
id: id,
|
|
item: temp,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Loop through Titles ...
|
|
foreach (var locale in resource.Titles.Locales)
|
|
{
|
|
//
|
|
// Add Or Update Locale ...
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
locale: locale,
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var desLocale = resource.Descriptions.Locales.FirstOrDefault(
|
|
dl =>
|
|
dl.Language == locale.Language);
|
|
if (!desLocale.IsNullOrDefault())
|
|
{
|
|
//
|
|
// Add Descriptions ...
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: desLocale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else if (isExists)
|
|
{
|
|
//
|
|
// Re State ...
|
|
id = resource.Item.Id;
|
|
|
|
//
|
|
// Try to Refresh Resource State ...
|
|
|
|
//
|
|
// Check Delete ...
|
|
isDelete = !resource.Titles.Locales.HasChild();
|
|
if (isDelete)
|
|
{
|
|
//
|
|
// Handle Delete ...
|
|
await Remove(
|
|
id: id,
|
|
language: null,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Handle Update ...
|
|
result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
#region Remove ...
|
|
//
|
|
// Titles ...
|
|
var removeTitles = result.Titles.Locales.Where(
|
|
l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in removeTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
connectionId: null,
|
|
language: locale.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var removeDescriptions = result.Descriptions.Locales.Where(
|
|
l => !resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in removeDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
connectionId: null,
|
|
language: locale.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
//
|
|
// Titles ...
|
|
var updateTitles = result.Titles.Locales.Where(
|
|
l => resource.Titles.Locales.Any(r =>
|
|
r.Value
|
|
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
|
|
r.Language
|
|
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase)
|
|
)
|
|
);
|
|
foreach (var locale in updateTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var updateDescriptions = result.Descriptions.Locales.Where(
|
|
l => resource.Descriptions.Locales.Any(r =>
|
|
r.Value
|
|
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
|
|
r.Language
|
|
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in updateDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region New ...
|
|
//
|
|
// Titles ...
|
|
var newTitles = resource.Titles.Locales.Where(
|
|
l => !result.Titles.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in newTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var newDescriptions = resource.Descriptions.Locales.Where(
|
|
l => !result.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in newDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Action ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Get Result ...
|
|
result =
|
|
isDelete
|
|
? resource
|
|
: await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !result.IsNullOrDefault();
|
|
|
|
//
|
|
// Send Notification ...
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: isNew
|
|
? XBaseEntityHubAction.Add.GetStringValue()
|
|
: isDelete
|
|
? XBaseEntityHubAction.Delete.GetStringValue()
|
|
: XBaseEntityHubAction.Update.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async IAsyncEnumerable<XCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var enumerable = provider.GetAllAsAsyncEnumerable(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Id)
|
|
);
|
|
|
|
//
|
|
await foreach (var dto in enumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
var resource = await GetResource(
|
|
id: dto.Id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
yield return resource;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XCategoryResourceDto>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XCategoryResourceDto>();
|
|
|
|
//
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result.Add(item);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryResourceDto> FindOneResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
XCategoryResourceDto result = null;
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Detect Predicate Condition ...
|
|
isApproved = predicate.Compile()(item);
|
|
if (isApproved)
|
|
{
|
|
//
|
|
result = item;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XCategoryResourceDto>> FindManyResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
var result = new List<XCategoryResourceDto>();
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Detect Predicate Condition ...
|
|
isApproved = predicate.Compile()(item);
|
|
if (isApproved)
|
|
{
|
|
result.Add(item);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Apply Order ...
|
|
if (!orderBuilder.IsNull())
|
|
{
|
|
//
|
|
result =
|
|
orderBuilder(result.AsQueryable())
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XCategoryResourceDto>> QueryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize Query ...
|
|
query = query.NormalizeQuery(dataServiceConfiguration);
|
|
|
|
//
|
|
var items = await FindManyResource(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<XCategoryResourceDto>
|
|
{
|
|
Page = query.Page,
|
|
Items = [.. items],
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory References ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XCategoryDto> GetReference(
|
|
int providedForId,
|
|
int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetReference(
|
|
forIndex: forIndex,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XCategoryDto>> GetAllReferences(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XReference<int>>> GetAllReferencings(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.GetAllReferencings(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountReferences(
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XCategoryDto>> QueryReferences(
|
|
XQuery query,
|
|
int providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.QueryReferences(
|
|
query: query,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.AddReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XCategoryDto model,
|
|
XReference<int> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.AddReference(
|
|
model: model,
|
|
reference: reference,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XCategoryDto model,
|
|
XReference<int> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReference(
|
|
model: model,
|
|
reference: reference,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReferences(
|
|
int providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await categorySubCategoryReferenceProvider
|
|
.RemoveReferences(
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Models.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Completely Exported Service ...
|
|
/// </summary>
|
|
public class XCategoryService : IXCategoryService
|
|
{
|
|
private readonly IXCategoryProvider categoryProvider;
|
|
private readonly IXSubCategoryProvider subCategoryProvider;
|
|
|
|
public XCategoryService(
|
|
IXCategoryProvider categoryProvider,
|
|
IXSubCategoryProvider subCategoryProvider
|
|
)
|
|
{
|
|
this.categoryProvider = categoryProvider;
|
|
this.subCategoryProvider = subCategoryProvider;
|
|
}
|
|
|
|
//
|
|
#region Category Provider ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> CategoryHasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> GetCategoryResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> AddCategory(
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.Add(
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item by It's Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> AddCategoryResource(
|
|
XCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.AddResource(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> RemoveCategory(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.Remove(
|
|
id: id,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> UpdateCategory(
|
|
int id,
|
|
XCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.Update(
|
|
id: id,
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> RefreshCategory(
|
|
XCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XCategoryResourceDto>> GetAllCategoryResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.GetAllResources(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XCategoryResourceDto> FindOneCategoryResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.FindOneResource(
|
|
predicate: predicate,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XCategoryResourceDto>> FindManyCategoryResource(
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.FindManyResource(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<XCategoryResourceDto>> QueryCategoryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await categoryProvider
|
|
.QueryResources(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual IAsyncEnumerable<XCategoryResourceDto> GetAllCategoryResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return categoryProvider
|
|
.GetAllResourcesAsAsyncEnumerable(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region SubCategory Provider ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> SubCategoryHasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> GetSubCategoryResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> AddSubCategory(
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.Add(
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> AddSubCategoryResource(
|
|
XSubCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.AddResource(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> RemoveSubCategory(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.Remove(
|
|
id: id,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> UpdateSubCategory(
|
|
int id,
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.Update(
|
|
id: id,
|
|
item: item,
|
|
language: language,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> RefreshSubCategory(
|
|
XSubCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XSubCategoryResourceDto>> GetAllSubCategoryResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.GetAllResources(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XSubCategoryResourceDto> FindOneSubCategoryResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.FindOneResource(
|
|
predicate: predicate,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XSubCategoryResourceDto>> FindManySubCategoryResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.FindManyResource(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<XSubCategoryResourceDto>> QuerySubCategoryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await subCategoryProvider
|
|
.QueryResources(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual IAsyncEnumerable<XSubCategoryResourceDto> GetAllSubCategoryResourcesAsAsyncEnumerable(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return subCategoryProvider
|
|
.GetAllResourcesAsAsyncEnumerable(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategorySubCategoryReferenceProvider.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategorySubCategoryReferenceProvider : XBaseCategoryProvider<int>, IXCategorySubCategoryReferenceProvider
|
|
{
|
|
public XCategorySubCategoryReferenceProvider(
|
|
IXCategoryServiceProvider categoryProvider
|
|
) : base(
|
|
categoryProvider: categoryProvider,
|
|
providedFor: XCategoryServiceConstants.SubCategoryReference
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XCategoryTitleResourceProvider.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XCategoryTitleResourceProvider : XBaseItemResourceProvider, IXCategoryTitleResourceProvider
|
|
{
|
|
public XCategoryTitleResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XCategoryServiceConstants.CategoryTitleResourceIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XSubCategoryDescriptionResourceProvider.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XSubCategoryDescriptionResourceProvider : XBaseItemResourceProvider, IXSubCategoryDescriptionResourceProvider
|
|
{
|
|
public XSubCategoryDescriptionResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XCategoryServiceConstants.SubCategoryDescriptionResourceIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XSubCategoryEntityRegisterar.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCategoryService.Configurations.Entities;
|
|
using xCategoryService.Models.Entities;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XSubCategoryEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XSubCategoryEntityRegisterar()
|
|
: base(nameof(XSubCategoryEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XSubCategory, int>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XSubCategoryEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XSubCategoryProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Interfaces.Dtos;
|
|
using xCategoryService.Models.Dtos;
|
|
using xCategoryService.Models.Entities;
|
|
using xCategoryService.Providers.Dtos;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xDataService.Extensions;
|
|
using xPushService.Constants;
|
|
using xPushService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XSubCategoryProvider : XBaseProvided<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXSubCategoryProvider
|
|
{
|
|
private readonly XAppConfiguration appConfiguration;
|
|
private readonly IXCategoryProvider categoryProvider;
|
|
private readonly IXSubCategoryServiceProvider provider;
|
|
private readonly XDataServiceConfiguration dataServiceConfiguration;
|
|
private readonly IXSubCategoryTitleResourceProvider titleResourceProvider;
|
|
private readonly IXSubCategoryDescriptionResourceProvider descriptionResourceProvider;
|
|
|
|
public XSubCategoryProvider(
|
|
XAppConfiguration appConfiguration,
|
|
IXCategoryProvider categoryProvider,
|
|
IXSubCategoryServiceProvider provider,
|
|
XDataServiceConfiguration dataServiceConfiguration,
|
|
IXSubCategoryTitleResourceProvider titleResourceProvider,
|
|
IXSubCategoryDescriptionResourceProvider descriptionResourceProvider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.appConfiguration = appConfiguration;
|
|
this.categoryProvider = categoryProvider;
|
|
this.titleResourceProvider = titleResourceProvider;
|
|
this.dataServiceConfiguration = dataServiceConfiguration;
|
|
this.descriptionResourceProvider = descriptionResourceProvider;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
public override bool IsOwned(
|
|
XSubCategoryDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XSubCategory item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Check Has Specified Locale or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> HasLocale(
|
|
int id,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
id.IsValidIntId() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Resource ...
|
|
var resource = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Result ...
|
|
var result =
|
|
!resource.IsNullOrDefault() &&
|
|
resource.Titles.Locales
|
|
.Any(x => x.Language
|
|
.Equals(language, System.StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an Item by all of it's Related Translations ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> GetResource(
|
|
int id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var titleResource = await titleResourceProvider.GetResource(
|
|
identifier: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider.GetResource(
|
|
identifier: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Reading Category Resource ...
|
|
XCategoryResourceDto categoryResourceDto = null;
|
|
try
|
|
{
|
|
var categoryDto = await categoryProvider.GetReference(
|
|
providedForId: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!categoryDto.IsNullOrDefault())
|
|
{
|
|
categoryResourceDto = await categoryProvider.GetResource(
|
|
id: categoryDto.Id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
var result = new XSubCategoryResourceDto
|
|
{
|
|
Item = item,
|
|
Titles = titleResource,
|
|
Category = categoryResourceDto,
|
|
Descriptions = descriptionResource
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> Add(
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
language =
|
|
!language.IsNullOrEmpty()
|
|
? language
|
|
: appConfiguration.DefaultLanguage;
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
try
|
|
{
|
|
//
|
|
var title = item.Title;
|
|
var description = item.Description;
|
|
|
|
//
|
|
// Add Item Pure for ID Generating ...
|
|
item = await base.Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: null, // Since here We dont want notification ...
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
id = item.Id;
|
|
var titleResource = await titleResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = title,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = description,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Update Category Dto ...
|
|
item.Title = titleResource.Resource;
|
|
item.Description = descriptionResource.Resource;
|
|
item = await base.Update(
|
|
id: id,
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Id ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Category Resourv=ce ...
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Sending Push Notification ...
|
|
isValid =
|
|
isValid &&
|
|
!result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Item by it's Locales and Reference ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> AddResource(
|
|
XSubCategoryResourceDto item,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!item.IsNullOrDefault() &&
|
|
!item.Titles.IsNullOrDefault() &&
|
|
item.Titles.Locales.HasChild() &&
|
|
!item.Titles.Locales.Any(tl =>
|
|
tl.Value.IsNullOrEmpty() ||
|
|
tl.Language.IsNullOrEmpty());
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (item.Item.IsNullOrDefault())
|
|
{
|
|
item.Item = new XSubCategoryDto();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
try
|
|
{
|
|
//
|
|
// Handle Category Generation ...
|
|
if (!item.Category.IsNullOrDefault())
|
|
{
|
|
//
|
|
// Handle Category ...
|
|
try
|
|
{
|
|
// Try to Add Category ...
|
|
item.Category = await categoryProvider.Refresh(
|
|
resource: item.Category,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
// Add SubCategory for ID Generation ...
|
|
item.Item = await base.Add(
|
|
item: item.Item,
|
|
userInfo: userInfo,
|
|
connectionId: null, // Since here We dont want notification ...
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !item.Item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
id = item.Item.Id;
|
|
|
|
//
|
|
foreach (var il in item.Titles.Locales)
|
|
{
|
|
//
|
|
var title = il.Value;
|
|
var language = il.Language;
|
|
|
|
//
|
|
var descriptionItem =
|
|
item.Descriptions.IsNullOrDefault() ||
|
|
!item.Descriptions.Locales.HasChild()
|
|
? null
|
|
: item.Descriptions.Locales
|
|
.FirstOrDefault(ides =>
|
|
ides.Language
|
|
.Equals(
|
|
language,
|
|
StringComparison.InvariantCultureIgnoreCase));
|
|
var description =
|
|
descriptionItem.IsNullOrDefault()
|
|
? string.Empty
|
|
: descriptionItem.Value;
|
|
|
|
//
|
|
// Try to Add Resources ...
|
|
var titleResource = await titleResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = title,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var descriptionResource = await descriptionResourceProvider
|
|
.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: new XLocaleResourceDto
|
|
{
|
|
Value = description,
|
|
Language = language
|
|
},
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Update Category Dto if not ...
|
|
if (item.Item.Title.IsNullOrEmpty() ||
|
|
!item.Item.Title
|
|
.Equals(
|
|
titleResource.Resource,
|
|
StringComparison.InvariantCultureIgnoreCase)
|
|
)
|
|
{
|
|
//
|
|
item.Item.Title = titleResource.Resource;
|
|
item.Item.Description = descriptionResource.Resource;
|
|
item.Item = await base.Update(
|
|
id: id,
|
|
item: item.Item,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Id ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Add Resource Reference to Category ...
|
|
isValid = await categoryProvider.AddReference(
|
|
providedForId: id,
|
|
connectionId: null,
|
|
model: item.Category.Item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Retrieve Category Resourv=ce ...
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Sending Push Notification ...
|
|
isValid =
|
|
isValid &&
|
|
!result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="language">if null, Remove All</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> Remove(
|
|
int id,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
isValid = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Locale if Provided ...
|
|
isValid =
|
|
language.IsNullOrEmpty() ||
|
|
await HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Remove All ...
|
|
|
|
//
|
|
// Titles ...
|
|
await titleResourceProvider.RemoveLocales(
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Descriptions ...
|
|
await descriptionResourceProvider.RemoveLocales(
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Remove Entity ...
|
|
await provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
isValid = true;
|
|
result.Titles.Locales = [];
|
|
result.Descriptions.Locales = [];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Remove Only One Locale, and if there is one, Remove all ...
|
|
|
|
//
|
|
// Remove Title if Exists ...
|
|
isValid = await titleResourceProvider.HasLocale(
|
|
identifier: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
await titleResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
language: language,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Remove Description if Exists ...
|
|
isValid = await descriptionResourceProvider.HasLocale(
|
|
identifier: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
language: language,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Retrieve Resource ...
|
|
result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Has Locales ...
|
|
isValid = result.Titles.Locales.HasChild();
|
|
if (!isValid)
|
|
{
|
|
//
|
|
// Remove Item ...
|
|
await provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result.Titles.Locales = [];
|
|
result.Descriptions.Locales = [];
|
|
}
|
|
|
|
//
|
|
isValid = true;
|
|
}
|
|
|
|
//
|
|
// Remove all Referencings ...
|
|
if (isValid)
|
|
{
|
|
await categoryProvider.RemoveReferences(
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Send Push ...
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action:
|
|
result.Titles.Locales.HasChild()
|
|
? "DeleteLocale"
|
|
: XBaseEntityHubAction.Delete.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item for Specified Language ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> Update(
|
|
int id,
|
|
XSubCategoryDto item,
|
|
string language = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
id.IsValidIntId() &&
|
|
!item.IsNullOrDefault() &&
|
|
!language.IsNullOrEmpty() &&
|
|
!item.Title.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Category Exists ...
|
|
isValid = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Locale Exists ...
|
|
isValid = await HasLocale(
|
|
id: id,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Category Dto for Validate Owining ...
|
|
var dto = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid =
|
|
!dto.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
(IsOwned(
|
|
item: dto,
|
|
userInfo: userInfo
|
|
) || HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Exists Item Resource ...
|
|
var resource = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var titleUpdated = false;
|
|
var descriptionUpdated = false;
|
|
|
|
//
|
|
// Update Title ...
|
|
resource.Titles.Locales
|
|
.ToList()
|
|
.ForEach(tl =>
|
|
{
|
|
//
|
|
if (tl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
//
|
|
titleUpdated = true;
|
|
tl.Value = item.Title;
|
|
}
|
|
});
|
|
|
|
//
|
|
// Update Description ...
|
|
resource.Descriptions.Locales
|
|
.ToList()
|
|
.ForEach(dl =>
|
|
{
|
|
//
|
|
if (dl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
//
|
|
descriptionUpdated = true;
|
|
dl.Value = item.Description;
|
|
}
|
|
});
|
|
|
|
//
|
|
// Validate Title and Description Updated ...
|
|
isValid = titleUpdated && descriptionUpdated;
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
resource = await Refresh(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return resource;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh a Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> Refresh(
|
|
XSubCategoryResourceDto resource,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid =
|
|
!resource.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Permission ...
|
|
isValid = HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var id = -1;
|
|
var isDelete = false;
|
|
XSubCategoryResourceDto result = null;
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
XSubCategoryDto dto =
|
|
(resource.Item.IsNullOrDefault() ||
|
|
!resource.Item.Id.IsValidIntId())
|
|
? null
|
|
: await Get(
|
|
id: resource.Item.Id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var isExists = !dto.IsNullOrDefault();
|
|
|
|
//
|
|
// Do Referesh Based on Existance ...
|
|
var isNew =
|
|
!isExists &&
|
|
(resource.Item.IsNullOrDefault() ||
|
|
!resource.Item.Id.IsValidIntId());
|
|
if (isNew)
|
|
{
|
|
//
|
|
// Add ...
|
|
// In this Senario, for Add a Category by Providing Resource
|
|
// the item must clean, either Title and Description, and tge Locales Provided by Resource
|
|
// ust Contains Values ...
|
|
// the Add Starts by Titles and only Items Add Which has Titles, since Title is Mandatory
|
|
// and Description is Optional ...
|
|
isValid =
|
|
//
|
|
// Resource ...
|
|
(resource.Item.IsNullOrDefault() ||
|
|
(!resource.Item.Id.IsValidIntId() &&
|
|
resource.Item.Title.IsNullOrEmpty() &&
|
|
resource.Item.Description.IsNullOrEmpty())) &&
|
|
//
|
|
// Titles ...
|
|
!resource.Titles.IsNullOrDefault() &&
|
|
resource.Titles.Locales.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Add Temp Category ...
|
|
var unique = Guid.NewGuid();
|
|
var temp = new XSubCategoryDto
|
|
{
|
|
Title = $"TmpT_{unique}",
|
|
Description = $"TmpD_{unique}",
|
|
};
|
|
temp = await provider.AddAsync(
|
|
item: temp,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!temp.IsNullOrDefault() &&
|
|
temp.Id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
id = temp.Id;
|
|
|
|
//
|
|
// Update Title and Description ...
|
|
var titleResource = titleResourceProvider.GetResourceTitle(id);
|
|
var descriptionResource = descriptionResourceProvider.GetResourceTitle(id);
|
|
temp.Title = titleResource;
|
|
temp.Description = descriptionResource;
|
|
temp = await provider.UpdateAsync(
|
|
id: id,
|
|
item: temp,
|
|
saveChanges: true,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Loop through Titles ...
|
|
foreach (var locale in resource.Titles.Locales)
|
|
{
|
|
//
|
|
// Add Or Update Locale ...
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
locale: locale,
|
|
identifier: id,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var desLocale = resource.Descriptions.Locales.FirstOrDefault(
|
|
dl =>
|
|
dl.Language == locale.Language);
|
|
if (!desLocale.IsNullOrDefault())
|
|
{
|
|
//
|
|
// Add Descriptions ...
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: desLocale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else if (isExists)
|
|
{
|
|
//
|
|
// Re State ...
|
|
id = resource.Item.Id;
|
|
|
|
//
|
|
// Try to Refresh Resource State ...
|
|
|
|
//
|
|
// Check Delete ...
|
|
isDelete = !resource.Titles.Locales.HasChild();
|
|
if (isDelete)
|
|
{
|
|
//
|
|
// Handle Delete ...
|
|
await Remove(
|
|
id: id,
|
|
language: null,
|
|
userInfo: userInfo,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Handle Update ...
|
|
result = await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
#region Remove ...
|
|
//
|
|
// Titles ...
|
|
var removeTitles = result.Titles.Locales.Where(
|
|
l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in removeTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
connectionId: null,
|
|
language: locale.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var removeDescriptions = result.Descriptions.Locales.Where(
|
|
l => !resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in removeDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.RemoveLocale(
|
|
identifier: id,
|
|
connectionId: null,
|
|
language: locale.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
//
|
|
// Titles ...
|
|
var updateTitles = result.Titles.Locales.Where(
|
|
l => resource.Titles.Locales.Any(r =>
|
|
r.Value
|
|
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
|
|
r.Language
|
|
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase)
|
|
)
|
|
);
|
|
foreach (var locale in updateTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var updateDescriptions = result.Descriptions.Locales.Where(
|
|
l => resource.Descriptions.Locales.Any(r =>
|
|
r.Value
|
|
.Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) &&
|
|
r.Language
|
|
.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in updateDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region New ...
|
|
//
|
|
// Titles ...
|
|
var newTitles = resource.Titles.Locales.Where(
|
|
l => !result.Titles.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in newTitles)
|
|
{
|
|
//
|
|
await titleResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
var newDescriptions = resource.Descriptions.Locales.Where(
|
|
l => !result.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, StringComparison.InvariantCultureIgnoreCase))
|
|
);
|
|
foreach (var locale in newDescriptions)
|
|
{
|
|
//
|
|
await descriptionResourceProvider.AddOrUpdateLocale(
|
|
identifier: id,
|
|
locale: locale,
|
|
connectionId: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle Category ...
|
|
if (
|
|
!isDelete &&
|
|
(isNew || isExists) &&
|
|
!resource.Category.IsNullOrDefault())
|
|
{
|
|
//
|
|
// Refresh Category ...
|
|
var category = await categoryProvider.Refresh(
|
|
userInfo: userInfo,
|
|
resource: resource.Category,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Handle SubCategory Referencings ...
|
|
var references = await categoryProvider.GetAllReferences(
|
|
providedForId: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var hasReference =
|
|
references.HasChild() &&
|
|
references.Any(r => r.Id == category.Item.Id);
|
|
if (!hasReference)
|
|
{
|
|
await categoryProvider.AddReference(
|
|
providedForId: id,
|
|
model: category.Item,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Action ...
|
|
isValid = id.IsValidIntId();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Get Result ...
|
|
result =
|
|
isDelete
|
|
? resource
|
|
: await GetResource(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !result.IsNullOrDefault();
|
|
|
|
//
|
|
// Send Notification ...
|
|
if (isValid)
|
|
{
|
|
//
|
|
await provider.SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: isNew
|
|
? XBaseEntityHubAction.Add.GetStringValue()
|
|
: isDelete
|
|
? XBaseEntityHubAction.Delete.GetStringValue()
|
|
: XBaseEntityHubAction.Update.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async IAsyncEnumerable<XSubCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var enumerable = provider.GetAllAsAsyncEnumerable(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Id)
|
|
);
|
|
|
|
//
|
|
await foreach (var dto in enumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
var resource = await GetResource(
|
|
id: dto.Id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
yield return resource;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Resources ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XSubCategoryResourceDto>> GetAllResources(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XSubCategoryResourceDto>();
|
|
|
|
//
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result.Add(item);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find One Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XSubCategoryResourceDto> FindOneResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
XSubCategoryResourceDto result = null;
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Detect Predicate Condition ...
|
|
isApproved = predicate.Compile()(item);
|
|
if (isApproved)
|
|
{
|
|
//
|
|
result = item;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Resource ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XSubCategoryResourceDto>> FindManyResource(
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isApproved = false;
|
|
var result = new List<XSubCategoryResourceDto>();
|
|
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
|
await foreach (var item in enumerable)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Detect Predicate Condition ...
|
|
isApproved = predicate.Compile()(item);
|
|
if (isApproved)
|
|
{
|
|
result.Add(item);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Apply Order ...
|
|
if (!orderBuilder.IsNull())
|
|
{
|
|
//
|
|
result =
|
|
orderBuilder(result.AsQueryable())
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Resources by Query Pattern ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XSubCategoryResourceDto>> QueryResources(
|
|
XQuery query = null,
|
|
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
|
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize Query ...
|
|
query = query.NormalizeQuery(dataServiceConfiguration);
|
|
|
|
//
|
|
var items = await FindManyResource(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<XSubCategoryResourceDto>
|
|
{
|
|
Page = query.Page,
|
|
Items = [.. items],
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCategoryService\Providers\XSubCategoryTitleResourceProvider.cs
|
|
|
|
using xCategoryService.Constants;
|
|
using xCategoryService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
|
|
namespace xCategoryService.Providers
|
|
{
|
|
public class XSubCategoryTitleResourceProvider : XBaseItemResourceProvider, IXSubCategoryTitleResourceProvider
|
|
{
|
|
public XSubCategoryTitleResourceProvider(
|
|
IXStringServiceProvider stringProvider
|
|
) : base(
|
|
stringProvider: stringProvider,
|
|
item: XCategoryServiceConstants.SubCategoryTitleResourceIdentifier
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Attributes\RequireXPoweredAttribute.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCommons.Attributes {
|
|
public partial class RequireXPoweredAttribute : AuthorizeAttribute, IAuthorizationFilter {
|
|
|
|
private readonly bool ignoreAnonymous;
|
|
|
|
public RequireXPoweredAttribute (bool IgnoreAnonymous = true) {
|
|
ignoreAnonymous = IgnoreAnonymous;
|
|
}
|
|
|
|
public void OnAuthorization (AuthorizationFilterContext context) {
|
|
//
|
|
var config = context.GetXAppConfiguration ();
|
|
|
|
//
|
|
var isExistsXPowered = context.HttpContext.Request.Headers
|
|
.Any (h => h.Key
|
|
.ToNormalString () == XAuthorization.XPoweredBy.ToNormalString () &&
|
|
h.Value == config.XPoweredValue);
|
|
|
|
//
|
|
var isAnonymous = context.IsAnonymousAllowed ();
|
|
var handler = ignoreAnonymous ? isAnonymous ? false : true : true;
|
|
|
|
//
|
|
if (handler &&
|
|
!isExistsXPowered) {
|
|
context.Result = new UnauthorizedResult ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Authorization\RequiredRolesHandler.cs
|
|
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
namespace xCommons.Authorization {
|
|
public partial class RequiredRolesHandler : AuthorizationHandler<RequiredRolesRequirement> {
|
|
protected override Task HandleRequirementAsync (
|
|
AuthorizationHandlerContext context,
|
|
RequiredRolesRequirement requirement
|
|
) {
|
|
//
|
|
var conatinsRole = context.User.HasClaim (c => c.Type == JwtClaimTypes.Role);
|
|
if (!conatinsRole) {
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
//
|
|
var roleClaim = context.User.Claims.FirstOrDefault (c => c.Type == JwtClaimTypes.Role);
|
|
if (roleClaim == null ||
|
|
!requirement.Roles.Contains (roleClaim.Value)
|
|
) {
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
//
|
|
context.Succeed (requirement);
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Authorization\RequiredRolesRequirement.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
namespace xCommons.Authorization {
|
|
public partial class RequiredRolesRequirement : IAuthorizationRequirement {
|
|
public string[] Roles { get; }
|
|
public RequiredRolesRequirement (params string[] Roles) {
|
|
this.Roles = Roles;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Configurations\XAppConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace xCommons.Configurations {
|
|
/// <summary>
|
|
/// represent an xBackend Application
|
|
/// </summary>
|
|
public partial class XAppConfiguration {
|
|
public string Name { get; set; }
|
|
public string Version { get; set; }
|
|
public string XPoweredValue { get; set; }
|
|
public IEnumerable<string> AllowedOrigins { get; set; }
|
|
public string WelcomeMessage { get; set; }
|
|
public string DefaultLanguage { get; set; }
|
|
public XMessageResourceTitles MessageResourceTitles { get; set; }
|
|
}
|
|
|
|
public partial class XMessageResourceTitles {
|
|
public string Terms { get; set; }
|
|
public string Invite { get; set; }
|
|
public string RegistrationApprove { get; set; }
|
|
public string Registered { get; set; }
|
|
public string VerificationCode { get; set; }
|
|
public string ChangePassword { get; set; }
|
|
public string PasswordChanged { get; set; }
|
|
public string NewDeviceLoggedIn { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Configurations\XSwaggerConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace xCommons.Configurations {
|
|
public partial class XSwaggerConfiguration {
|
|
public string Title { get; set; } = "";
|
|
public string Version { get; set; } = "V1.0";
|
|
public string Description { get; set; } = "";
|
|
public string TermsOfServiceUrl { get; set; } = "";
|
|
|
|
public XSwaggerContact Contact { get; set; } = null;
|
|
public XSwaggerLicence License { get; set; } = null;
|
|
public Dictionary<string, string> DefaultValues {get; set;} = null;
|
|
}
|
|
|
|
public partial class XSwaggerContact {
|
|
public string Name { get; set; }
|
|
public string Email { get; set; }
|
|
public string Url { get; set; }
|
|
}
|
|
|
|
public partial class XSwaggerLicence {
|
|
public string Name { get; set; }
|
|
public string Url { get; set; }
|
|
}
|
|
|
|
public partial class XSwaggerDefaultValues
|
|
{
|
|
public Dictionary<string, string> Values { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\CommonConstants.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial class CommonConstants {
|
|
public static char DEFAULT_LIST_SEPERATOR = ',';
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string CERTIFICATES_NODE = "Certificates";
|
|
public const string SWAGGER_NODE = "SwaggerConfiguration";
|
|
public const string MESSAGE_RESOURCE_TITLES_NODE = "MessageResourceTitles";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XAuthentication.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial struct XAuthentication {
|
|
public const string JWT = "jwt";
|
|
public const string BEARER = "Bearer";
|
|
public const string TOKEN = "token";
|
|
public const string INTROSPECTION = "introspection";
|
|
public const string IDENTITY_SERVER_LOCAL_API = "IdentityServerAccessToken";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XAuthorization.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial struct XAuthorization {
|
|
public const string TokenIdentifier = "Bearer ";
|
|
public const string Header = "Authorization";
|
|
public const string AccessToken = "access_token";
|
|
public const string RefreshToken = "refresh_token";
|
|
public const string ExpiresAt = "expires_at";
|
|
public const string AccessTokenExpired = "AccessToken-Expired";
|
|
public const string RevisionChecksum = "revision_checksum";
|
|
public const string XPoweredBy = "X-PoweredBy";
|
|
public const int ThresholdBeforeTokenExpiration = 600;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XCustomClaims.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial struct XCustomClaims {
|
|
public const string IsEnabled = "is_enabled";
|
|
public const string IsBanned = "is_banned";
|
|
public const string Issuer = "iss";
|
|
public const string ExpiredOn = "exp";
|
|
public const string Audience = "aud";
|
|
public const string ClientId = "client_id";
|
|
public const string AuthenticatedOn = "auth_time";
|
|
public const string UserId = "sub";
|
|
public const string UserName = "unique_name";
|
|
public const string FirstName = "given_name";
|
|
public const string LastName = "family_name";
|
|
public const string Gender = "gender";
|
|
public const string Picture = "picture";
|
|
public const string BrithDate = "birthdate";
|
|
public const string Bio ="bio";
|
|
public const string CoverImage = "cover_image";
|
|
public const string OpenToSearch = "open_to_search";
|
|
public const string Email = "email";
|
|
public const string EmailVerified = "email_verified";
|
|
public const string PhoneNumber = "phone_number";
|
|
public const string PhoneNumberVerified = "phone_number_verified";
|
|
public const string Role = "role";
|
|
public const string Scope = "scope";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XDeviceType.cs
|
|
|
|
namespace xCommons.Constants {
|
|
/// <summary>
|
|
/// a collection of available Client Devices
|
|
/// </summary>
|
|
public enum XDeviceType {
|
|
Unknown,
|
|
Mobile,
|
|
Tablet,
|
|
Desktop
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XFileType.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public enum XFileType {
|
|
Image,
|
|
ProfileImasge,
|
|
CoverImage,
|
|
Audio,
|
|
Video,
|
|
Document
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Constants\XPolicy.cs
|
|
|
|
namespace xCommons.Constants {
|
|
public partial struct XPolicy {
|
|
public const string AllowedOrigins = "AllowedOrigins";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Controllers\XBaseApiController.cs
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
|
|
namespace xCommons.Controllers {
|
|
/// <summary>
|
|
/// Base Api Controller
|
|
/// </summary>
|
|
[ApiController]
|
|
[RequireXPowered(true)]
|
|
[Route("api/[controller]")]
|
|
[Produces("application/json")]
|
|
public abstract partial class XBaseApiController : XBaseController
|
|
{
|
|
protected XBaseApiController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Controllers\XBaseApiV1Controller.cs
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
|
|
namespace xCommons.Controllers {
|
|
/// <summary>
|
|
/// Base Api V1 Controller
|
|
/// </summary>
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[RequireXPowered(true)]
|
|
[Route("api/v{version:apiVersion}/[controller]")]
|
|
public abstract partial class XBaseApiV1Controller : XBaseApiController
|
|
{
|
|
protected XBaseApiV1Controller(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Controllers\XBaseController.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xCommons.Controllers {
|
|
/// <summary>
|
|
/// Base Controller
|
|
/// </summary>
|
|
[Route ("[controller]")]
|
|
[Produces ("application/json")]
|
|
public abstract partial class XBaseController : ControllerBase {
|
|
public ILogger Logger { get; }
|
|
public XAppConfiguration AppConfiguration { get; }
|
|
public XValidationProvider ValidationProvider { get; }
|
|
|
|
protected XBaseController (
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) {
|
|
Logger = logger;
|
|
AppConfiguration = appConfiguration;
|
|
ValidationProvider = validationProvider;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check the Controller Up and Running
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet]
|
|
[Route ("Test/Hi")]
|
|
[AllowAnonymous]
|
|
public virtual IActionResult Hi () {
|
|
//
|
|
var controllerName = GetControllerName ();
|
|
var message = $"{controllerName} Controller is Up and running ...";
|
|
|
|
//
|
|
return Ok (message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Controller ByPass XPowered Filter
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet]
|
|
[AllowAnonymous]
|
|
[RequireXPowered (false)]
|
|
[Route ("Test/PassRequireXPowered")]
|
|
public virtual IActionResult PassRequireXPowered () {
|
|
//
|
|
var controllerName = GetControllerName ();
|
|
var message = $"{controllerName} Controller bypass RequiredXPowered and Up and running ...";
|
|
|
|
//
|
|
return Ok (message);
|
|
}
|
|
|
|
//
|
|
#region Non Actions ...
|
|
/// <summary>
|
|
/// Convert an Exception to Propper Error Result
|
|
/// </summary>
|
|
/// <param name="ex"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public ActionResult GetExceptionActionResult (Exception ex) {
|
|
//
|
|
var exception = GetExceptionResult (ex);
|
|
var error = ex.Message.ToXError ();
|
|
|
|
//
|
|
Logger.LogError ($"exception: {exception}, error: {error}");
|
|
|
|
//
|
|
try {
|
|
var xError = exception.Message.ToXError ();
|
|
var xException = (XException) xError.Id;
|
|
|
|
//
|
|
switch (xException) {
|
|
//
|
|
case XException.NotFound:
|
|
return NotFound (error);
|
|
|
|
//
|
|
case XException.NotAuthorized:
|
|
return Unauthorized ();
|
|
}
|
|
} catch { }
|
|
|
|
//
|
|
return BadRequest (error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Structured Exception
|
|
/// </summary>
|
|
/// <param name="ex"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public Exception GetExceptionResult (Exception ex) {
|
|
//
|
|
// Log Exception Message ...
|
|
Logger.LogError (ex.Message);
|
|
|
|
//
|
|
// if Happens Exception is Know Error
|
|
// catch it and return it in BadRequest Container ...
|
|
var isEr = ex.Message.IsXError ();
|
|
|
|
//
|
|
if (isEr) {
|
|
return ex;
|
|
}
|
|
|
|
//
|
|
// if catched Exception Contains Unknown Error
|
|
// return an Unknown Error ...
|
|
return XException.Unknown.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve ControllerName
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public string GetControllerName () {
|
|
return this.ControllerContext.RouteData.Values["controller"].ToString ();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\DI\XDIHelperExtension.cs
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Providers;
|
|
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Register XCommons Module Services
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
public static void AddXCommons (this IServiceCollection services) {
|
|
services.AddSingleton<XValidationProvider> ();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\CertificateExtensions.cs
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
using xCommons.Constants;
|
|
using xCommons.Models;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static partial class CertificateExtensions {
|
|
/// <summary>
|
|
/// Retrieve Specific Certificate From app Settings
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
public static XCertificate GetCertificate (this IConfiguration configuration, string name) {
|
|
//
|
|
var certificatesSection = configuration.GetSection (ConfigurationNodeNames.CERTIFICATES_NODE);
|
|
var certificateSection = certificatesSection.GetSection (name);
|
|
var certificate = certificateSection.Get<XCertificate> ();
|
|
|
|
//
|
|
return certificate;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\CommonExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using System.Xml;
|
|
using AutoMapper;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using Newtonsoft.Json.Serialization;
|
|
using xCommons.Constants;
|
|
using xCommons.Helpers;
|
|
using xExceptions.Attributes;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xCommons.Extensions
|
|
{
|
|
public static partial class CommonExtensions
|
|
{
|
|
/// <summary>
|
|
/// Conert XMLNode to String ...
|
|
/// </summary>
|
|
/// <param name="node"></param>
|
|
/// <param name="indentation"></param>
|
|
/// <returns></returns>
|
|
public static string ToString(this XmlNode node, int indentation = 2)
|
|
{
|
|
//
|
|
using (var sw = new StringWriter())
|
|
{
|
|
//
|
|
using (var xw = new XmlTextWriter(sw))
|
|
{
|
|
xw.Formatting = System.Xml.Formatting.Indented;
|
|
xw.Indentation = indentation;
|
|
node.WriteContentTo(xw);
|
|
}
|
|
|
|
//
|
|
return sw.ToString();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a Json String to Dictionary of String Mappings
|
|
/// </summary>
|
|
/// <param name="source">Json String</param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> JSONToDictionary(this string source)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeObject<Dictionary<string, string>>(source);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert properties of specific Class instance to Dictionary ...
|
|
/// </summary>
|
|
/// <param name="source">class instance</param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> ToDictionary<T>(this T source) where T : class
|
|
{
|
|
//
|
|
var result = new Dictionary<string, string>();
|
|
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
PropertyInfo[] propertyInfos = source.GetType().GetProperties();
|
|
if (!propertyInfos.HasChild())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
foreach (PropertyInfo propertyInfo in propertyInfos)
|
|
{
|
|
result.Add(
|
|
propertyInfo.Name,
|
|
propertyInfo
|
|
.GetValue(source, null)
|
|
.ToString()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// run specific task and retrieve result ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
public static void RunTask(this Task source)
|
|
{
|
|
source.
|
|
GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
/// <summary>
|
|
/// run specific task and retrieve result ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
public static T RunTask<T>(this Task<T> source)
|
|
{
|
|
return source.
|
|
GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert XML String to Json Object ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToJSON(this string source)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
try
|
|
{
|
|
//
|
|
result = XMLToJSONHelper.ToJSON(source);
|
|
|
|
//
|
|
// Handle Removing Additional Values ...
|
|
result = result.Replace("s:", "").Replace("a:", "");
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert object to Json ...
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static string ToJSON<T>(this T value)
|
|
where T : class
|
|
{
|
|
//
|
|
if (value.IsNull())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
var setting = new JsonSerializerSettings
|
|
{
|
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|
PreserveReferencesHandling = PreserveReferencesHandling.None
|
|
};
|
|
|
|
//
|
|
return JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.None, setting);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert to Json With Support of Camel Casing
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="camelCase"></param>
|
|
/// <returns></returns>
|
|
public static string ToJSON<T>(this T value, bool camelCase = false)
|
|
{
|
|
//
|
|
if (value.IsNull())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
var setting = new JsonSerializerSettings
|
|
{
|
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|
PreserveReferencesHandling = PreserveReferencesHandling.None,
|
|
};
|
|
|
|
//
|
|
if (camelCase)
|
|
{
|
|
setting.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
|
}
|
|
|
|
//
|
|
return JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.None, setting);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Map to Dynamic Object ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static dynamic ToDynamicObject(this string source)
|
|
{
|
|
return JsonConvert.DeserializeObject(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Map to Dynamic Object ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static dynamic ToDynamicObject(this object source)
|
|
{
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b => { });
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
return dMapper.Map<dynamic>(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse From Dynamic Object ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T FromDynamicObject<T>(this object source)
|
|
where T : class
|
|
{
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b => { });
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
dynamic dSource = source;
|
|
|
|
//
|
|
return dMapper.Map<T>(dSource);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Type of Object to Safe Type
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T ConvertTo<T>(this object source)
|
|
{
|
|
//
|
|
T result = default(T);
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
T item = (T)Convert.ChangeType(source, typeof(T));
|
|
|
|
//
|
|
result = item;
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an Instance to another Instance
|
|
/// using AutoMapper dynamic Convertion
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T MapConvert<T>(this T source)
|
|
where T : class
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dSource = (object)source.ToDynamicObject();
|
|
return dSource.FromDynamicObject<T>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Using Auto Mapper ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="E"></typeparam>
|
|
/// <returns></returns>
|
|
public static T MapConvert<T, E>(this E source)
|
|
where T : class
|
|
where E : class
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b =>
|
|
{
|
|
b.CreateMap<T, E>()
|
|
.ReverseMap();
|
|
});
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
var dSource = (object)dMapper.Map<dynamic>(source);
|
|
var result = dMapper.Map<T>(dSource);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Using Auto Mapper ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="E"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> MapConvert<T, E>(this IEnumerable<E> source)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b =>
|
|
{
|
|
b.CreateMap<T, E>()
|
|
.ReverseMap();
|
|
});
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
var dSource = (object)dMapper.Map<dynamic>(source);
|
|
var result = dMapper.Map<IEnumerable<T>>(dSource);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Using Auto Mapper ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="E"></typeparam>
|
|
/// <returns></returns>
|
|
public static ICollection<T> MapConvert<T, E>(this ICollection<E> source)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b =>
|
|
{
|
|
b.CreateMap<T, E>()
|
|
.ReverseMap();
|
|
});
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
var dSource = (object)dMapper.Map<dynamic>(source);
|
|
var result = dMapper.Map<ICollection<T>>(dSource);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Using Auto Mapper ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="E"></typeparam>
|
|
/// <returns></returns>
|
|
public static IList<T> MapConvert<T, E>(this IList<E> source)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b =>
|
|
{
|
|
b.CreateMap<T, E>()
|
|
.ReverseMap();
|
|
});
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
var dSource = (object)dMapper.Map<dynamic>(source);
|
|
var result = dMapper.Map<IList<T>>(dSource);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Using Auto Mapper ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TDest"></typeparam>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <returns></returns>
|
|
public static IDictionary<TKey, TDest> MapConvert<TKey, TDest, TSource>(this IDictionary<TKey, TSource> source)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var dMapConfig = new MapperConfiguration(b =>
|
|
{
|
|
b.CreateMap<TDest, TSource>()
|
|
.ReverseMap();
|
|
});
|
|
var dMapper = dMapConfig.CreateMapper();
|
|
|
|
//
|
|
var dSource = (object)dMapper.Map<dynamic>(source);
|
|
var result = dMapper.Map<IDictionary<TKey, TDest>>(dSource);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a Type to Static Type
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T ToStatic<T>(this object source)
|
|
{
|
|
//
|
|
var entity = Activator.CreateInstance<T>();
|
|
|
|
//
|
|
var properties = source as IDictionary<string, object>;
|
|
|
|
//
|
|
if (properties == null)
|
|
{
|
|
return entity;
|
|
}
|
|
|
|
//
|
|
foreach (var entry in properties)
|
|
{
|
|
//
|
|
var propertyInfo = entity.GetType().GetProperty(entry.Key);
|
|
if (propertyInfo != null)
|
|
{
|
|
propertyInfo.SetValue(entity, entry.Value, null);
|
|
}
|
|
}
|
|
|
|
//
|
|
return entity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert From Json String ...
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T FromJSON<T>(this string value)
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert From Json String ...
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public static object FromJSON(
|
|
this string value,
|
|
Type type
|
|
)
|
|
{
|
|
return JsonConvert
|
|
.DeserializeObject(value, type);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search a Json String for Specific Node ...
|
|
/// </summary>
|
|
/// <param name="containerToken"></param>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
public static List<JToken> FindTokens(this JToken containerToken, string name)
|
|
{
|
|
List<JToken> matches = new List<JToken>();
|
|
FindTokens(containerToken, name, matches);
|
|
return matches;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert to MD5 Bytes ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static byte[] ToMd5Bytes(this string source)
|
|
{
|
|
return new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(source));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert to MD5 String ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToMd5String(this string source)
|
|
{
|
|
//
|
|
// string representation (similar to UNIX format)
|
|
return BitConverter.ToString(source.ToMd5Bytes())
|
|
// without dashes
|
|
.Replace("-", string.Empty)
|
|
// make lowercase
|
|
.ToLower();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a String is MD5 String or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsMD5String(this string source)
|
|
{
|
|
//
|
|
if (String.IsNullOrEmpty(source))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return Regex.IsMatch(source, "^[0-9a-fA-F]{32}$", RegexOptions.Compiled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an string to Byte array Representation ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static byte[] ToBytes(this string source)
|
|
{
|
|
return Encoding.UTF8.GetBytes(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts Byte Array to String Value ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string FromBytes(this byte[] source)
|
|
{
|
|
//
|
|
var result = Encoding.UTF8.GetString(source, 0, source.Length);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check object is Null ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsNull(this object source)
|
|
{
|
|
return source == null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check collection Has Childs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool HasChild<T>(this IList<T> source)
|
|
{
|
|
return !source.IsNull() && source.Count() > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check collection Has Childs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool HasChild<T>(this ICollection<T> source)
|
|
{
|
|
return !source.IsNull() && source.Count() > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check collection Has Childs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool HasChild<T>(this IEnumerable<T> source)
|
|
{
|
|
return !source.IsNull() && source.Count() > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select Async ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="method"></param>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
public static async Task<IEnumerable<TResult>> SelectAsync<TSource, TResult>(
|
|
this IEnumerable<TSource> source, Func<TSource, Task<TResult>> method
|
|
)
|
|
{
|
|
return await Task.WhenAll(source.Select(async s => await method(s)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an Enumerable to Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(
|
|
this IEnumerable<T> source,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
foreach (var item in source)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
yield return item;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an Stream to Model AsyncEnumerator ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async IAsyncEnumerable<T> ToModelAsyncEnumerable<T>(
|
|
this Stream source,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Stream ...
|
|
if (source.IsNull())
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
while (source.CanRead)
|
|
{
|
|
//
|
|
var model = await source
|
|
.ReadModelFromStream<T>(cancellationToken);
|
|
|
|
//
|
|
yield return model;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an Stream to String AsyncEnumerator ...
|
|
/// using Read Line of Stream Reader ...S
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async IAsyncEnumerable<string> ToStringAsyncEnumerable(
|
|
this Stream source,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Stream ...
|
|
if (source.IsNull())
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
while (source.CanRead)
|
|
{
|
|
//
|
|
var json = await source
|
|
.ReadJsonFromStream(cancellationToken);
|
|
|
|
//
|
|
yield return json;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a Model to Stream ...
|
|
/// </summary>
|
|
/// <param name="source">an Stream to Write ...</param>
|
|
/// <param name="model">a Model instance to Write ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async Task WriteModelToStream<T>(
|
|
this Stream source,
|
|
T model,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull() || model.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Extract Json of Model ...
|
|
var json = model.ToJSON(true);
|
|
|
|
//
|
|
await source.WriteJsonToStream(
|
|
json: json,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a Json String to Stream ...
|
|
/// </summary>
|
|
/// <param name="source">an Stream to Write ...</param>
|
|
/// <param name="json">json string to write ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async Task WriteJsonToStream(
|
|
this Stream source,
|
|
string json,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull() || json.IsNullOrEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
using (var streamWriter = new StreamWriter(stream: source))
|
|
{
|
|
//
|
|
using (var jsonWriter = new JsonTextWriter(streamWriter))
|
|
{
|
|
//
|
|
await jsonWriter.WriteRawAsync(json, cancellationToken);
|
|
await jsonWriter.FlushAsync(cancellationToken);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a Json Model From Stream ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async Task<T> ReadModelFromStream<T>(
|
|
this Stream source,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
T result = default(T);
|
|
|
|
//
|
|
var json = await source.ReadJsonFromStream(cancellationToken);
|
|
if (!json.IsNullOrEmpty())
|
|
{
|
|
//
|
|
try
|
|
{
|
|
result = json.FromJSON<T>();
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reading Json String From Stream ...
|
|
/// </summary>
|
|
/// <param name="source">an Stream to Write ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async Task<string> ReadJsonFromStream(
|
|
this Stream source,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
using (var streamReader = new StreamReader(source))
|
|
{
|
|
//
|
|
result = await Task.Run(() =>
|
|
{
|
|
return streamReader.ReadLine();
|
|
},
|
|
cancellationToken);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection item ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sourceItem"></param>
|
|
/// <param name="updateWith"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IList<T> Update<T>(
|
|
this IList<T> source,
|
|
T sourceItem,
|
|
T updateWith
|
|
)
|
|
{
|
|
//
|
|
var result = new List<T>();
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (!source.HasChild() ||
|
|
updateWith.IsNull() ||
|
|
sourceItem.IsNull()
|
|
)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Item from source ...
|
|
result = source
|
|
.Except(new List<T>() { sourceItem })
|
|
.ToList();
|
|
result.Add(updateWith);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection item ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sourceItem"></param>
|
|
/// <param name="updateWith"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static ICollection<T> Update<T>(
|
|
this ICollection<T> source,
|
|
T sourceItem,
|
|
T updateWith
|
|
)
|
|
{
|
|
//
|
|
var result = new List<T>();
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (!source.HasChild() ||
|
|
updateWith.IsNull() ||
|
|
sourceItem.IsNull()
|
|
)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Item from source ...
|
|
result = source
|
|
.Except(new List<T>() { sourceItem })
|
|
.ToList();
|
|
result.Add(updateWith);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection item ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sourceItem"></param>
|
|
/// <param name="updateWith"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> Update<T>(
|
|
this IEnumerable<T> source,
|
|
T sourceItem,
|
|
T updateWith
|
|
)
|
|
{
|
|
//
|
|
var result = new List<T>();
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (!source.HasChild() ||
|
|
updateWith.IsNull() ||
|
|
sourceItem.IsNull()
|
|
)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Item from source ...
|
|
result = source
|
|
.Except(new List<T>() { sourceItem })
|
|
.ToList();
|
|
result.Add(updateWith);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select and Retrieve Nth Childs of given List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="n"></param>
|
|
/// <param name="throwException"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> GetNthItems<T>(this IList<T> source, int n, bool throwException = false)
|
|
{
|
|
//
|
|
var result = new List<T>();
|
|
if (n < 1 || n > source.Count || source.IsNull() || !source.HasChild())
|
|
{
|
|
if (throwException)
|
|
{
|
|
throw XException.InvalidArgs.ToException();
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
var index = 0;
|
|
foreach (var item in source)
|
|
{
|
|
//
|
|
result.Add(item);
|
|
index++;
|
|
|
|
//
|
|
if (index >= n)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select and Retrieve Nth Childs of given List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="n"></param>
|
|
/// <param name="throwException"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> GetNthItems<T>(this ICollection<T> source, int n, bool throwException = false)
|
|
{
|
|
return source.ToList().GetNthItems(
|
|
n: n,
|
|
throwException: throwException
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select and Retrieve Nth Childs of given List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="n"></param>
|
|
/// <param name="throwException"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> GetNthItems<T>(this IEnumerable<T> source, int n, bool throwException = false)
|
|
{
|
|
return source.ToList().GetNthItems(
|
|
n: n,
|
|
throwException: throwException
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is Null or Empty ...
|
|
/// </summary>
|
|
/// <param name="sourse"></param>
|
|
/// <returns></returns>
|
|
public static bool IsNullOrEmpty(this string sourse)
|
|
{
|
|
return string.IsNullOrEmpty(sourse);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get string Value Attribute of an Enum ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetStringValue(this Enum source)
|
|
{
|
|
var type = source.GetType();
|
|
var fieldInfo = type.GetField(source.ToString());
|
|
var attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
|
|
|
|
return attributes != null && attributes.Length > 0 ?
|
|
attributes[0].StringValue : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extracts digit's of an string ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetDigits(this string source)
|
|
{
|
|
try
|
|
{
|
|
//
|
|
Regex regexObj = new Regex(@"[^\d]");
|
|
return regexObj.Replace(source, "");
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is contains only digits ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsDigits(this string source)
|
|
{
|
|
return (source.GetDigits() != null &&
|
|
source.GetDigits().ToString() == source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert to normal string, Trim and ToLower ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToNormalString(this string source)
|
|
{
|
|
//
|
|
if (source.IsNullOrEmpty())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
return source.Trim().ToLowerInvariant();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Capitalize an string ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string Capitalize(this string source)
|
|
{
|
|
//
|
|
if (source.IsNullOrEmpty())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
var result = "";
|
|
if (source.Length > 1)
|
|
{
|
|
//
|
|
var firstCharr = source.Substring(0, 1);
|
|
var otherParts = source.Substring(1, source.Length - 1);
|
|
|
|
//
|
|
result = firstCharr.ToUpperInvariant() + otherParts;
|
|
}
|
|
else
|
|
{
|
|
result = source.ToUpperInvariant();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Summarize a Text ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="maxAllowedLength"></param>
|
|
/// <param name="endsWith"></param>
|
|
/// <returns></returns>
|
|
public static string SummarizeContent(
|
|
this string source,
|
|
int maxAllowedLength = 0,
|
|
string endsWith = ""
|
|
)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
if (source.IsNullOrEmpty() || maxAllowedLength <= 0)
|
|
{
|
|
//
|
|
result = source;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Pattern of Links ...
|
|
var pattern = @"(?:[!]\[(.*?)\]\(.*?\))";
|
|
|
|
//
|
|
// Apply Summarization ...
|
|
|
|
//
|
|
// Replace Markdown Links using RegExp ...
|
|
result = Regex.Replace(source, pattern, "");
|
|
|
|
//
|
|
// Do Summarization if Length bigger than MaxLength ...
|
|
if (result.Length > maxAllowedLength)
|
|
{
|
|
result = result.Substring(0, maxAllowedLength);
|
|
}
|
|
|
|
//
|
|
// Apply EndsWith if Provided ...
|
|
if (!endsWith.IsNullOrEmpty() &&
|
|
!result.EndsWith(endsWith))
|
|
{
|
|
result += endsWith;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is a Valid Representation of PhoneNumber ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValidMobileNumber(this string source)
|
|
{
|
|
//
|
|
// Validating Mobile Numbers ...
|
|
var phoneNumberUtil = PhoneNumbers.PhoneNumberUtil.GetInstance();
|
|
try
|
|
{
|
|
//
|
|
var mPhoneNumber = phoneNumberUtil.Parse(source, null);
|
|
if (phoneNumberUtil.IsValidNumber(mPhoneNumber))
|
|
{
|
|
//
|
|
return true;
|
|
}
|
|
|
|
//
|
|
return false;
|
|
}
|
|
catch
|
|
{
|
|
|
|
//
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is Valid Representation of Email Address ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValidEmail(this string source)
|
|
{
|
|
try
|
|
{
|
|
var addr = new System.Net.Mail.MailAddress(source);
|
|
return addr.Address == source;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is Valid Representation of URL Address ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValidUrl(this string url)
|
|
{
|
|
return Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute);
|
|
}
|
|
|
|
/// <summary>
|
|
/// check a URL has / at the end, if not add one ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <returns></returns>
|
|
public static string NormalizeUrl(this string url)
|
|
{
|
|
return url.EndsWith("/") ? url : url + "/";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an string is GUID or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsGuid(this string source)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNullOrEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
Guid guid;
|
|
var result = Guid.TryParse(source, out guid);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specific Guid string is Default Guid or not ...
|
|
/// </summary>
|
|
/// <param name="guid"></param>
|
|
/// <returns></returns>
|
|
public static bool IsDefaultGuid(this string guid)
|
|
{
|
|
//
|
|
if (!guid.IsGuid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var empty = Guid.Empty.ToString();
|
|
return guid == empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specific Guid is Default Guid or not ...
|
|
/// </summary>
|
|
/// <param name="guid"></param>
|
|
/// <returns></returns>
|
|
public static bool IsDefaultGuid(this Guid guid)
|
|
{
|
|
//
|
|
var empty = Guid.Empty;
|
|
return guid == empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse an String to related Enumerable Items ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ParseListString<T>(
|
|
this string source,
|
|
char? separator = null
|
|
)
|
|
{
|
|
//
|
|
if (!separator.HasValue)
|
|
{
|
|
separator = CommonConstants.DEFAULT_LIST_SEPERATOR;
|
|
}
|
|
|
|
//
|
|
var list = source.Split(separator.Value);
|
|
var result = new Collection<T>();
|
|
|
|
//
|
|
foreach (var s in list)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
T item = (T)Convert.ChangeType(s, typeof(T));
|
|
|
|
//
|
|
result.Add(item);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a List String Representation to GUid List ...
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="separator"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<Guid> ParseListGuid(
|
|
this string list,
|
|
char? separator = null
|
|
)
|
|
{
|
|
//
|
|
var result = new List<Guid>();
|
|
|
|
//
|
|
if (!separator.HasValue)
|
|
{
|
|
separator = CommonConstants.DEFAULT_LIST_SEPERATOR;
|
|
}
|
|
|
|
//
|
|
if (list.IsNullOrEmpty())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var items = list.Split(separator.Value);
|
|
items.ToList().ForEach(i =>
|
|
{
|
|
//
|
|
if (!i.IsNullOrEmpty() && i.IsGuid() && !i.IsDefaultGuid())
|
|
{
|
|
//
|
|
var gID = new Guid(i);
|
|
result.Add(gID);
|
|
}
|
|
});
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a List to List String ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static string ToListString<T>(
|
|
this IEnumerable<T> source,
|
|
char? separator = null
|
|
)
|
|
{
|
|
//
|
|
if (!separator.HasValue)
|
|
{
|
|
separator = CommonConstants.DEFAULT_LIST_SEPERATOR;
|
|
}
|
|
|
|
//
|
|
if (!source.HasChild())
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
string result = String.Join(
|
|
separator
|
|
.ToString(),
|
|
source
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// get default value of a Type
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T Default<T>(this T source)
|
|
where T : class
|
|
{
|
|
return default(T);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if an object is Null or Default Value
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool IsNullOrDefault<T>(this T source)
|
|
where T : class
|
|
{
|
|
return Equals(source, default(T));
|
|
}
|
|
|
|
/// <summary>
|
|
/// convert a timestamp to ISO String representation ...
|
|
/// </summary>
|
|
/// <param name="timestamp"></param>
|
|
/// <returns></returns>
|
|
public static string ISODateString(this long timestamp)
|
|
{
|
|
//
|
|
var time = timestamp.FromTimestamp();
|
|
var result = time.ToString("o");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a DateTime to Unix Like Long ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static long ToTimestamp(
|
|
this DateTime source
|
|
)
|
|
{
|
|
return new DateTimeOffset(source)
|
|
.ToUnixTimeMilliseconds();
|
|
}
|
|
|
|
/// <summary>
|
|
/// convert timestamp to DateTime ...
|
|
/// </summary>
|
|
/// <param name="timestamp"></param>
|
|
/// <returns></returns>
|
|
public static DateTime FromTimestamp(this long timestamp)
|
|
{
|
|
//
|
|
var result = DateTimeOffset.FromUnixTimeMilliseconds(timestamp);
|
|
return result.DateTime;
|
|
}
|
|
public static DateTime FromTimestamp(this string source)
|
|
{
|
|
//
|
|
var timestamp = Int64.Parse(source);
|
|
var time = timestamp.FromTimestamp();
|
|
return time;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Date Time is Expired or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsExPired(this DateTime source)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//
|
|
var currentDate = DateTime.UtcNow;
|
|
var isExpired = currentDate >= source;
|
|
|
|
//
|
|
return isExpired;
|
|
}
|
|
public static bool IsExpired(this long source)
|
|
{
|
|
var time = source.FromTimestamp();
|
|
return time.IsExPired();
|
|
}
|
|
public static bool IsExpired(this string source)
|
|
{
|
|
//
|
|
var time = DateTime.Parse(source);
|
|
return time.IsExPired();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a File Type is Image Kind or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsImageKind(this XFileType source)
|
|
{
|
|
//
|
|
var imageKind = new Collection<XFileType>() {
|
|
XFileType.Image,
|
|
XFileType.CoverImage,
|
|
XFileType.ProfileImasge
|
|
};
|
|
|
|
//
|
|
return imageKind.Contains(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Encode String as Url
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToUrlEncoded(this string source)
|
|
{
|
|
return HttpUtility.UrlEncode(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decode Url String
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToUrlDecoded(this string source)
|
|
{
|
|
return HttpUtility.UrlDecode(source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an Object to string for use in HttpParams
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="cultureInfo"></param>
|
|
/// <returns></returns>
|
|
public static string ToHttpParamString(this object value, CultureInfo cultureInfo)
|
|
{
|
|
//
|
|
if (value is Enum)
|
|
{
|
|
//
|
|
string name = Enum.GetName(value.GetType(), value);
|
|
if (name != null)
|
|
{
|
|
//
|
|
var field = IntrospectionExtensions
|
|
.GetTypeInfo(value.GetType())
|
|
.GetDeclaredField(name);
|
|
|
|
//
|
|
if (field != null)
|
|
{
|
|
//
|
|
var attribute = CustomAttributeExtensions
|
|
.GetCustomAttribute(field, typeof(EnumMemberAttribute))
|
|
as EnumMemberAttribute;
|
|
|
|
//
|
|
if (attribute != null)
|
|
{
|
|
return attribute.Value != null ? attribute.Value : name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (value is bool)
|
|
{
|
|
return System.Convert.ToString(value, cultureInfo).ToLowerInvariant();
|
|
}
|
|
else if (value is byte[])
|
|
{
|
|
return System.Convert.ToBase64String((byte[])value);
|
|
}
|
|
else if (value != null && value.GetType().IsArray)
|
|
{
|
|
//
|
|
var array = Enumerable.OfType<object>((Array)value);
|
|
return string.Join(",", Enumerable
|
|
.Select(
|
|
array,
|
|
o => o.ToHttpParamString(cultureInfo)));
|
|
}
|
|
|
|
//
|
|
return System.Convert.ToString(value, cultureInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// ReShape an Object as HttpParam String
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static string AsHttpParamString(this object value)
|
|
{
|
|
return System.Uri
|
|
.EscapeDataString(value
|
|
.ToHttpParamString(CultureInfo.InvariantCulture));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculating Date Difference Provider String
|
|
/// and Generate Date based on UTC Time in Milliseconds like unix Date ...
|
|
/// </summary>
|
|
/// <param name="offsetProvider"></param>
|
|
/// <returns></returns>
|
|
public static long GenerateDateTimeOffset(this string offsetProvider)
|
|
{
|
|
//
|
|
if (offsetProvider.IsNullOrEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
var mExpireValue = 0;
|
|
var mExpireValueStr = offsetProvider.GetDigits();
|
|
var mExpireUnit = offsetProvider.Replace(mExpireValueStr, "");
|
|
if (mExpireValueStr.IsNullOrEmpty() || mExpireUnit.IsNullOrEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
var isParsed = int.TryParse(mExpireValueStr, out mExpireValue);
|
|
if (!isParsed)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
DateTime? date = null;
|
|
switch (mExpireUnit)
|
|
{
|
|
case "d":
|
|
date = DateTime.UtcNow.AddDays(mExpireValue);
|
|
break;
|
|
|
|
case "h":
|
|
date = DateTime.UtcNow.AddHours(mExpireValue);
|
|
break;
|
|
|
|
case "m":
|
|
date = DateTime.UtcNow.AddMinutes(mExpireValue);
|
|
break;
|
|
|
|
case "s":
|
|
date = DateTime.UtcNow.AddSeconds(mExpireValue);
|
|
break;
|
|
|
|
case "ms":
|
|
default:
|
|
date = DateTime.UtcNow.AddMilliseconds(mExpireValue);
|
|
break;
|
|
}
|
|
|
|
//
|
|
var result = !date.HasValue ? 0 : new DateTimeOffset(date.Value)
|
|
.ToUnixTimeMilliseconds();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Int Id Extensions ...
|
|
public static bool IsValidIntId(this int source)
|
|
{
|
|
return source > 0;
|
|
}
|
|
|
|
public static void ValidateIntId(this int source)
|
|
{
|
|
//
|
|
if (!source.IsValidIntId())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region StringExtensions for Identity Server ...
|
|
public static string EnsureTrailingSlash(this string input)
|
|
{
|
|
if (!input.EndsWith("/"))
|
|
{
|
|
return input + "/";
|
|
}
|
|
|
|
return input;
|
|
}
|
|
|
|
public static bool IsMissing(this string value)
|
|
{
|
|
return string.IsNullOrWhiteSpace(value);
|
|
}
|
|
|
|
public static bool IsPresent(this string value)
|
|
{
|
|
return !string.IsNullOrWhiteSpace(value);
|
|
}
|
|
|
|
public static string Sha256(this string input)
|
|
{
|
|
if (input.IsMissing()) return string.Empty;
|
|
|
|
using (var sha = SHA256.Create())
|
|
{
|
|
var bytes = Encoding.UTF8.GetBytes(input);
|
|
var hash = sha.ComputeHash(bytes);
|
|
|
|
return Convert.ToBase64String(hash);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
|
|
{
|
|
if (containerToken.Type == JTokenType.Object)
|
|
{
|
|
foreach (JProperty child in containerToken.Children<JProperty>())
|
|
{
|
|
if (child.Name == name)
|
|
{
|
|
matches.Add(child.Value);
|
|
}
|
|
FindTokens(child.Value, name, matches);
|
|
}
|
|
}
|
|
else if (containerToken.Type == JTokenType.Array)
|
|
{
|
|
foreach (JToken child in containerToken.Children())
|
|
{
|
|
FindTokens(child, name, matches);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\DIExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.OpenApi.Models;
|
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
|
using xCommons.Configurations;
|
|
using xCommons.Constants;
|
|
using xCommons.Filters;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static partial class DIExtensions {
|
|
|
|
/// <summary>
|
|
/// Inject Specific Registered Service from IServiceCollection
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T GetRegisteredService<T> (this IServiceCollection source) {
|
|
//
|
|
var serviceProvider = source.BuildServiceProvider ();
|
|
return serviceProvider.GetService<T> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register App Configuration as a Service
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXAppConfiguration (this IServiceCollection services, IConfiguration configuration) {
|
|
//
|
|
var appConfiguration = configuration.GetXAppConfiguration ();
|
|
services.AddSingleton<XAppConfiguration> (appConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Required OperationFilters and Authorization Fields to Swagger Options
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="xmlFilePath"></param>
|
|
/// <param name="addRequiredXPoweredFilter"></param>
|
|
/// <param name="addXTokenAuthorization"></param>
|
|
/// <param name="addDefaultValueFilter"></param>
|
|
public static void AddXSwaggerGenOptions (
|
|
this SwaggerGenOptions source,
|
|
string xmlFilePath = null,
|
|
bool addRequiredXPoweredFilter = true,
|
|
bool addXTokenAuthorization = true,
|
|
bool addDefaultValueFilter = true
|
|
) {
|
|
//
|
|
if (source.IsNull ()) {
|
|
source = new SwaggerGenOptions ();
|
|
}
|
|
|
|
//
|
|
// Add Xml File Path ...
|
|
if (!xmlFilePath.IsNullOrEmpty ()) {
|
|
source.IncludeXmlComments (xmlFilePath);
|
|
}
|
|
|
|
//
|
|
// Handle RequireXPowered Filter ...
|
|
if (addRequiredXPoweredFilter) {
|
|
source.OperationFilter<RequireXPoweredOperationFilter> ();
|
|
}
|
|
|
|
//
|
|
// Add Default Values Filter ...
|
|
if (addDefaultValueFilter) {
|
|
source.OperationFilter<SwaggerDefaultValuesOperationFilter> ();
|
|
}
|
|
|
|
//
|
|
// Handle XToken Authorizations ...
|
|
if (addXTokenAuthorization) {
|
|
//
|
|
#region Bearer AccessToken ...
|
|
//
|
|
source.AddSecurityDefinition (nameof (XAuthorization.AccessToken), new OpenApiSecurityScheme {
|
|
In = ParameterLocation.Header,
|
|
Description = "Bearer token",
|
|
Type = SecuritySchemeType.ApiKey,
|
|
Name = XAuthorization.Header
|
|
});
|
|
|
|
//
|
|
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
|
{
|
|
new OpenApiSecurityScheme {
|
|
Reference = new OpenApiReference {
|
|
Id = nameof (XAuthorization.AccessToken),
|
|
Type = ReferenceType.SecurityScheme
|
|
}
|
|
}, Array.Empty<string> ()
|
|
}
|
|
});
|
|
#endregion
|
|
|
|
//
|
|
#region RefreshToken ...
|
|
//
|
|
source.AddSecurityDefinition (nameof (XAuthorization.RefreshToken), new OpenApiSecurityScheme {
|
|
In = ParameterLocation.Header,
|
|
Description = "refresh token",
|
|
Type = SecuritySchemeType.ApiKey,
|
|
Name = nameof (XAuthorization.RefreshToken)
|
|
});
|
|
|
|
//
|
|
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
|
{
|
|
new OpenApiSecurityScheme {
|
|
Reference = new OpenApiReference {
|
|
Id = nameof (XAuthorization.RefreshToken),
|
|
Type = ReferenceType.SecurityScheme
|
|
}
|
|
}, Array.Empty<string> ()
|
|
}
|
|
});
|
|
#endregion
|
|
|
|
//
|
|
#region ExpiresAt ...
|
|
//
|
|
source.AddSecurityDefinition (nameof (XAuthorization.ExpiresAt), new OpenApiSecurityScheme {
|
|
In = ParameterLocation.Header,
|
|
Description = "expires at",
|
|
Type = SecuritySchemeType.ApiKey,
|
|
Name = nameof (XAuthorization.ExpiresAt)
|
|
});
|
|
|
|
//
|
|
source.AddSecurityRequirement (new OpenApiSecurityRequirement {
|
|
{
|
|
new OpenApiSecurityScheme {
|
|
Reference = new OpenApiReference {
|
|
Id = nameof (XAuthorization.ExpiresAt),
|
|
Type = ReferenceType.SecurityScheme
|
|
}
|
|
}, Array.Empty<string> ()
|
|
}
|
|
});
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Swagger
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="settings"></param>
|
|
/// <param name="xmlFilePath"></param>
|
|
/// <param name="addRequiredXPoweredFilter"></param>
|
|
/// <param name="addXTokenAuthorization"></param>
|
|
/// <param name="addDefaultValueFilter"></param>
|
|
public static void AddXSwagger (
|
|
this IServiceCollection source,
|
|
IConfiguration configuration,
|
|
SwaggerGenOptions settings = null,
|
|
string xmlFilePath = null,
|
|
bool addRequiredXPoweredFilter = true,
|
|
bool addXTokenAuthorization = true,
|
|
bool addDefaultValueFilter = true
|
|
) {
|
|
//
|
|
var xSwaggerConfig = configuration.GetXSwaggerConfiguration ();
|
|
if (xSwaggerConfig.IsNull ()) {
|
|
xSwaggerConfig = new XSwaggerConfiguration ();
|
|
}
|
|
|
|
//
|
|
source.AddSingleton(xSwaggerConfig);
|
|
|
|
//
|
|
#region Prepare SwaggerGenOptions ...
|
|
if (settings.IsNull ()) {
|
|
settings = new SwaggerGenOptions ();
|
|
}
|
|
settings.AddXSwaggerGenOptions (
|
|
xmlFilePath: xmlFilePath,
|
|
addDefaultValueFilter: addDefaultValueFilter,
|
|
addXTokenAuthorization: addXTokenAuthorization,
|
|
addRequiredXPoweredFilter: addRequiredXPoweredFilter
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Prepare Swagger Doc ...
|
|
//
|
|
// Api Document Section ...
|
|
var apiDoc = new OpenApiInfo {
|
|
Title = xSwaggerConfig.Title,
|
|
Version = xSwaggerConfig.Version,
|
|
Description = xSwaggerConfig.Description,
|
|
};
|
|
|
|
//
|
|
// Api Document TermsOfUse URL ...
|
|
if (!xSwaggerConfig.TermsOfServiceUrl.IsNullOrEmpty ()) {
|
|
apiDoc.TermsOfService = new Uri (xSwaggerConfig.TermsOfServiceUrl);
|
|
}
|
|
|
|
//
|
|
// Contact Section ...
|
|
if (!xSwaggerConfig.Contact.IsNull ()) {
|
|
//
|
|
var apiContact = new OpenApiContact {
|
|
Name = xSwaggerConfig.Contact.Name,
|
|
Email = xSwaggerConfig.Contact.Email
|
|
};
|
|
|
|
//
|
|
// Contact URL ...
|
|
if (!xSwaggerConfig.Contact.Url.IsNullOrEmpty ()) {
|
|
apiContact.Url = new Uri (xSwaggerConfig.Contact.Url);
|
|
}
|
|
|
|
//
|
|
apiDoc.Contact = apiContact;
|
|
}
|
|
|
|
//
|
|
// License Section ...
|
|
if (!xSwaggerConfig.License.IsNull ()) {
|
|
//
|
|
var apiLicense = new OpenApiLicense {
|
|
Name = xSwaggerConfig.License.Name,
|
|
};
|
|
|
|
//
|
|
// License URL ...
|
|
if (!xSwaggerConfig.License.Url.IsNullOrEmpty ()) {
|
|
apiLicense.Url = new Uri (xSwaggerConfig.License.Url);
|
|
}
|
|
|
|
//
|
|
apiDoc.License = apiLicense;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Register Swagger ...
|
|
source.AddSwaggerGen (
|
|
opt => {
|
|
//
|
|
opt.UpdateData (settings);
|
|
|
|
//
|
|
opt.SwaggerDoc ("v1", apiDoc);
|
|
}
|
|
);
|
|
|
|
//
|
|
// Register Swagger Operation Filters ...
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Sagger
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="options"></param>
|
|
public static void UseXSwagger (
|
|
this IApplicationBuilder source,
|
|
SwaggerUIOptions options = null
|
|
) {
|
|
//
|
|
source.UseSwagger ();
|
|
|
|
//
|
|
if (options.IsNull ()) {
|
|
source.UseSwaggerUI ();
|
|
} else {
|
|
source.UseSwaggerUI (options: options);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Cross Origin Resource Sharings
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="allowedOrigins"></param>
|
|
public static void AddXCors (
|
|
this IServiceCollection source,
|
|
IEnumerable<string> allowedOrigins
|
|
) {
|
|
//
|
|
if (!allowedOrigins.HasChild ()) {
|
|
//
|
|
Console.WriteLine ($"XCommons: there is no provided allowedOrigins, start app without any specific cors, this may be unsecure ...");
|
|
|
|
//
|
|
source.AddCors (options => {
|
|
options.AddPolicy (XPolicy.AllowedOrigins,
|
|
builder => {
|
|
builder
|
|
.AllowAnyOrigin ()
|
|
.AllowAnyHeader ()
|
|
.AllowAnyMethod ()
|
|
.WithExposedHeaders ("*");
|
|
});
|
|
});
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
source.AddCors (options => {
|
|
options.AddPolicy (XPolicy.AllowedOrigins,
|
|
builder => {
|
|
builder
|
|
.WithOrigins (allowedOrigins.ToArray ())
|
|
.AllowAnyHeader ()
|
|
.AllowAnyMethod ()
|
|
.AllowCredentials ()
|
|
.WithExposedHeaders ("*");
|
|
});
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use X Registered Cross Origin Resource Sharings
|
|
/// </summary>
|
|
/// <param name="sources"></param>
|
|
public static void UseXCors (this IApplicationBuilder sources) {
|
|
//
|
|
sources.UseCors (XPolicy.AllowedOrigins);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Api V1 Versioning ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
public static void AddXApiV1Versioning(this IServiceCollection services)
|
|
{
|
|
//
|
|
// Register Api Versioning ...
|
|
services.AddApiVersioning(opt =>
|
|
{
|
|
//
|
|
// Set Default Api Version ...
|
|
opt.DefaultApiVersion = new ApiVersion(1, 0);
|
|
|
|
//
|
|
// Set Routing to Default API Version, if Version unspecified ...
|
|
opt.AssumeDefaultVersionWhenUnspecified = true;
|
|
|
|
//
|
|
// Report All Available Api Versions on Response ...
|
|
opt.ReportApiVersions = true;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\EnumExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static partial class EnumExtensions {
|
|
public static string GetKey (this Enum source) {
|
|
return Enum.GetName (source.GetType (), source);
|
|
}
|
|
|
|
public static T GetValue<T> (this string source) {
|
|
return (T) Enum.Parse (typeof (T), source);
|
|
}
|
|
|
|
public static void Iterate<T> (this IEnumerator<T> source, Action<T> action) {
|
|
//
|
|
while (source.MoveNext ()) {
|
|
//
|
|
var current = source.Current;
|
|
action (current);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\ExceptionExtensions.cs
|
|
|
|
using System;
|
|
using xExceptions.Constants;
|
|
using xExceptions.Models;
|
|
|
|
namespace xCommons.Extensions {
|
|
/// <summary>
|
|
/// this is an extension pack for Exceptions
|
|
/// </summary>
|
|
public static partial class ExceptionExtensions {
|
|
|
|
/// <summary>
|
|
/// determines an string contains an XError content or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsXError (this string source) {
|
|
//
|
|
if (source.IsNullOrEmpty ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var xError = source.ToXError ();
|
|
if (xError != null) {
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// If Convert Proccess fails ...
|
|
var normalString = source.ToNormalString ();
|
|
|
|
//
|
|
// Return result based on string values ...
|
|
return normalString.Contains ("id") && normalString.Contains ("message");
|
|
}
|
|
|
|
/// <summary>
|
|
/// deserialize an string to to XError class instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XError ToXError (this string source) {
|
|
//
|
|
if (source.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
try {
|
|
//
|
|
var err = source.FromJSON<XError> ();
|
|
|
|
//
|
|
// if err is null we have to manually get value
|
|
if (err == null) {
|
|
//
|
|
var normalString = source.ToNormalString ();
|
|
var parts = normalString.Split (',');
|
|
if (parts.Length > 2) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var idContainer = parts[0];
|
|
var messageContainer = parts[1];
|
|
}
|
|
|
|
//
|
|
return err;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static XError ToXError (this XException source) {
|
|
//
|
|
var errorId = (int) source;
|
|
var errorMessage = source.GetStringValue ();
|
|
|
|
//
|
|
return new XError {
|
|
Id = errorId,
|
|
Message = errorMessage
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an XError instance to an Exception
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Exception ToException (this XError source) {
|
|
//
|
|
var jsonStr = source.ToJSON ();
|
|
return new Exception (jsonStr);
|
|
}
|
|
|
|
public static Exception ToException (this XException source) {
|
|
return source
|
|
.ToXError ()
|
|
.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an Exception to corresponding XError Object
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XError FromException (this Exception source) {
|
|
//
|
|
if (source == null || source.Message.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return source.Message.ToXError ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Content to Contentable XException member and return XError Object
|
|
/// </summary>
|
|
/// <param name="exception"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static XError AddContentToError (this XException exception, string value) {
|
|
//
|
|
var xError = exception.ToXError ();
|
|
xError.Message = string.Format (xError.Message, value);
|
|
|
|
//
|
|
return xError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Content to Contentable XException member and return Exception Object
|
|
/// </summary>
|
|
/// <param name="exception"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Exception AddContentToException (this XException exception, string value) {
|
|
//
|
|
var xError = exception.ToXError ();
|
|
xError.Message = string.Format (xError.Message, value);
|
|
|
|
//
|
|
return xError.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throw Specific Exception ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="content"></param>
|
|
public static void Throw (
|
|
this XException source,
|
|
string content = null
|
|
) {
|
|
//
|
|
Exception exception = null;
|
|
if (content.IsNullOrEmpty ()) {
|
|
exception = source.ToException ();
|
|
} else {
|
|
exception = source.AddContentToException (content);
|
|
}
|
|
|
|
//
|
|
throw exception;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\FilterExtensions.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using xCommons.Configurations;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static partial class FilterExtensions {
|
|
public static XAppConfiguration GetXAppConfiguration (this ActionExecutingContext source) {
|
|
//
|
|
var services = source.HttpContext.RequestServices;
|
|
return (XAppConfiguration) services.GetService (typeof (XAppConfiguration));
|
|
}
|
|
|
|
public static XAppConfiguration GetXAppConfiguration (this AuthorizationFilterContext source) {
|
|
//
|
|
var services = source.HttpContext.RequestServices;
|
|
return (XAppConfiguration) services.GetService (typeof (XAppConfiguration));
|
|
}
|
|
|
|
public static bool IsAnonymousAllowed (this AuthorizationFilterContext source) {
|
|
//
|
|
var result = source.Filters
|
|
.Any (f => f.GetType () == typeof (AllowAnonymousFilter)) ||
|
|
source.ActionDescriptor.FilterDescriptors
|
|
.Any (f => f.GetType () == typeof (AllowAnonymousFilter)) ||
|
|
source.ActionDescriptor.EndpointMetadata
|
|
.Any (f => f.GetType () == typeof (AllowAnonymousAttribute));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\IConfigurationExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.Extensions.Configuration;
|
|
using xCommons.Configurations;
|
|
using xCommons.Constants;
|
|
|
|
namespace xCommons.Extensions
|
|
{
|
|
public static partial class IConfigurationExtensions
|
|
{
|
|
/// <summary>
|
|
/// Retrieve AppConfiguration from Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XAppConfiguration GetXAppConfiguration(this IConfiguration source)
|
|
{
|
|
//
|
|
var xMessageResourceTitlesConfigSection = source
|
|
.GetSection(ConfigurationNodeNames.MESSAGE_RESOURCE_TITLES_NODE);
|
|
|
|
//
|
|
var result = new XAppConfiguration
|
|
{
|
|
Name = source[nameof(XAppConfiguration.Name)],
|
|
Version = source[nameof(XAppConfiguration.Version)],
|
|
XPoweredValue = source[nameof(XAppConfiguration.XPoweredValue)],
|
|
WelcomeMessage = source[nameof(XAppConfiguration.WelcomeMessage)],
|
|
AllowedOrigins = source
|
|
.GetSection(nameof(XAppConfiguration.AllowedOrigins))
|
|
.Get<IEnumerable<string>>(),
|
|
DefaultLanguage = source[nameof(XAppConfiguration.DefaultLanguage)],
|
|
MessageResourceTitles = xMessageResourceTitlesConfigSection
|
|
.Get<XMessageResourceTitles>()
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Swagger Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XSwaggerConfiguration GetXSwaggerConfiguration(this IConfiguration source)
|
|
{
|
|
//
|
|
var xSwaggerConfigSection = source
|
|
.GetSection(ConfigurationNodeNames.SWAGGER_NODE);
|
|
return xSwaggerConfigSection.Get<XSwaggerConfiguration>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a ConfigurationSection to object Representation ...
|
|
/// </summary>
|
|
/// <param name="section"></param>
|
|
/// <returns></returns>
|
|
public static object ToObject(this IConfigurationSection section)
|
|
{
|
|
//
|
|
// an Inner Function for Create Recursive Parsing ...
|
|
object ConvertSection(IConfigurationSection sec)
|
|
{
|
|
//
|
|
var children = sec
|
|
.GetChildren()
|
|
.ToList();
|
|
if (!children.Any())
|
|
{
|
|
return sec.Value ?? string.Empty;
|
|
}
|
|
|
|
//
|
|
// Detect Array Like Sections ...
|
|
bool isArray = children.All(ch => int.TryParse(ch.Key, out _));
|
|
if (isArray)
|
|
{
|
|
//
|
|
return children
|
|
.OrderBy(c => int.Parse(c.Key))
|
|
.Select(ConvertSection)
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
// Otherwise ...
|
|
return children
|
|
.ToDictionary(
|
|
c => c.Key,
|
|
c => ConvertSection(c)
|
|
);
|
|
}
|
|
|
|
//
|
|
// Try to Parse using Inner Function ...
|
|
var result = ConvertSection(section);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a ConfigurationSection to Json Representation ...
|
|
/// </summary>
|
|
/// <param name="section"></param>
|
|
/// <returns></returns>
|
|
public static string ToJSON(this IConfigurationSection section)
|
|
{
|
|
//
|
|
// Try to Parse using Inner Function ...
|
|
var obj = section.ToObject();
|
|
|
|
//
|
|
// Convert it to Json ...
|
|
var result = obj.ToJSON();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Configuration Section as Object ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="section"></param>
|
|
/// <returns></returns>
|
|
public static object GetSectionAsObject(
|
|
this IConfiguration source,
|
|
string section
|
|
)
|
|
{
|
|
//
|
|
object result = null;
|
|
|
|
//
|
|
if (!section.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var sec = source.GetSection(section);
|
|
if (!sec.IsNull())
|
|
{
|
|
result = sec.ToObject();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Configuration Section as Json String ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="section"></param>
|
|
/// <returns></returns>
|
|
public static string GetSectionAsJson(
|
|
this IConfiguration source,
|
|
string section
|
|
)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
// Retrieve Secion as Object ...
|
|
var obj = source.GetSectionAsObject(section);
|
|
if (!obj.IsNull())
|
|
{
|
|
//
|
|
// Converts Section Object to Json ...
|
|
result = obj.ToJSON();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\IFormFileExtensions.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UglyToad.PdfPig;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xAiModels.Extensions
|
|
{
|
|
public static class IFormFileExtensions
|
|
{
|
|
/// <summary>
|
|
/// Read a IFormFile Content as byte array ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async Task<byte[]> ReadAsBytes(
|
|
this IFormFile source,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Create and use a Memory Stream ...
|
|
using var stream = new MemoryStream();
|
|
|
|
//
|
|
// Copy File Content to Stream ...
|
|
await source.CopyToAsync(
|
|
target: stream,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Read Stream Content as byte array ...
|
|
var result = stream.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a File Content by it's Path as byte array ...
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <param name="bufferSize"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
public static async Task<byte[]> ReadAsBytes(
|
|
this string filePath,
|
|
int bufferSize = 81920,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
{
|
|
throw new Exception("Invalid Args ...");
|
|
}
|
|
|
|
//
|
|
// Create and use a Memory Stream ...
|
|
using var memStream = new MemoryStream();
|
|
|
|
//
|
|
using var stream = new FileStream(
|
|
path: filePath,
|
|
mode: FileMode.Open,
|
|
access: FileAccess.Read,
|
|
share: FileShare.ReadWrite
|
|
);
|
|
|
|
//
|
|
// Copy File Content to Stream ...
|
|
await stream.CopyToAsync(
|
|
destination: memStream,
|
|
bufferSize: bufferSize,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Read Stream Content as byte array ...
|
|
var result = memStream.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read Text Content of Document ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async Task<string> ReadContent(
|
|
this IFormFile source,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check if File PDF or not ...
|
|
var isPDF = source.ContentType
|
|
.ToNormalString()
|
|
.Contains("pdf"
|
|
.ToNormalString());
|
|
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
var isValidFileType = isPDF;
|
|
if (!isValidFileType)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (isPDF)
|
|
{
|
|
//
|
|
// Reading File Content as Byte array ...
|
|
var fileBytes = await source.ReadAsBytes(cancellationToken);
|
|
|
|
//
|
|
// Create a PDF Document ...
|
|
using var stream = new MemoryStream(fileBytes);
|
|
using var document = PdfDocument.Open(stream);
|
|
|
|
//
|
|
// Extract PDF Text ...
|
|
var textBuilder = new StringBuilder();
|
|
foreach (var page in document.GetPages())
|
|
{
|
|
textBuilder.Append(page.Text);
|
|
}
|
|
|
|
//
|
|
result = textBuilder.ToString();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\ModelExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
|
|
namespace xCommons.Extensions
|
|
{
|
|
public static partial class ModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Retrieve a Binding Flag for Retrieve all Instance Members including
|
|
/// Priate and Public ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static BindingFlags GetDefaultBindingFlag()
|
|
{
|
|
return BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Instance of a Typed Object with Data Provided by another Instance of Typed Object
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="updateWith"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="propertyValueProviders"></param>
|
|
/// <param name="updateWithNullOrEmptyValues"></param>
|
|
/// <param name="throwExceptionOnFails"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="D"></typeparam>
|
|
/// <returns></returns>
|
|
public static T UpdateData<T, D>(
|
|
this T source,
|
|
D updateWith,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<D, object>>> propertyValueProviders = null,
|
|
bool updateWithNullOrEmptyValues = false,
|
|
bool throwExceptionOnFails = false
|
|
)
|
|
where T : class
|
|
where D : class
|
|
{
|
|
//
|
|
var hasWhiteList = propertyWhiteList.HasChild<string>();
|
|
var hasBlackList = propertyBlackList.HasChild<string>();
|
|
var hasValueProvider = propertyValueProviders.HasChild<KeyValuePair<string, Func<D, object>>>();
|
|
|
|
//
|
|
var fullPropertyList = updateWith.GetType().GetProperties().Select(prop => prop.Name);
|
|
var mustSetProps = (hasWhiteList ? propertyWhiteList : fullPropertyList);
|
|
|
|
//
|
|
if (hasBlackList)
|
|
{
|
|
mustSetProps = mustSetProps.Where(propName => !propertyBlackList.Contains(propName));
|
|
}
|
|
|
|
//
|
|
mustSetProps.ToList().ForEach(propName =>
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var sourceProp = source.GetType().GetProperty(propName);
|
|
var sourceValue = sourceProp.GetValue(source);
|
|
var sourceValueType = sourceValue.IsNull() ? null : sourceValue.GetType();
|
|
|
|
//
|
|
var updateWithProp = updateWith.GetType().GetProperty(propName);
|
|
var updateWithValue = updateWithProp.GetValue(updateWith);
|
|
var updateWithValueType = updateWithValue.IsNull() ? null : updateWithValue.GetType();
|
|
|
|
//
|
|
var valueProviderValue = hasValueProvider ? propertyValueProviders
|
|
.FirstOrDefault(p => p.Key == propName).Value : null;
|
|
var updateVal = !valueProviderValue.IsNull() ?
|
|
valueProviderValue.Invoke(updateWith) :
|
|
(updateWithValue.IsNull() && !updateWithNullOrEmptyValues) ?
|
|
sourceValue : updateWithValue;
|
|
var updateValType = updateVal.IsNull() ? null : updateVal.GetType();
|
|
|
|
//
|
|
Type t = Nullable.GetUnderlyingType(sourceProp.PropertyType) ?? sourceProp.PropertyType;
|
|
object safeValue =
|
|
(updateVal == null) ?
|
|
null :
|
|
!updateValType.IsCollectionType() ?
|
|
Convert.ChangeType(updateVal, t) :
|
|
updateVal;
|
|
|
|
//
|
|
sourceProp.SetValue(source, safeValue);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
if (throwExceptionOnFails)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
});
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Class is Contains a Property or not ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="property"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static bool HasProperty<T>(
|
|
this T source,
|
|
string property,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetProperties(bindingAttr)
|
|
.Any(prop => prop.Name == property); ;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Class is Contains a field or not ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="field"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static bool HasField<T>(
|
|
this T source,
|
|
string field,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetFields(bindingAttr)
|
|
.Any(fld => fld.Name == field);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Class is Contains a Method or not ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static bool HasMethod<T>(
|
|
this T source,
|
|
string method,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetMethods(bindingAttr)
|
|
.Any(mthd => mthd.Name == method);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Class Properties Names ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static string[] GetPropertiesNames<T>(
|
|
this T source,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetProperties(bindingAttr)
|
|
.Select(p => p.Name)
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Class Fields Names ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static string[] GetFieldsNames<T>(
|
|
this T source,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetFields(bindingAttr)
|
|
.Select(p => p.Name)
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Class Methods Names ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static string[] GetMethodsNames<T>(
|
|
this T source,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetMethods(bindingAttr)
|
|
.Select(p => p.Name)
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Class Members Names ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static string[] GetMembersNames<T>(
|
|
this T source,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
{
|
|
//
|
|
var result = source
|
|
.GetType()
|
|
.GetMembers(bindingAttr)
|
|
.Select(p => p.Name)
|
|
.ToArray();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Class Property Value using Generic Concept ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TProp"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="property"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static TProp GetProperty<T, TProp>(
|
|
this T source,
|
|
string property,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
TProp result = default;
|
|
|
|
//
|
|
// Check if T Has Property ...
|
|
if (source.HasProperty(property))
|
|
{
|
|
//
|
|
// Access Property ...
|
|
var prop = source
|
|
.GetType()
|
|
.GetProperty(
|
|
property,
|
|
bindingAttr
|
|
);
|
|
|
|
//
|
|
// Retrieve Property Value as Object ...
|
|
var propVal = prop.GetValue(source);
|
|
|
|
//
|
|
result = (TProp)propVal;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Class Field Value using Generic Concept ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TField"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="field"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static TField GetField<T, TField>(
|
|
this T source,
|
|
string field,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
TField result = default;
|
|
|
|
//
|
|
if (source.HasField(field))
|
|
{
|
|
//
|
|
var fld = source
|
|
.GetType()
|
|
.GetField(
|
|
field,
|
|
bindingAttr
|
|
);
|
|
|
|
//
|
|
var fieldVal = fld.GetValue(source);
|
|
result = (TField)fieldVal;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set a Class Property Value using Generic Concept ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TProp"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="property"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static bool SetProperty<T, TProp>(
|
|
this T source,
|
|
string property,
|
|
TProp value,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
// Check T Has Property ...
|
|
var result = source.HasProperty(property);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Access Property ...
|
|
var prop = source
|
|
.GetType()
|
|
.GetProperty(
|
|
property,
|
|
bindingAttr
|
|
);
|
|
|
|
//
|
|
// Set Property ...
|
|
try
|
|
{
|
|
//
|
|
result = true;
|
|
prop.SetValue(source, value);
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set a Class Field Value using Generic Concept ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TField"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="field"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="bindingAttr"></param>
|
|
/// <returns></returns>
|
|
public static bool SetField<T, TField>(
|
|
this T source,
|
|
string field,
|
|
TField value,
|
|
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
// Check T Has Field ...
|
|
var result = source.HasField(field);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Access Field ...
|
|
var fld = source
|
|
.GetType()
|
|
.GetField(
|
|
field,
|
|
bindingAttr
|
|
);
|
|
|
|
//
|
|
// Set Value ...
|
|
try
|
|
{
|
|
//
|
|
result = true;
|
|
fld.SetValue(source, value);
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check two Instance of Typed Object Values are Same or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="throwExceptionOnFails"></param>
|
|
/// <param name="propertyValueCheckers"></param>
|
|
/// /// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="D"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool IsSameContent<T, D>(
|
|
this T source,
|
|
D dest,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<T, D, bool>>> propertyValueCheckers = null,
|
|
bool throwExceptionOnFails = false
|
|
)
|
|
where T : class
|
|
where D : class
|
|
{
|
|
//
|
|
var hasWhiteList = propertyWhiteList.HasChild<string>();
|
|
var hasBlackList = propertyBlackList.HasChild<string>();
|
|
var hasCheckerProvider = propertyValueCheckers.HasChild<KeyValuePair<string, Func<T, D, bool>>>();
|
|
|
|
//
|
|
var fullPropertyList = dest.GetType().GetProperties().Select(prop => prop.Name);
|
|
var mustCheckProps = (hasWhiteList ? propertyWhiteList : fullPropertyList);
|
|
if (hasBlackList)
|
|
{
|
|
mustCheckProps = mustCheckProps.Where(propName => !propertyBlackList.Contains(propName));
|
|
}
|
|
|
|
//
|
|
var result = true;
|
|
mustCheckProps.ToList().ForEach(propName =>
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var sourceProp = source.GetType().GetProperty(propName);
|
|
var destProp = dest.GetType().GetProperty(propName);
|
|
|
|
//
|
|
// Check Types ...
|
|
var isSameType = true;
|
|
|
|
//
|
|
// Check
|
|
var isSameValue = false;
|
|
var mustDoCustomCheck = hasCheckerProvider && propertyValueCheckers.Any(p => p.Key == propName);
|
|
if (mustDoCustomCheck)
|
|
{
|
|
//
|
|
// Check Values ...
|
|
var valueChecker = propertyValueCheckers.FirstOrDefault(p => p.Key == propName).Value;
|
|
isSameValue = valueChecker.Invoke(source, dest);
|
|
}
|
|
else
|
|
{
|
|
// //
|
|
// isSameType = (sourceProp.PropertyType == destProp.PropertyType &&
|
|
// sourceProp.ReflectedType == destProp.ReflectedType);
|
|
|
|
//
|
|
// Check Values ...
|
|
isSameValue = Equals(sourceProp.GetValue(source), destProp.GetValue(dest));
|
|
}
|
|
|
|
//
|
|
if (!isSameType || !isSameValue)
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
if (throwExceptionOnFails)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
});
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check specific type is Collection Type or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsCollectionType(this Type source)
|
|
{
|
|
//
|
|
if (source.IsNull() || !source.IsGenericType)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var genericTypeDefinition = source.GetGenericTypeDefinition();
|
|
var result = genericTypeDefinition == typeof(List<>) ||
|
|
genericTypeDefinition == typeof(HashSet<>) ||
|
|
genericTypeDefinition == typeof(Collection<>) ||
|
|
genericTypeDefinition == typeof(ICollection<>) ||
|
|
genericTypeDefinition == typeof(IEnumerable<>);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Property Value in Generic
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static string GetPropValues<T>(this T item)
|
|
where T : class
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var vals = props.Select(p => p.GetValue(item));
|
|
|
|
//
|
|
return vals.ToJSON();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Property Value Contains specific value
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="value"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool PropValuesContains<T>(this T item, string value)
|
|
where T : class
|
|
{
|
|
//
|
|
return item.GetPropValues()
|
|
.ToNormalString()
|
|
.Contains(value
|
|
.ToNormalString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Default Column Map
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IDictionary<string, Expression<Func<T, object>>> GetDefaultColumnsMap<T>(this T item)
|
|
where T : class
|
|
{
|
|
//
|
|
if (item.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new Dictionary<string, Expression<Func<T, object>>>();
|
|
var props = item.GetType().GetProperties();
|
|
|
|
//
|
|
foreach (var prop in props)
|
|
{
|
|
result.Add(prop.Name, t => t.GetType().GetProperty(prop.Name).GetValue(t, null));
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Default Column Map
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IDictionary<string, string> GetPropValuesDictionary<T>(this T item)
|
|
where T : class
|
|
{
|
|
//
|
|
if (item.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new Dictionary<string, string>();
|
|
var props = item.GetType().GetProperties();
|
|
|
|
//
|
|
foreach (var prop in props)
|
|
{
|
|
result.Add(prop.Name, prop.GetValue(item).ToJSON());
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\ServiceProviderExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Helpers;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static class ServiceProviderExtensions {
|
|
/// <summary>
|
|
/// Get all registered <see cref="ServiceDescriptor"/>
|
|
/// </summary>
|
|
/// <param name="provider"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<Type, ServiceDescriptor> GetAllServiceDescriptors (this IServiceProvider provider) {
|
|
//
|
|
if (provider is ServiceProvider serviceProvider) {
|
|
//
|
|
var result = new Dictionary<Type, ServiceDescriptor> ();
|
|
|
|
//
|
|
var engine = serviceProvider.GetFieldValue ("_engine");
|
|
var callSiteFactory = engine.GetPropertyValue ("CallSiteFactory");
|
|
var descriptorLookup = callSiteFactory.GetFieldValue ("_descriptorLookup");
|
|
if (descriptorLookup is IDictionary dictionary) {
|
|
foreach (DictionaryEntry entry in dictionary) {
|
|
result.Add ((Type) entry.Key, (ServiceDescriptor) entry.Value.GetPropertyValue ("Last"));
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
throw new NotSupportedException ($"Type '{provider.GetType()}' is not supported!");
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\XHttpContextExtensions.cs
|
|
|
|
using System.IO;
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
namespace xCommons.Extensions {
|
|
public static partial class XHttpContextExtensions {
|
|
/// <summary>
|
|
/// Convert IFormFile to Bytes Array
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static byte[] ToByteArray (this IFormFile source) {
|
|
//
|
|
byte[] data;
|
|
using (var br = new BinaryReader (source.OpenReadStream ())) {
|
|
data = br.ReadBytes ((int) source.OpenReadStream ().Length);
|
|
}
|
|
|
|
//
|
|
return data;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Extensions\XMiddlewareExtensions.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using xCommons.Middlewares;
|
|
|
|
namespace xCommons.Extensions
|
|
{
|
|
public static class XMiddlewareExtensions
|
|
{
|
|
/// <summary>
|
|
/// Use XRequestLogger Middleware for log Requests ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXRequestLogger(this IApplicationBuilder app) {
|
|
app.UseMiddleware<XRequestLogger>();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Filters\RequireXPoweredOperationFilter.cs
|
|
|
|
using System.Collections.Generic;
|
|
using Microsoft.OpenApi.Any;
|
|
using Microsoft.OpenApi.Models;
|
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
using xCommons.Configurations;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCommons.Filters {
|
|
/// <summary>
|
|
/// RequireXPowered for NGSwag
|
|
/// </summary>
|
|
public partial class RequireXPoweredOperationFilter : IOperationFilter {
|
|
private readonly XAppConfiguration config;
|
|
|
|
public RequireXPoweredOperationFilter (XAppConfiguration config) {
|
|
this.config = config;
|
|
}
|
|
|
|
public void Apply (OpenApiOperation operation, OperationFilterContext context) {
|
|
//
|
|
if (operation.Parameters.IsNull ()) {
|
|
operation.Parameters = new List<OpenApiParameter> ();
|
|
}
|
|
|
|
//
|
|
operation.Parameters.Add (new OpenApiParameter {
|
|
In = ParameterLocation.Header,
|
|
Name = XAuthorization.XPoweredBy,
|
|
Description = "a Basic Authorization Filter",
|
|
Required = false,
|
|
Schema = new OpenApiSchema {
|
|
Type = "String",
|
|
Default = new OpenApiString (config.XPoweredValue)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Filters\SwaggerDefaultValuesOperationFilter.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.OpenApi.Any;
|
|
using Microsoft.OpenApi.Models;
|
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCommons.Filters
|
|
{
|
|
public class SwaggerDefaultValuesOperationFilter : IOperationFilter
|
|
{
|
|
private readonly XSwaggerConfiguration config;
|
|
|
|
public SwaggerDefaultValuesOperationFilter(
|
|
XSwaggerConfiguration config
|
|
)
|
|
{
|
|
this.config = config;
|
|
}
|
|
|
|
public void Apply(
|
|
OpenApiOperation operation,
|
|
OperationFilterContext context
|
|
)
|
|
{
|
|
//
|
|
// Validate Configuration ...
|
|
if (
|
|
!config.IsNull() &&
|
|
!config.DefaultValues.IsNull() &&
|
|
config.DefaultValues.HasChild()
|
|
)
|
|
{
|
|
//
|
|
foreach (var prv in config.DefaultValues)
|
|
{
|
|
//
|
|
// Detect Parameter ...
|
|
var swaggerParam = operation.Parameters.FirstOrDefault(p => p.Name == prv.Key);
|
|
if (!swaggerParam.IsNull())
|
|
{
|
|
swaggerParam.Schema.Default = new OpenApiString(prv.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\ObjectHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace xCommons.Helpers {
|
|
public partial class ObjectHelper {
|
|
/// <summary>
|
|
/// Convert Enum Keys to Array
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static Array GetKeys<T> () {
|
|
//
|
|
ValidateEnumbType<T> ();
|
|
var type = typeof (T);
|
|
|
|
//
|
|
var result = Enum.GetNames (type);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert EnumValues to Array
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static Array GetValues<T> () {
|
|
//
|
|
ValidateEnumbType<T> ();
|
|
var type = typeof (T);
|
|
|
|
//
|
|
var result = Enum.GetValues (type);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an Enum to IEnumerable of it's Childs
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ToEnumerableValues<T> () {
|
|
//
|
|
ValidateEnumbType<T> ();
|
|
var type = typeof (T);
|
|
|
|
//
|
|
var result = GetValues<T> ()
|
|
.Cast<T> ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Keys of an Enumerable
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<string> ToEnumerableKeys<T> () {
|
|
//
|
|
ValidateEnumbType<T> ();
|
|
var type = typeof (T);
|
|
|
|
//
|
|
var result = GetKeys<T> ()
|
|
.Cast<string> ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static IDictionary<string, int> ToDictionary<T> () {
|
|
//
|
|
ValidateEnumbType<T> ();
|
|
|
|
//
|
|
var result = new Dictionary<string, int> ();
|
|
foreach (var name in Enum.GetNames (typeof (T))) {
|
|
result.Add (name, (int) Enum.Parse (typeof (T), name));
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private static void ValidateEnumbType<T> () {
|
|
//
|
|
var type = typeof (T);
|
|
if (!type.IsEnum) {
|
|
throw new InvalidCastException ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XDateHelper.cs
|
|
|
|
using System;
|
|
|
|
namespace xCommons.Helpers {
|
|
public partial class XDateHelper {
|
|
/// <summary>
|
|
/// retrieve utc now timestam unix like representation ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static long UtcNowTimespan () {
|
|
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XGenericHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xCommons.Helpers
|
|
{
|
|
public static class XGenericHelper
|
|
{
|
|
/// <summary>
|
|
/// Invoke a Generic Method of Specified Type ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="methodName"></param>
|
|
/// <param name="runtimeType"></param>
|
|
/// <param name="args"></param>
|
|
public static void InvokeGenericMethod(
|
|
this Type source,
|
|
string methodName,
|
|
Type runtimeType,
|
|
params object[] args
|
|
)
|
|
{
|
|
//
|
|
source.InvokeGenericMethod<object>(
|
|
args: args,
|
|
methodName: methodName,
|
|
runtimeType: runtimeType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoke a Generic Method of Specified Type ...
|
|
/// </summary>
|
|
/// <typeparam name="TResponse"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="methodName"></param>
|
|
/// <param name="runtimeType"></param>
|
|
/// <param name="args"></param>
|
|
/// <returns></returns>
|
|
public static TResponse InvokeGenericMethod<TResponse>(
|
|
this Type source,
|
|
string methodName,
|
|
Type runtimeType,
|
|
params object[] args
|
|
)
|
|
{
|
|
//
|
|
var overLoads = source.GetGenericMethodInfo(
|
|
methodName: methodName
|
|
);
|
|
if (!overLoads.HasChild())
|
|
{
|
|
return default;
|
|
}
|
|
|
|
//
|
|
var method = overLoads.ElementAt(0);
|
|
MethodInfo genericMethod = method.MakeGenericMethod(runtimeType);
|
|
|
|
//
|
|
var resultObj = genericMethod.Invoke(null, args);
|
|
var result = (TResponse)resultObj;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoke a Generic Method of Specified Type ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="methodName"></param>
|
|
/// <param name="runtimeTypes"></param>
|
|
/// <param name="args"></param>
|
|
public static void InvokeGenericMethod(
|
|
this Type source,
|
|
string methodName,
|
|
Type[] runtimeTypes,
|
|
params object[] args
|
|
)
|
|
{
|
|
//
|
|
source.InvokeGenericMethod<object>(
|
|
args: args,
|
|
methodName: methodName,
|
|
runtimeTypes: runtimeTypes
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoke a Generic Method of Specified Type ...
|
|
/// </summary>
|
|
/// <typeparam name="TResponse"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="methodName"></param>
|
|
/// <param name="runtimeTypes"></param>
|
|
/// <param name="args"></param>
|
|
/// <returns></returns>
|
|
public static TResponse InvokeGenericMethod<TResponse>(
|
|
this Type source,
|
|
string methodName,
|
|
Type[] runtimeTypes,
|
|
params object[] args
|
|
)
|
|
{
|
|
//
|
|
var overLoads = source.GetGenericMethodInfo(
|
|
methodName: methodName
|
|
);
|
|
if (!overLoads.HasChild())
|
|
{
|
|
return default;
|
|
}
|
|
|
|
//
|
|
// Detect a Method by Generic Types ...
|
|
// var method = overLoads.ElementAt(0);
|
|
var method = overLoads.First(m => m.GetGenericArguments().Length == runtimeTypes.Length);
|
|
MethodInfo genericMethod = method.MakeGenericMethod(runtimeTypes);
|
|
|
|
//
|
|
var resultObj = genericMethod.Invoke(null, args);
|
|
var result = resultObj.ConvertTo<TResponse>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract a Generic Method's Overloads ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="methodName"></param>
|
|
/// <returns></returns>
|
|
public static List<MethodInfo> GetGenericMethodInfo(
|
|
this Type source,
|
|
string methodName
|
|
)
|
|
{
|
|
//
|
|
var methods = source
|
|
.GetMethods();
|
|
|
|
//
|
|
var result = methods
|
|
.Where(mi =>
|
|
mi.Name == methodName &&
|
|
mi.IsGenericMethodDefinition)
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XMLToJSONHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Xml;
|
|
|
|
namespace xCommons.Helpers {
|
|
public partial class XMLToJSONHelper {
|
|
//
|
|
#region Actions ...
|
|
public static string ToJSON (string xml) {
|
|
//
|
|
XmlDocument doc = new XmlDocument ();
|
|
doc.LoadXml (xml);
|
|
|
|
//
|
|
return XmlToJSON (doc);
|
|
}
|
|
|
|
public static string XmlToJSON (XmlDocument xmlDoc) {
|
|
//
|
|
StringBuilder sbJSON = new StringBuilder ();
|
|
|
|
//
|
|
sbJSON.Append ("{ ");
|
|
XmlToJSONnode (sbJSON, xmlDoc.DocumentElement, true);
|
|
sbJSON.Append ("}");
|
|
|
|
//
|
|
return sbJSON.ToString ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
//
|
|
private static void XmlToJSONnode (StringBuilder sbJSON, XmlElement node, bool showNodeName) {
|
|
//
|
|
if (showNodeName) {
|
|
sbJSON.Append ("\"" + SafeJSON (node.Name) + "\": ");
|
|
}
|
|
|
|
//
|
|
sbJSON.Append ("{");
|
|
|
|
//
|
|
// Build a sorted list of key-value pairs
|
|
// where key is case-sensitive nodeName
|
|
// value is an ArrayList of string or XmlElement
|
|
// so that we know whether the nodeName is an array or not.
|
|
SortedList<string, object> childNodeNames = new SortedList<string, object> ();
|
|
|
|
//
|
|
// Add in all node attributes
|
|
if (node.Attributes != null)
|
|
foreach (XmlAttribute attr in node.Attributes)
|
|
StoreChildNode (childNodeNames, attr.Name, attr.InnerText);
|
|
|
|
//
|
|
// Add in all nodes
|
|
foreach (XmlNode cnode in node.ChildNodes) {
|
|
//
|
|
if (cnode is XmlText) {
|
|
StoreChildNode (childNodeNames, "value", cnode.InnerText);
|
|
} else if (cnode is XmlElement) {
|
|
StoreChildNode (childNodeNames, cnode.Name, cnode);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now output all stored info
|
|
foreach (string childname in childNodeNames.Keys) {
|
|
//
|
|
List<object> alChild = (List<object>) childNodeNames[childname];
|
|
if (alChild.Count == 1) {
|
|
OutputNode (childname, alChild[0], sbJSON, true);
|
|
} else {
|
|
//
|
|
sbJSON.Append (" \"" + SafeJSON (childname) + "\": [ ");
|
|
|
|
//
|
|
foreach (object Child in alChild) {
|
|
OutputNode (childname, Child, sbJSON, false);
|
|
}
|
|
|
|
//
|
|
sbJSON.Remove (sbJSON.Length - 2, 2);
|
|
sbJSON.Append (" ], ");
|
|
}
|
|
}
|
|
|
|
//
|
|
sbJSON.Remove (sbJSON.Length - 2, 2);
|
|
sbJSON.Append (" }");
|
|
}
|
|
|
|
//
|
|
// StoreChildNode: Store data associated with each nodeName
|
|
// so that we know whether the nodeName is an array or not.
|
|
private static void StoreChildNode (SortedList<string, object> childNodeNames, string nodeName, object nodeValue) {
|
|
//
|
|
// Pre-process contraction of XmlElement-s
|
|
if (nodeValue is XmlElement) {
|
|
//
|
|
// Convert <aa></aa> into "aa":null
|
|
// <aa>xx</aa> into "aa":"xx"
|
|
XmlNode cnode = (XmlNode) nodeValue;
|
|
if (cnode.Attributes.Count == 0) {
|
|
//
|
|
XmlNodeList children = cnode.ChildNodes;
|
|
if (children.Count == 0) {
|
|
nodeValue = null;
|
|
} else if (children.Count == 1 && (children[0] is XmlText)) {
|
|
nodeValue = ((XmlText) (children[0])).InnerText;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add nodeValue to ArrayList associated with each nodeName
|
|
// If nodeName doesn't exist then add it
|
|
List<object> ValuesAL;
|
|
|
|
//
|
|
if (childNodeNames.ContainsKey (nodeName)) {
|
|
ValuesAL = (List<object>) childNodeNames[nodeName];
|
|
} else {
|
|
//
|
|
ValuesAL = new List<object> ();
|
|
childNodeNames[nodeName] = ValuesAL;
|
|
}
|
|
|
|
//
|
|
ValuesAL.Add (nodeValue);
|
|
}
|
|
|
|
//
|
|
private static void OutputNode (string childname, object alChild, StringBuilder sbJSON, bool showNodeName) {
|
|
if (alChild == null) {
|
|
if (showNodeName)
|
|
sbJSON.Append ("\"" + SafeJSON (childname) + "\": ");
|
|
sbJSON.Append ("null");
|
|
} else if (alChild is string) {
|
|
if (showNodeName)
|
|
sbJSON.Append ("\"" + SafeJSON (childname) + "\": ");
|
|
string sChild = (string) alChild;
|
|
sChild = sChild.Trim ();
|
|
sbJSON.Append ("\"" + SafeJSON (sChild) + "\"");
|
|
} else
|
|
XmlToJSONnode (sbJSON, (XmlElement) alChild, showNodeName);
|
|
sbJSON.Append (", ");
|
|
}
|
|
|
|
//
|
|
// Make a string safe for JSON
|
|
private static string SafeJSON (string sIn) {
|
|
//
|
|
StringBuilder sbOut = new StringBuilder (sIn.Length);
|
|
foreach (char ch in sIn) {
|
|
//
|
|
if (Char.IsControl (ch) || ch == '\'') {
|
|
//
|
|
int ich = (int) ch;
|
|
sbOut.Append (@"\u" + ich.ToString ("x4"));
|
|
continue;
|
|
} else if (ch == '\"' || ch == '\\' || ch == '/') {
|
|
sbOut.Append ('\\');
|
|
}
|
|
|
|
//
|
|
sbOut.Append (ch);
|
|
}
|
|
|
|
//
|
|
return sbOut.ToString ();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XNetworkHelper.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
using xCommons.Models;
|
|
|
|
namespace xCommons.Helpers {
|
|
public static class XNetworkHelper {
|
|
/// <summary>
|
|
/// Retrieve Application Host's Machin IP Addresses ...
|
|
/// </summary>
|
|
/// <returns>string</returns>
|
|
public static string GetIp () {
|
|
//
|
|
var name = Dns.GetHostName (); // get container id
|
|
var result = Dns.GetHostEntry (name)
|
|
.AddressList
|
|
.FirstOrDefault (
|
|
x => x.AddressFamily == AddressFamily.InterNetwork
|
|
)
|
|
.MapToIPv4 ()
|
|
.ToString ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Available IP's in Application Host's Machin ...
|
|
/// </summary>
|
|
/// <returns>a Collection of XNetworkInfo class instances</returns>
|
|
public static IEnumerable<XNetworkInfo> GetNetworkInfos () {
|
|
//
|
|
var result = System.Net.NetworkInformation.NetworkInterface
|
|
.GetAllNetworkInterfaces ()
|
|
.Where (
|
|
ni =>
|
|
!ni.IsReceiveOnly &&
|
|
ni.OperationalStatus == OperationalStatus.Up &&
|
|
ni.NetworkInterfaceType != NetworkInterfaceType.Loopback
|
|
)
|
|
.SelectMany (ni =>
|
|
ni
|
|
.GetIPProperties ()
|
|
.GatewayAddresses
|
|
.Select (ga =>
|
|
new {
|
|
Name = ni.Name,
|
|
Description = ni.Description,
|
|
Gateway = ga.Address
|
|
.MapToIPv4 ()
|
|
.ToString (),
|
|
NI = ni
|
|
}
|
|
)
|
|
)
|
|
.SelectMany (data =>
|
|
data.NI
|
|
.GetIPProperties ()
|
|
.UnicastAddresses
|
|
.Select (ip =>
|
|
new XNetworkInfo {
|
|
Name = data.Name,
|
|
Gateway = data.Gateway,
|
|
Description = data.Description,
|
|
NetworkInterface = data.NI,
|
|
IP = ip.Address
|
|
.MapToIPv4 ()
|
|
.ToString ()
|
|
}
|
|
)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XOsHelper.cs
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Attributes;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xCommons.Helpers
|
|
{
|
|
/// <summary>
|
|
/// Several OS Type ...
|
|
/// </summary>
|
|
public enum XOSType
|
|
{
|
|
[StringValue("Unknown")]
|
|
XUnknown,
|
|
|
|
[StringValue("Mac")]
|
|
XMacOs,
|
|
|
|
[StringValue("Linux")]
|
|
XLinux,
|
|
|
|
[StringValue("Windows")]
|
|
XWindows,
|
|
|
|
[StringValue("FreeBSD")]
|
|
XFreeBSD,
|
|
}
|
|
|
|
/// <summary>
|
|
/// OS Command Execution Result ...
|
|
/// </summary>
|
|
public class XOSCMDResult
|
|
{
|
|
/// <summary>
|
|
/// Execution Result ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Result { get; set; }
|
|
|
|
/// <summary>
|
|
/// Execution Error ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Error { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Helper Class which Provides OS Command Executions ...
|
|
/// </summary>
|
|
public static partial class XOsHelper
|
|
{
|
|
/// <summary>
|
|
/// Retrieve OS Type ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static XOSType GetOSType()
|
|
{
|
|
//
|
|
XOSType result = XOSType.XUnknown;
|
|
|
|
//
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
|
{
|
|
result = XOSType.XMacOs;
|
|
}
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
{
|
|
result = XOSType.XLinux;
|
|
}
|
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
result = XOSType.XWindows;
|
|
}
|
|
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
|
|
// {
|
|
// result = XOSType.XFreeBSD;
|
|
// }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve OS Description ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string GetOSDescription()
|
|
{
|
|
//
|
|
var result = RuntimeInformation.OSDescription;
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Execute an Specified Command ...
|
|
/// </summary>
|
|
/// <param name="cmd">Specified Command</param>
|
|
/// <param name="args">Command Arguments</param>
|
|
/// <returns></returns>
|
|
public static async Task<XOSCMDResult> Execute(
|
|
string cmd,
|
|
string args
|
|
)
|
|
{
|
|
//
|
|
var result = new XOSCMDResult
|
|
{
|
|
Error = "Unknown",
|
|
};
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate CMD ...
|
|
var isValid = !cmd.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate OS Type ...
|
|
XOSType osType = GetOSType();
|
|
isValid = osType != XOSType.XUnknown;
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return await Task.Run<XOSCMDResult>(() =>
|
|
{
|
|
//
|
|
ProcessStartInfo psi = new ProcessStartInfo();
|
|
|
|
//
|
|
psi.FileName = cmd;
|
|
psi.Arguments = args;
|
|
psi.UseShellExecute = false;
|
|
psi.RedirectStandardError = true;
|
|
psi.RedirectStandardOutput = true;
|
|
|
|
//
|
|
Process process = Process.Start(psi);
|
|
|
|
//
|
|
// Read the output
|
|
string output = process.StandardOutput.ReadToEnd();
|
|
string error = process.StandardError.ReadToEnd();
|
|
|
|
//
|
|
process.WaitForExit();
|
|
|
|
//
|
|
result = new XOSCMDResult
|
|
{
|
|
Error = error,
|
|
Result = output,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Error = ex.Message;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Helpers\XReflectionHelper.cs
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
|
|
namespace xCommons.Helpers {
|
|
public static class XReflectionHelper {
|
|
public static object GetFieldValue (this object obj, string fieldName) {
|
|
if (obj == null)
|
|
throw new ArgumentNullException (nameof (obj));
|
|
Type objType = obj.GetType ();
|
|
var fieldInfo = GetFieldInfo (objType, fieldName);
|
|
if (fieldInfo == null)
|
|
throw new ArgumentOutOfRangeException (fieldName,
|
|
$"Couldn't find field {fieldName} in type {objType.FullName}");
|
|
return fieldInfo.GetValue (obj);
|
|
}
|
|
|
|
public static void SetFieldValue (this object obj, string fieldName, object val) {
|
|
if (obj == null)
|
|
throw new ArgumentNullException (nameof (obj));
|
|
Type objType = obj.GetType ();
|
|
var fieldInfo = GetFieldInfo (objType, fieldName);
|
|
if (fieldInfo == null)
|
|
throw new ArgumentOutOfRangeException (fieldName,
|
|
$"Couldn't find field {fieldName} in type {objType.FullName}");
|
|
fieldInfo.SetValue (obj, val);
|
|
}
|
|
|
|
private static FieldInfo GetFieldInfo (Type type, string fieldName) {
|
|
FieldInfo fieldInfo = null;
|
|
do {
|
|
fieldInfo = type.GetField (fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
type = type.BaseType;
|
|
} while (fieldInfo == null && type != null);
|
|
|
|
return fieldInfo;
|
|
}
|
|
|
|
public static object GetPropertyValue (this object obj, string propertyName) {
|
|
if (obj == null)
|
|
throw new ArgumentNullException (nameof (obj));
|
|
Type objType = obj.GetType ();
|
|
var propertyInfo = GetPropertyInfo (objType, propertyName);
|
|
if (propertyInfo == null)
|
|
throw new ArgumentOutOfRangeException (propertyName,
|
|
$"Couldn't find property {propertyName} in type {objType.FullName}");
|
|
return propertyInfo.GetValue (obj, null);
|
|
}
|
|
|
|
public static void SetPropertyValue (this object obj, string propertyName, object val) {
|
|
if (obj == null)
|
|
throw new ArgumentNullException (nameof (obj));
|
|
Type objType = obj.GetType ();
|
|
var propertyInfo = GetPropertyInfo (objType, propertyName);
|
|
if (propertyInfo == null)
|
|
throw new ArgumentOutOfRangeException (propertyName,
|
|
$"Couldn't find property {propertyName} in type {objType.FullName}");
|
|
propertyInfo.SetValue (obj, val, null);
|
|
}
|
|
|
|
private static PropertyInfo GetPropertyInfo (Type type, string propertyName) {
|
|
PropertyInfo propertyInfo = null;
|
|
do {
|
|
propertyInfo = type.GetProperty (propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
type = type.BaseType;
|
|
} while (propertyInfo == null && type != null);
|
|
|
|
return propertyInfo;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Interfaces\IXCipher.cs
|
|
|
|
namespace xCommons.Interfaces
|
|
{
|
|
public interface IXCipher
|
|
{
|
|
string Encrypt(string plainText);
|
|
string Decrypt(string cipherText);
|
|
string EncryptFromBytes(byte[] textBytes);
|
|
string DecryptFromBytes(byte[] cipherBytes);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Middlewares\XRequestLogger.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xCommons.Models;
|
|
|
|
namespace xCommons.Middlewares {
|
|
public partial class XRequestLogger {
|
|
|
|
private readonly ILogger logger;
|
|
private readonly RequestDelegate next;
|
|
|
|
public XRequestLogger (
|
|
RequestDelegate next,
|
|
ILoggerFactory loggerFactory
|
|
) {
|
|
//
|
|
this.next = next;
|
|
this.logger = loggerFactory
|
|
.CreateLogger<XRequestLogger> ();
|
|
}
|
|
|
|
public async Task InvokeAsync (HttpContext context) {
|
|
//
|
|
var logModel = new XLoggerModel ();
|
|
|
|
//
|
|
logModel.Path = context.Request.Path;
|
|
logModel.Schema = context.Request.Scheme;
|
|
logModel.Method = context.Request.Method;
|
|
logModel.Headers = context.Request.Headers;
|
|
logModel.Host = context.Request.Host.ToString ();
|
|
logModel.QueryString = context.Request.QueryString.ToString ();
|
|
logModel.UserID = context.User.Identity.IsAuthenticated ? context.User.Identity.Name : "Not Authenticated";
|
|
|
|
//
|
|
logModel.Connection = new XLoggerHttpConnection {
|
|
Id = context.Connection.Id,
|
|
RemoteIpAddress = context.Connection.RemoteIpAddress.ToString (),
|
|
RemotePort = context.Connection.RemotePort.ToString (),
|
|
LocalIpAddress = context.Connection.LocalIpAddress.ToString (),
|
|
LocalPort = context.Connection.LocalPort.ToString (),
|
|
};
|
|
|
|
//
|
|
// Check if a request is a Post Call so read data from Body ...
|
|
if (context.Request.Method.ToNormalString () == "post") {
|
|
//
|
|
context.Request.EnableBuffering ();
|
|
var request = await new StreamReader (context.Request.Body)
|
|
.ReadToEndAsync ();
|
|
|
|
//
|
|
context.Request.Body.Position = 0;
|
|
logModel.Request = request;
|
|
}
|
|
|
|
//
|
|
logModel.RequestedOn = DateTime.UtcNow;
|
|
|
|
//
|
|
// Do Request ...
|
|
await next.Invoke (context);
|
|
|
|
//
|
|
using (Stream originalRequest = context.Response.Body) {
|
|
try {
|
|
using (var memStream = new MemoryStream ()) {
|
|
//
|
|
context.Response.Body = memStream;
|
|
|
|
//
|
|
// All the Request processing as described above
|
|
// happens from here.
|
|
// Response handling starts from here
|
|
// set the pointer to the beginning of the
|
|
// memory stream to read
|
|
memStream.Position = 0;
|
|
|
|
//
|
|
// read the memory stream till the end
|
|
var response = await new StreamReader (memStream)
|
|
.ReadToEndAsync ();
|
|
|
|
//
|
|
logModel.Response = response;
|
|
logModel.RespondedOn = DateTime.UtcNow;
|
|
logModel.StatusCode = context.Response.StatusCode;
|
|
logModel.IsSucceed = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
|
|
|
|
//
|
|
// since we have read till the end of the stream,
|
|
// reset it onto the first position
|
|
memStream.Position = 0;
|
|
|
|
//
|
|
// now copy the content of the temporary memory
|
|
// stream we have passed to the actual response body
|
|
// which will carry the response out.
|
|
await memStream.CopyToAsync (originalRequest);
|
|
}
|
|
} catch (Exception ex) {
|
|
//
|
|
// Log Exception ...
|
|
logger.LogError ($"Error on Logging Request/Response ... {ex.ToJSON()}");
|
|
} finally {
|
|
//
|
|
// assign the response body to the actual context
|
|
context.Response.Body = originalRequest;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Log Response ...
|
|
logger.LogCritical ($"Http Response/Response Information:{Environment.NewLine}" +
|
|
$"Schema:{logModel.Schema} " + Environment.NewLine +
|
|
$"Host: {logModel.Host} " + Environment.NewLine +
|
|
$"Path: {logModel.Path} " + Environment.NewLine +
|
|
$"Method: {logModel.Method} " + Environment.NewLine +
|
|
$"UserID: {logModel.UserID} " + Environment.NewLine +
|
|
$"QueryString: {context.Request.QueryString} " + Environment.NewLine +
|
|
$"Headers: {logModel.Headers.ToJSON()}" + Environment.NewLine +
|
|
$"" + Environment.NewLine +
|
|
$"Http Connection: " + Environment.NewLine +
|
|
$"Id: {logModel.Connection.Id}" + Environment.NewLine +
|
|
$"RemoteIpAddress: {logModel.Connection.RemoteIpAddress}" + Environment.NewLine +
|
|
$"RemotePort: {logModel.Connection.RemotePort}" + Environment.NewLine +
|
|
$"LocalIpAddress: {logModel.Connection.LocalIpAddress}" + Environment.NewLine +
|
|
$"LocalPort: {logModel.Connection.LocalPort}" + Environment.NewLine +
|
|
$"" + Environment.NewLine +
|
|
$"Request Body: {logModel.Request}" + Environment.NewLine +
|
|
$"RequestedOn: {logModel.RequestedOn}" + Environment.NewLine +
|
|
$"" + Environment.NewLine +
|
|
$"IsSucceed: {logModel.IsSucceed}" + Environment.NewLine +
|
|
$"StatucCode: {logModel.StatusCode}" + Environment.NewLine +
|
|
$"Response Body: {logModel.Response}" + Environment.NewLine +
|
|
$"RespondedOn: {logModel.RespondedOn}" + Environment.NewLine +
|
|
$"" + Environment.NewLine
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Models\XCertificate.cs
|
|
|
|
namespace xCommons.Models {
|
|
public partial class XCertificate {
|
|
public string Path { get; set; }
|
|
public string Secret { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Models\XLoggerModel.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
namespace xCommons.Models {
|
|
public class XLoggerModel {
|
|
public string Schema { get; set; }
|
|
public string Host { get; set; }
|
|
public string Path { get; set; }
|
|
public string Method { get; set; }
|
|
public string UserID { get; set; }
|
|
public string QueryString { get; set; }
|
|
public IHeaderDictionary Headers { get; set; }
|
|
public string Request { get; set; }
|
|
public int StatusCode { get; set; }
|
|
public bool IsSucceed { get; set; }
|
|
public string Response { get; set; }
|
|
public DateTime RequestedOn { get; set; }
|
|
public DateTime RespondedOn { get; set; }
|
|
public XLoggerHttpConnection Connection { get; set; }
|
|
}
|
|
|
|
public class XLoggerHttpConnection {
|
|
public string Id { get; set; }
|
|
public string RemoteIpAddress { get; set; }
|
|
public string RemotePort { get; set; }
|
|
public string LocalIpAddress { get; set; }
|
|
public string LocalPort { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Models\XNetworkInfo.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.NetworkInformation;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace xCommons.Models {
|
|
public class XNetworkInfo {
|
|
/// <summary>
|
|
/// Network Name ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Network Description ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// IP Address which Exists on Current Network ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IP { get; set; }
|
|
|
|
/// <summary>
|
|
/// Current Networks Gateway Address ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Gateway { get; set; }
|
|
|
|
/// <summary>
|
|
/// Network Interface Object ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public NetworkInterface NetworkInterface { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Models\XServiceDescriptor.cs
|
|
|
|
using System;
|
|
|
|
namespace xCommons.Models
|
|
{
|
|
public class XServiceDescriptor
|
|
{
|
|
public Type Service { get; set; }
|
|
public Type Implementation { get; set; }
|
|
}
|
|
|
|
public class XServiceDescriptor<TService, TImplmentation> : XServiceDescriptor
|
|
{
|
|
public XServiceDescriptor() : base()
|
|
{
|
|
Service = typeof(TService);
|
|
Implementation = typeof(TImplmentation);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Providers\XCipher.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xCommons.Interfaces;
|
|
|
|
namespace xCommons.Providers
|
|
{
|
|
public class XCipher : IXCipher
|
|
{
|
|
//
|
|
#region Props ...
|
|
private readonly string secretKey;
|
|
private readonly byte[] iv;
|
|
private readonly byte[] key;
|
|
private readonly XValidationProvider validationProvider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XCipher(
|
|
string cipherKey,
|
|
XValidationProvider validationProvider
|
|
)
|
|
{
|
|
//
|
|
this.secretKey = cipherKey.ToMd5String();
|
|
this.validationProvider = validationProvider;
|
|
|
|
//
|
|
var ivBytes = new byte[16];
|
|
var keyBytes = new byte[32];
|
|
var secretBytes = Encoding.UTF8.GetBytes(this.secretKey);
|
|
|
|
//
|
|
Array.Copy(
|
|
secretBytes,
|
|
ivBytes,
|
|
secretBytes.Length < ivBytes.Length ?
|
|
secretBytes.Length :
|
|
ivBytes.Length
|
|
);
|
|
this.iv = ivBytes;
|
|
|
|
//
|
|
Array.Copy(
|
|
secretBytes,
|
|
keyBytes,
|
|
secretBytes.Length < keyBytes.Length ?
|
|
secretBytes.Length :
|
|
keyBytes.Length
|
|
);
|
|
this.key = keyBytes;
|
|
|
|
// Encoding.UTF8.GetBytes (this.secretKey);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
public string Encrypt(string plainText)
|
|
{
|
|
//
|
|
validationProvider.NotEmpty(plainText);
|
|
|
|
//
|
|
var textBytes = Encoding.UTF8.GetBytes(plainText);
|
|
var result = EncryptFromBytes(textBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string Decrypt(string cipherText)
|
|
{
|
|
//
|
|
validationProvider.NotEmpty(cipherText);
|
|
|
|
//
|
|
var cipherBytes = Convert.FromBase64String(cipherText);
|
|
var result = DecryptFromBytes(cipherBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string EncryptFromBytes(byte[] textBytes)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(textBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
byte[] encryptedBytes = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged())
|
|
{
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
//
|
|
using (var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV))
|
|
{
|
|
encryptedBytes = encryptor.TransformFinalBlock(textBytes, 0, textBytes.Length);
|
|
}
|
|
}
|
|
|
|
//
|
|
return Convert.ToBase64String(encryptedBytes);
|
|
}
|
|
|
|
public string DecryptFromBytes(byte[] cipherBytes)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(cipherBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
string plaintext = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged())
|
|
{
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
// Create a decrytor to perform the stream transform.
|
|
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
|
|
|
|
// Create the streams used for decryption.
|
|
using (var msDecrypt = new MemoryStream(cipherBytes))
|
|
{
|
|
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
|
{
|
|
using (var srDecrypt = new StreamReader(csDecrypt))
|
|
{
|
|
// Read the decrypted bytes from the decrypting stream
|
|
// and place them in a string.
|
|
plaintext = srDecrypt.ReadToEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return plaintext;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xCommons\Providers\XValidationProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xCommons.Providers {
|
|
public partial class XValidationProvider {
|
|
private ICollection<System.Action> validationGroup;
|
|
|
|
//
|
|
#region Simple Validators ...
|
|
/// <summary>
|
|
/// given objects must not null
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotNull (
|
|
params object[] values) {
|
|
//
|
|
foreach (var o in values) {
|
|
//
|
|
if (o == null) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// given strings must not empty or null
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotEmpty (
|
|
params string[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s.IsNullOrEmpty ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a numeric value is bigger than 0
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotZero (
|
|
params int[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s == 0) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a numeric value is bigger than 0
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotZero (
|
|
params long[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s == 0) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a numeric value is bigger than 0
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotZero (
|
|
params decimal[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s == 0) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Value is a Valid Guid ...
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void IsGuid (params string[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (!s.IsGuid () || s.IsDefaultGuid ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Value is a Valid Guid ...
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void IsGuid (params Guid[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s.IsNull () || s.IsDefaultGuid ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Value is an MD5 ...
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void IsMD5 (params string[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (!s.IsMD5String ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// non zero childs
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotZeroChilds (
|
|
params IEnumerable<object>[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s == null ||
|
|
s.Count () == 0) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// non zero childs
|
|
/// </summary>
|
|
/// <param name="values"></param>
|
|
public void NotZeroChilds (
|
|
params ICollection<object>[] values) {
|
|
//
|
|
foreach (var s in values) {
|
|
//
|
|
if (s == null ||
|
|
s.Count == 0) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// given string must be a valid URL ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="exception"></param>
|
|
public void Url (
|
|
string url,
|
|
Exception exception = null
|
|
) {
|
|
//
|
|
NotEmpty (url);
|
|
|
|
//
|
|
if (exception == null) {
|
|
exception = XException.InavlidUrl.ToException ();
|
|
}
|
|
|
|
//
|
|
if (!url.IsValidUrl ()) {
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// given string must be a valid Email Address ...
|
|
/// </summary>
|
|
/// <param name="emailAdress"></param>
|
|
/// <param name="exception"></param>
|
|
public void EmailAddress (
|
|
string emailAdress,
|
|
Exception exception = null
|
|
) {
|
|
//
|
|
NotEmpty (emailAdress);
|
|
|
|
//
|
|
if (exception == null) {
|
|
exception = XException.InvalidEmailAddress.ToException ();
|
|
}
|
|
|
|
//
|
|
if (!emailAdress.IsValidEmail ()) {
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// given string must be a valid Mobile Number ...
|
|
/// </summary>
|
|
/// <param name="mobileNumber"></param>
|
|
/// <param name="exception"></param>
|
|
public void MobileNumber (
|
|
string mobileNumber,
|
|
Exception exception = null
|
|
) {
|
|
//
|
|
NotEmpty (mobileNumber);
|
|
|
|
//
|
|
if (exception == null) {
|
|
exception = XException.InvalidMobileNumber.ToException ();
|
|
}
|
|
|
|
//
|
|
if (!mobileNumber.IsValidMobileNumber ()) {
|
|
throw exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Group Validatos ...
|
|
public XValidationProvider GroupValidationBuilder () {
|
|
//
|
|
validationGroup = new List<System.Action> ();
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotEmpty (params string[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotEmpty (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotNull (params object[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotNull (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotZero (params int[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotZero (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotZero (params long[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotZero (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotZero (params decimal[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotZero (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddIsGuid (params string[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.IsGuid (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddIsGuid (params Guid[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.IsGuid (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddIsMD5 (params string[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.IsMD5 (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotZeroChilds (params IEnumerable<object>[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotZeroChilds (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddNotZeroChilds (params ICollection<object>[] values) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.NotZeroChilds (values)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddEmailAddress (
|
|
string emailAdress,
|
|
Exception exception = null) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.EmailAddress (emailAdress, exception)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddMobileNumber (
|
|
string mobileNumber,
|
|
Exception exception = null) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.MobileNumber (mobileNumber, exception)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public XValidationProvider AddUrl (
|
|
string url,
|
|
Exception exception = null) {
|
|
//
|
|
this.validationGroup.Add (() =>
|
|
this.Url (url, exception)
|
|
);
|
|
|
|
//
|
|
return this;
|
|
}
|
|
|
|
public void ValidateGroup () {
|
|
//
|
|
// Run each Tasks ...
|
|
foreach (var action in validationGroup) {
|
|
action.Invoke ();
|
|
}
|
|
|
|
//
|
|
// Clear Task List ...
|
|
validationGroup.Clear ();
|
|
}
|
|
|
|
public async Task ValidateGroupAsync () {
|
|
//
|
|
// Run each Tasks ...
|
|
foreach (var action in validationGroup) {
|
|
await Task.Run (action);
|
|
}
|
|
|
|
//
|
|
// Clear Task List ...
|
|
validationGroup.Clear ();
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Configuration\XDataBaseConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
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; }
|
|
|
|
/// <summary>
|
|
/// Holds Seeding items ...
|
|
/// nameof(TEntity) => TEntity
|
|
/// </summary>
|
|
public IDictionary<string, List<object>> SeedItems { get; set; } = new Dictionary<string, List<object>>();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Configuration\XDataServiceConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xDataService.Constants;
|
|
|
|
namespace xDataService.Configuration
|
|
{
|
|
/// <summary>
|
|
/// Represent Configurations of DataService Module ...
|
|
/// </summary>
|
|
public partial class XDataServiceConfiguration
|
|
{
|
|
/// <summary>
|
|
/// the base path for providing GraphQL ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string GraphQLBasePath { get; set; } = "/graphql";
|
|
|
|
/// <summary>
|
|
/// Data Bases Configuration ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IDictionary<string, XDataBaseConfiguration> Databases { get; set; } = new Dictionary<string, XDataBaseConfiguration>();
|
|
|
|
/// <summary>
|
|
/// Enable Soft Delete Entities or Not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableSoftDelete { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specified Seeding Mode ...
|
|
/// </summary>
|
|
public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.None;
|
|
|
|
/// <summary>
|
|
/// Enable Tracking of Entities ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableTracking { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// Enable Logging Details of Errors ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableDetailedErrors { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// Enable Logging Sensitive Data ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableSensitiveDataLogging { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// this is a way to provide Default Pagination Data on XQuery based requests ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration();
|
|
}
|
|
|
|
/// <summary>
|
|
/// this is a way to provide Default Pagination Data on XQuery based requests ...
|
|
/// </summary>
|
|
public partial class PagingConfiguration
|
|
{
|
|
/// <summary>
|
|
/// Default Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int DefaultPageSize { get; set; } = XDataServiceConstants.DEFAULT_PAGE_SIZE;
|
|
|
|
/// <summary>
|
|
/// restrict Maximum Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MaxAvailablePageSize { get; set; } = XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE;
|
|
|
|
/// <summary>
|
|
/// restrice Minimum Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MinAvailablePageSize { get; set; } = XDataServiceConstants.MIN_AVAILABLE_PAGE_SIZE;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xDataService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string DB_PROVIDER_NODE = "XDBProvider";
|
|
public const string DATA_SERVICE_NODE = "DataServiceConfiguration";
|
|
public const string DATA_SERVICE_DB_SEED_NODE = "DbSeeder";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDataServiceConstants.cs
|
|
|
|
namespace xDataService.Constants {
|
|
/// <summary>
|
|
/// Default Pagination Values ...
|
|
/// </summary>
|
|
public partial struct XDataServiceConstants {
|
|
public static int DEFAULT_PAGE_SIZE = 50;
|
|
public static int MAX_AVAILABLE_PAGE_SIZE = 500;
|
|
public static int MIN_AVAILABLE_PAGE_SIZE = 20;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDbProviders.cs
|
|
|
|
namespace xDataService.Constants {
|
|
/// <summary>
|
|
/// Represent Supported DBMS for Managing Data ...
|
|
/// </summary>
|
|
public enum XDbProviders {
|
|
None,
|
|
MySQL,
|
|
SQLite,
|
|
Oracle,
|
|
SQLServer,
|
|
MongoDB,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represent Supported DBMS for Managing Data ...
|
|
/// </summary>
|
|
public partial struct ProviderType {
|
|
public const string MySQL = "MYSQL";
|
|
public const string SQLite = "SQLITE";
|
|
public const string Oracle = "ORACLE";
|
|
public const string MongoDB = "MONGODB";
|
|
public const string SQLServer = "SQLSERVER";
|
|
}
|
|
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDbSeedingMode.cs
|
|
|
|
namespace xDataService.Constants
|
|
{
|
|
/// <summary>
|
|
/// All Seeding Data Mode ...
|
|
/// </summary>
|
|
public enum XDbSeedingMode
|
|
{
|
|
/// <summary>
|
|
/// No Seed Data ...
|
|
/// </summary>
|
|
None,
|
|
|
|
/// <summary>
|
|
/// Seed Only New Items ...
|
|
/// </summary>
|
|
AddIfNotExists,
|
|
|
|
/// <summary>
|
|
/// Seed Force (Add/Update) ...
|
|
/// </summary>
|
|
AddOrUpdate,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XRepositoryType.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xDataService.Constants
|
|
{
|
|
public enum XRepositoryType
|
|
{
|
|
[StringValue("EF")]
|
|
EF,
|
|
|
|
[StringValue("Mongo")]
|
|
Mongo,
|
|
|
|
[StringValue("InMemory")]
|
|
InMemory
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Controllers\XBaseRepositoryController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xDataService.Interfaces;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using System.Threading;
|
|
using xCommons.Controllers;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
namespace xDataService.Controllers
|
|
{
|
|
/// <summary>
|
|
/// an Abstract Controller for Providing Entity Repository Actions Implementatin ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
[AllowAnonymous]
|
|
public abstract class XBaseRepositoryController<TEntity, TKey> : XBaseApiV1Controller, IXBaseRepositoryController<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
|
|
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
|
|
public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseRepositoryController(
|
|
ILogger<XBaseRepositoryController<TEntity, TKey>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{
|
|
//
|
|
Repository = repository;
|
|
DefaultOrderBuilder = defaultOrderBuilder;
|
|
DefaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// Add Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public virtual async Task<ActionResult<TEntity>> Add(
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.AddAsync(
|
|
item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddOrUpdate")]
|
|
public virtual async Task<ActionResult<TEntity>> AddOrUpdate(
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.AddOrUpdateAsync(
|
|
item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddMany")]
|
|
public virtual async Task<ActionResult> AddMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
await Repository
|
|
.AddRangeAsync(
|
|
request.Items,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Get Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.GetAsync(
|
|
id,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
public virtual async Task<ActionResult<IEnumerable<TEntity>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.GetAllAsync(
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne/{query}")]
|
|
public virtual async Task<ActionResult<TEntity>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.FindOneAsync(
|
|
predicate: t =>
|
|
t.PropValuesContains(query),
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany/{query}")]
|
|
public virtual async Task<ActionResult<IEnumerable<TEntity>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.FindManyAsync(
|
|
predicate: t =>
|
|
t.PropValuesContains(query),
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Items Based on Query Mechanism ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TEntity>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.QueryAsync(
|
|
query: query,
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id, item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection of items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("UpdateMany")]
|
|
public virtual async Task<ActionResult<bool>> UpdateMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.UpdateRangeAsync(
|
|
saveChanges: true,
|
|
items: request.Items,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
///Check an Item Exists or not ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/IsExists")]
|
|
public virtual async Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// Remove an Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await Repository
|
|
.RemoveAsync(
|
|
id: id,
|
|
saveChanges: true,
|
|
softDelete: softDelete,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Many Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("RemoveMany")]
|
|
public virtual async Task<ActionResult> RemoveMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
await Repository
|
|
.RemoveRangeAsync(
|
|
saveChanges: true,
|
|
items: request.Items,
|
|
softDelete: softDelete,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Controllers\XBaseServiceController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Controllers;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xDataService.Interfaces;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Controllers
|
|
{
|
|
/// <summary>
|
|
/// an Abstract Controller for Providing Entity Dto Repository Service Actions Implementatin ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
[AllowAnonymous]
|
|
public abstract class XBaseServiceController<TEntity, TDto, TKey> : XBaseApiV1Controller, IXBaseServiceController<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IXBaseRepositoryService<TEntity, TDto, TKey> RepositoryService { get; }
|
|
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseServiceController(
|
|
ILogger<XBaseServiceController<TEntity, TDto, TKey>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXBaseRepositoryService<TEntity, TDto, TKey> repositoryService,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{
|
|
//
|
|
RepositoryService = repositoryService;
|
|
DefaultOrderBuilder = defaultOrderBuilder;
|
|
DefaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// Add Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public virtual async Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.AddAsync(
|
|
item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddOrUpdate")]
|
|
public virtual async Task<ActionResult<TDto>> AddOrUpdate(
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.AddOrUpdateAsync(
|
|
item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddMany")]
|
|
public virtual async Task<ActionResult> AddMany(
|
|
[FromBody] XBaseRangeRequest<TDto> request,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
await RepositoryService
|
|
.AddRangeAsync(
|
|
request.Items,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Get Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.GetAsync(
|
|
id,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.GetAllAsync(
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Specified Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne/{query}")]
|
|
public virtual async Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.FindOneAsync(
|
|
predicate: t =>
|
|
t.PropValuesContains(query),
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find Many Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany/{query}")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.FindManyAsync(
|
|
predicate: t =>
|
|
t.PropValuesContains(query),
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Items Based on Query Mechanism ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(query);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.QueryAsync(
|
|
query: query,
|
|
orderBuilder: useDefaultOrders
|
|
? DefaultOrderBuilder
|
|
: null,
|
|
includeBuilder: useDefaultIncludes
|
|
? DefaultIncludeBuilder
|
|
: null,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update Item ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id, item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection of items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("UpdateMany")]
|
|
public virtual async Task<ActionResult<bool>> UpdateMany(
|
|
[FromBody] XBaseRangeRequest<TDto> request,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.UpdateRangeAsync(
|
|
saveChanges: true,
|
|
items: request.Items,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
///Check an Item Exists or not ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/IsExists")]
|
|
public virtual async Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// Remove an Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await RepositoryService
|
|
.RemoveAsync(
|
|
id: id,
|
|
saveChanges: true,
|
|
softDelete: softDelete,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Many Items ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// </remarks>
|
|
/// <param name="request"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("RemoveMany")]
|
|
public virtual async Task<ActionResult> RemoveMany(
|
|
[FromBody] XBaseRangeRequest<TDto> request,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(request)
|
|
.AddNotZeroChilds(request.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
await RepositoryService
|
|
.RemoveRangeAsync(
|
|
saveChanges: true,
|
|
items: request.Items,
|
|
softDelete: softDelete,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Db\XDbContext.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Helpers;
|
|
using xDataService.Providers;
|
|
|
|
namespace xDataService.Db
|
|
{
|
|
/// <summary>
|
|
/// Provide an abstraction layout arround DBContext ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
public abstract class XDbContext : DbContext
|
|
{
|
|
//
|
|
#region Properties ...
|
|
private readonly string database;
|
|
private readonly XDataServiceConfiguration config;
|
|
private readonly string[] dynamicEntityRegisterarsNames;
|
|
private readonly XEntityRegisterarHandlerService dynamicEntityHandlers;
|
|
#endregion
|
|
|
|
//
|
|
#region Entities ...
|
|
//
|
|
// Register Default and Base Entities ...
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XDbContext(
|
|
string database,
|
|
DbContextOptions options,
|
|
XDataServiceConfiguration config,
|
|
XEntityRegisterarHandlerService dynamicEntityHandlers,
|
|
string[] dynamicEntityRegisterarsNames = null
|
|
) : base(options)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
Database.EnsureCreated();
|
|
Database.Migrate();
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
this.config = config;
|
|
this.database = database;
|
|
this.dynamicEntityHandlers = dynamicEntityHandlers;
|
|
this.dynamicEntityRegisterarsNames = dynamicEntityRegisterarsNames;
|
|
|
|
//
|
|
// Handling DbSets of Dynamic Entities ...
|
|
if (!dynamicEntityHandlers.IsNull())
|
|
{
|
|
//
|
|
// Configure XEntityRegisterarHandlerService ...
|
|
dynamicEntityHandlers.HandleRegisteredEntities();
|
|
|
|
//
|
|
// Loop through Entity Types ...
|
|
foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames))
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Use reflection to call Set<T>()
|
|
var method = typeof(XDbContext)
|
|
.GetMethod(nameof(XDbContext.Set), Type.EmptyTypes)
|
|
.MakeGenericMethod(entityType);
|
|
if (!method.IsNull())
|
|
{
|
|
method.Invoke(this, null);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Extract Current Database Configuration ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public XDataBaseConfiguration GetDatabaseConfiguration()
|
|
{
|
|
//
|
|
XDataBaseConfiguration result =
|
|
config.Databases.FirstOrDefault(db => string
|
|
.Equals(db.Key, database, StringComparison.InvariantCultureIgnoreCase)).Value;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Overrides ...
|
|
//
|
|
// Prepare Model Configs ...
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
OnXModelCreating(modelBuilder);
|
|
|
|
//
|
|
// Automatically apply all IEntityTypeConfiguration<T> in this assembly
|
|
modelBuilder.ApplyConfigurationsFromAssembly(typeof(XDbContext).Assembly);
|
|
|
|
//
|
|
// Check Dynamic Registered Service is Exists or not ...
|
|
if (!dynamicEntityHandlers.IsNull())
|
|
{
|
|
//
|
|
// Set Entity of Dynamically Registered Entities ...
|
|
foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames))
|
|
{
|
|
modelBuilder.Entity(entityType);
|
|
}
|
|
|
|
//
|
|
// Configure Entity using Provided Registerar ...
|
|
dynamicEntityHandlers
|
|
.HandleApplyRegisteredEntitiesConfigurations(modelBuilder, dynamicEntityRegisterarsNames);
|
|
}
|
|
|
|
//
|
|
// Since this class inherit from Identity Db Context,
|
|
// we have to pass this to Building Identity Models ...
|
|
base.OnModelCreating(modelBuilder);
|
|
}
|
|
|
|
//
|
|
// Prepare Configuring ...
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
//
|
|
if (config.EnableDetailedErrors)
|
|
{
|
|
optionsBuilder.EnableDetailedErrors();
|
|
}
|
|
|
|
//
|
|
if (config.EnableSensitiveDataLogging)
|
|
{
|
|
optionsBuilder.EnableSensitiveDataLogging();
|
|
}
|
|
|
|
//
|
|
if (config.EnableTracking)
|
|
{
|
|
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
|
|
}
|
|
else
|
|
{
|
|
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
|
}
|
|
|
|
//
|
|
OnXConfiguring(optionsBuilder);
|
|
|
|
//
|
|
base.OnConfiguring(optionsBuilder);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Abstracts ...
|
|
//
|
|
public abstract void OnXModelCreating(ModelBuilder modelBuilder);
|
|
|
|
//
|
|
public abstract void OnXConfiguring(DbContextOptionsBuilder optionsBuilder);
|
|
#endregion
|
|
|
|
//
|
|
#region Dynamic DbSet(s) ...
|
|
public override DbSet<TEntity> Set<TEntity>()
|
|
where TEntity : class
|
|
{
|
|
return base.Set<TEntity>();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Db\XUnitOfWorks.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Db {
|
|
/// <summary>
|
|
/// Provide Unit Of Works Design Pattern for Db Transactions ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <typeparam name="TDbContext"></typeparam>
|
|
public class XUnitOfWorks<TDbContext> : IXUnitOfWorks<TDbContext>
|
|
where TDbContext : XDbContext {
|
|
public TDbContext DbContext { get; }
|
|
|
|
public XUnitOfWorks (TDbContext context) {
|
|
this.DbContext = context;
|
|
}
|
|
|
|
public DbSet<T> GetDbSet<T, TKey> ()
|
|
where T : XBaseEntity<TKey> {
|
|
return DbContext.Set<T> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save Changes
|
|
/// </summary>
|
|
public int SaveChanges () {
|
|
return DbContext.SaveChanges ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save Changes Async
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> SaveChangesAsync (
|
|
CancellationToken cancellationToken = default
|
|
) {
|
|
return await DbContext.SaveChangesAsync (cancellationToken);
|
|
}
|
|
|
|
public void Dispose () {
|
|
DbContext.Dispose ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\DI\XDIHelperExtension.cs
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\DbContextOptionExtensions.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
using MySql.EntityFrameworkCore.Infrastructure;
|
|
|
|
namespace xDataService.Extensions {
|
|
public static class DbContextOptionExtensions {
|
|
/// <summary>
|
|
/// convert dynamic object to MySqlDbContextOptionBuilder ...
|
|
/// Only Used in EFCore ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<MySQLDbContextOptionsBuilder> ToMySQLDbContextOptionsBuilder (
|
|
this Action<dynamic> source
|
|
) {
|
|
return ((Action<MySQLDbContextOptionsBuilder>) source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// convert dynamic object to SqliteDbContextOptionBuilder ...
|
|
/// Only Used in EFCore ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<SqliteDbContextOptionsBuilder> ToSqliteDbContextOptionsBuilder (
|
|
this Action<dynamic> source
|
|
) {
|
|
return ((Action<SqliteDbContextOptionsBuilder>) source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// convert dynamic object to SqlServerDbContextOptionBuilder ...
|
|
/// Only Used in EFCore ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<SqlServerDbContextOptionsBuilder> ToSqlServerDbContextOptionsBuilder (
|
|
this Action<dynamic> source
|
|
) {
|
|
return ((Action<SqlServerDbContextOptionsBuilder>) source);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\EntityExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Extensions {
|
|
public static class EntityExtensions {
|
|
/// <summary>
|
|
/// return all values of an entity properties as a json string ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static string GetPropValues<T> (this T item)
|
|
where T : XBaseEntity<T> {
|
|
//
|
|
var props = item.GetType ().GetProperties ();
|
|
var vals = props.Select (p => p.GetValue (item));
|
|
|
|
//
|
|
return vals.ToJSON ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// check values of all properties of an Entity contains specific value or not ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="value"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static bool PropValuesContains<T> (this T item, string value)
|
|
where T : XBaseEntity<T> => item.GetPropValues ()
|
|
.ToNormalString ()
|
|
.Contains (value);
|
|
|
|
/// <summary>
|
|
/// Retrieve Default Column Map of specific Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IDictionary<string, Expression<Func<T, object>>> GetDefaultColumnsMap<T> (this T item)
|
|
where T : XBaseEntity<T> {
|
|
//
|
|
if (item.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new Dictionary<string, Expression<Func<T, object>>> ();
|
|
var props = item.GetType ().GetProperties ();
|
|
|
|
//
|
|
foreach (var prop in props) {
|
|
result.Add (
|
|
prop.Name,
|
|
t => t.GetType ().GetProperty (prop.Name).GetValue (t, null));
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Type is XBaseEntity or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsXEntity(this Type source)
|
|
{
|
|
//
|
|
var result = !source.IsNull();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var baseType = source.BaseType;
|
|
while(!baseType.IsNull() && baseType != typeof(object))
|
|
{
|
|
//
|
|
if (baseType.IsGenericType &&
|
|
baseType.GetGenericTypeDefinition() == typeof(XBaseEntity<>))
|
|
{
|
|
result = true;
|
|
break;
|
|
}
|
|
|
|
//
|
|
baseType = baseType.BaseType;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\IQueryableExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Constants;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Extensions
|
|
{
|
|
public static class IQueryableExtensions
|
|
{
|
|
/// <summary>
|
|
/// Apply Search Filter on a Query
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="filter"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IQueryable<T> ApplyFilter<T, TKey>(
|
|
this IQueryable<T> source,
|
|
string filter
|
|
)
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
// Apply Filter ...
|
|
return source.Where(r => r.PropValuesContains(filter));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Search Filter on a Query
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="filter"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async Task<IQueryable<T>> ApplyFilterAsync<T, TKey>(
|
|
this IQueryable<T> source,
|
|
string filter
|
|
)
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
// Where Clause ...
|
|
Expression<Func<T, bool>> whereClause = r => r
|
|
.PropValuesContains(filter);
|
|
|
|
//
|
|
// Generate Where Function ...
|
|
var whereFunc = whereClause.Compile();
|
|
|
|
//
|
|
// Get Enumerable ...
|
|
var enumerator = source
|
|
.AsAsyncEnumerable();
|
|
|
|
//
|
|
var result = new List<T>();
|
|
await
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
var isApproved = whereFunc(entity);
|
|
if (isApproved)
|
|
{
|
|
result.Add(entity);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result.AsQueryable();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Search Filter on a Enumerable
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="filter"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static async Task<IEnumerable<T>> ApplyFilterAsync<T, TKey>(
|
|
this IEnumerable<T> source,
|
|
string filter
|
|
)
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
// Where Clause ...
|
|
Expression<Func<T, bool>> whereClause = r => r
|
|
.PropValuesContains(filter);
|
|
|
|
//
|
|
// Generate Where Function ...
|
|
var whereFunc = whereClause.Compile();
|
|
|
|
//
|
|
// Get Enumerable ...
|
|
var enumerator = source
|
|
.ToList()
|
|
.AsQueryable();
|
|
|
|
//
|
|
var result = new List<T>();
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
var isApproved = whereFunc(entity);
|
|
if (isApproved)
|
|
{
|
|
result.Add(entity);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result
|
|
.AsEnumerable();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Search Filter on a Enumerable
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="filter"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ApplyFilter<T>(
|
|
this IEnumerable<T> source,
|
|
string filter
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
// Apply Filter ...
|
|
return source.Where(r => r.PropValuesContains(filter));
|
|
}
|
|
|
|
/// <summary>
|
|
/// provide a way to Order an IQueryable by string FieldName ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="propertyName"></param>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <returns></returns>
|
|
public static IOrderedQueryable<TSource> OrderBy<TSource>(
|
|
this IQueryable<TSource> query,
|
|
string propertyName
|
|
)
|
|
{
|
|
//
|
|
var entityType = typeof(TSource);
|
|
|
|
//
|
|
// Create x => x.PropName
|
|
var propertyInfo = entityType.GetProperty(propertyName);
|
|
if (propertyInfo.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
ParameterExpression arg = Expression.Parameter(entityType, "x");
|
|
MemberExpression property = Expression.Property(arg, propertyName);
|
|
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
|
|
|
//
|
|
// Get System.Linq.Queryable.OrderBy() method.
|
|
var enumarableType = typeof(System.Linq.Queryable);
|
|
var method = enumarableType.GetMethods()
|
|
.Where(m => m.Name == "OrderBy" && m.IsGenericMethodDefinition)
|
|
.Where(m =>
|
|
{
|
|
//
|
|
var parameters = m.GetParameters().ToList();
|
|
|
|
//
|
|
// Put more restriction here to ensure selecting the right overload
|
|
return parameters.Count == 2; // overload that has 2 parameters
|
|
}).Single();
|
|
|
|
//
|
|
// The linq's OrderBy<TSource, TKey> has two generic types, which provided here ...
|
|
MethodInfo genericMethod = method
|
|
.MakeGenericMethod(entityType, propertyInfo.PropertyType);
|
|
|
|
/*
|
|
Call query.OrderBy(selector), with query and selector: x=> x.PropName
|
|
Note that we pass the selector as Expression to the method and we don't compile it.
|
|
|
|
By doing so EF can extract "order by" columns and generate SQL for it.
|
|
*/
|
|
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
|
.Invoke(genericMethod, new object[] { query, selector });
|
|
|
|
//
|
|
return newQuery;
|
|
}
|
|
|
|
/// <summary>
|
|
/// provide a way to Order an IEnumerable by string FieldName ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="propertyName"></param>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <returns></returns>
|
|
public static IOrderedEnumerable<TSource> OrderBy<TSource>(
|
|
this IEnumerable<TSource> query,
|
|
string propertyName
|
|
)
|
|
{
|
|
//
|
|
var entityType = typeof(TSource);
|
|
var propertyInfo = entityType.GetProperty(propertyName);
|
|
if (propertyInfo.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return query.OrderBy(x => propertyInfo.GetValue(x, null));
|
|
}
|
|
|
|
/// <summary>
|
|
/// provide a way to Order an IQueryable by string FieldName ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="propertyName"></param>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <returns></returns>
|
|
public static IOrderedQueryable<TSource> OrderByDescending<TSource>(
|
|
this IQueryable<TSource> query,
|
|
string propertyName
|
|
)
|
|
{
|
|
//
|
|
var entityType = typeof(TSource);
|
|
|
|
//
|
|
// Create x => x.PropName
|
|
var propertyInfo = entityType.GetProperty(propertyName);
|
|
if (propertyInfo.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
ParameterExpression arg = Expression.Parameter(entityType, "x");
|
|
MemberExpression property = Expression.Property(arg, propertyName);
|
|
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
|
|
|
//
|
|
// Get System.Linq.Queryable.OrderBy() method.
|
|
var enumarableType = typeof(System.Linq.Queryable);
|
|
var method = enumarableType.GetMethods()
|
|
.Where(m => m.Name == "OrderByDescending" && m.IsGenericMethodDefinition)
|
|
.Where(m =>
|
|
{
|
|
//
|
|
var parameters = m.GetParameters().ToList();
|
|
|
|
//
|
|
// Put more restriction here to ensure selecting the right overload
|
|
return parameters.Count == 2; // overload that has 2 parameters
|
|
}).Single();
|
|
|
|
//
|
|
// The linq's OrderBy<TSource, TKey> has two generic types, which provided here ...
|
|
MethodInfo genericMethod = method
|
|
.MakeGenericMethod(entityType, propertyInfo.PropertyType);
|
|
|
|
/*
|
|
Call query.OrderBy(selector), with query and selector: x=> x.PropName
|
|
Note that we pass the selector as Expression to the method and we don't compile it.
|
|
|
|
By doing so EF can extract "order by" columns and generate SQL for it.
|
|
*/
|
|
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
|
.Invoke(genericMethod, new object[] { query, selector });
|
|
|
|
//
|
|
return newQuery;
|
|
}
|
|
|
|
/// <summary>
|
|
/// provide a way to Order an IEnumerable by string FieldName ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="propertyName"></param>
|
|
/// <typeparam name="TSource"></typeparam>
|
|
/// <returns></returns>
|
|
public static IOrderedEnumerable<TSource> OrderByDescending<TSource>(
|
|
this IEnumerable<TSource> query,
|
|
string propertyName
|
|
)
|
|
{
|
|
//
|
|
var entityType = typeof(TSource);
|
|
var propertyInfo = entityType.GetProperty(propertyName);
|
|
if (propertyInfo.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return query.OrderByDescending(x => propertyInfo.GetValue(x, null));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Sorting on a query
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sortBy"></param>
|
|
/// <param name="isAscending"></param>
|
|
/// <param name="columnsMap"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IQueryable<T> ApplySorting<T, TKey>(
|
|
this IQueryable<T> source,
|
|
string sortBy,
|
|
bool isAscending,
|
|
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
|
|
)
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
//
|
|
columnsMap = source.FirstOrDefault()
|
|
.GetDefaultColumnsMap();
|
|
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
return source;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate SortBy ...
|
|
var sortByItem = columnsMap.Keys
|
|
.FirstOrDefault(p =>
|
|
p.ToNormalString() == sortBy.ToNormalString());
|
|
if (sortByItem.IsNullOrEmpty())
|
|
{
|
|
return source;
|
|
}
|
|
|
|
//
|
|
// Apply Sorting ...
|
|
if (isAscending)
|
|
{
|
|
return source.OrderBy(sortByItem);
|
|
}
|
|
else
|
|
{
|
|
return source.OrderByDescending(sortByItem);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Sorting on a query
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sortBy"></param>
|
|
/// <param name="isAscending"></param>
|
|
/// <param name="columnsMap"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ApplySorting<T, TKey>(
|
|
this IEnumerable<T> source,
|
|
string sortBy,
|
|
bool isAscending,
|
|
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
|
|
)
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
//
|
|
columnsMap = source.FirstOrDefault()
|
|
.GetDefaultColumnsMap();
|
|
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
return source;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate SortBy ...
|
|
var sortByItem = columnsMap.Keys
|
|
.FirstOrDefault(p =>
|
|
p.ToNormalString() == sortBy.ToNormalString());
|
|
if (sortByItem.IsNullOrEmpty())
|
|
{
|
|
return source;
|
|
}
|
|
|
|
//
|
|
// Apply Sorting ...
|
|
if (isAscending)
|
|
{
|
|
return source.OrderBy(sortByItem);
|
|
}
|
|
else
|
|
{
|
|
return source.OrderByDescending(sortByItem);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Sorting on a Enumerable
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="sortBy"></param>
|
|
/// <param name="isAscending"></param>
|
|
/// <param name="columnsMap"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ApplySorting<T>(
|
|
this IEnumerable<T> source,
|
|
string sortBy,
|
|
bool isAscending,
|
|
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
|
|
)
|
|
where T : class
|
|
{
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
//
|
|
columnsMap = source.FirstOrDefault()
|
|
.GetDefaultColumnsMap();
|
|
|
|
//
|
|
if (columnsMap == null)
|
|
{
|
|
return source;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate SortBy ...
|
|
var sortByItem = columnsMap.Keys
|
|
.FirstOrDefault(p =>
|
|
p.ToNormalString() == sortBy.ToNormalString());
|
|
if (sortByItem.IsNullOrEmpty())
|
|
{
|
|
return source;
|
|
}
|
|
|
|
//
|
|
// Apply Sorting ...
|
|
if (isAscending)
|
|
{
|
|
return source.OrderBy(sortByItem);
|
|
}
|
|
else
|
|
{
|
|
return source.OrderByDescending(sortByItem);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Paging on a qury
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="page"></param>
|
|
/// <param name="pageSize"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IQueryable<T> ApplyPaging<T>(
|
|
this IQueryable<T> source,
|
|
int? page,
|
|
int? pageSize
|
|
)
|
|
{
|
|
//
|
|
if (!page.HasValue ||
|
|
page <= 0)
|
|
{
|
|
page = 1;
|
|
}
|
|
|
|
//
|
|
if (!pageSize.HasValue ||
|
|
pageSize <= 0 ||
|
|
pageSize > XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE)
|
|
{
|
|
pageSize = XDataServiceConstants.DEFAULT_PAGE_SIZE;
|
|
}
|
|
|
|
//
|
|
var pageVal = page.GetValueOrDefault();
|
|
var pageSizeVal = pageSize.GetValueOrDefault();
|
|
|
|
//
|
|
return source
|
|
.Skip((pageVal - 1) * pageSizeVal)
|
|
.Take(pageSizeVal);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply Paging on a Enumerable
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="page"></param>
|
|
/// <param name="pageSize"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> ApplyPaging<T>(
|
|
this IEnumerable<T> source,
|
|
int? page,
|
|
int? pageSize
|
|
)
|
|
{
|
|
//
|
|
if (!page.HasValue ||
|
|
page <= 0)
|
|
{
|
|
page = 1;
|
|
}
|
|
|
|
//
|
|
if (!pageSize.HasValue ||
|
|
pageSize <= 0 ||
|
|
pageSize > XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE)
|
|
{
|
|
pageSize = XDataServiceConstants.DEFAULT_PAGE_SIZE;
|
|
}
|
|
|
|
//
|
|
var pageVal = page.GetValueOrDefault();
|
|
var pageSizeVal = pageSize.GetValueOrDefault();
|
|
|
|
//
|
|
return source
|
|
.Skip((pageVal - 1) * pageSizeVal)
|
|
.Take(pageSizeVal);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count Query Pages based on Specified Total Number ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <returns></returns>
|
|
public static int CountPages(this XQuery source, int totalItems)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Validate and Calculate ...
|
|
if (!source.IsNull() && source.PageSize > 0 && totalItems > 0)
|
|
{
|
|
//
|
|
result = totalItems / source.PageSize;
|
|
if (totalItems % source.PageSize > 0)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Normalize an XQuery based on Data Service Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XQuery NormalizeQuery(
|
|
this XQuery source,
|
|
XDataServiceConfiguration configuration //
|
|
)
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
source = new XQuery();
|
|
}
|
|
|
|
//
|
|
// Page Size Normalization ...
|
|
if (source.PageSize < configuration.PagingConfiguration.MinAvailablePageSize)
|
|
{
|
|
source.PageSize = configuration.PagingConfiguration.MinAvailablePageSize;
|
|
}
|
|
if (source.PageSize > configuration.PagingConfiguration.MaxAvailablePageSize)
|
|
{
|
|
source.PageSize = configuration.PagingConfiguration.MaxAvailablePageSize;
|
|
}
|
|
|
|
//
|
|
return source;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XDatabaseDescriptorExtensions.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xDataService.Constants;
|
|
using xDataService.Models;
|
|
|
|
namespace xDataService.Extensions
|
|
{
|
|
public static class XDatabaseDescriptorExtensions
|
|
{
|
|
/// <summary>
|
|
/// Validate a Database Descriptor ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this XDatabaseDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
!source.IsNull() &&
|
|
!source.Name.IsNullOrEmpty();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chack a Descriptor Has Provider or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasProvider(this XDatabaseDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.Provider != XDbProviders.None;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has EF Core Context or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasContext(this XDatabaseDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.HasProvider() &&
|
|
source.Provider != XDbProviders.MongoDB &&
|
|
!source.Context.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has Repositories or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasRepositories(this XDatabaseDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.HasProvider() &&
|
|
!source.Repositories.IsNull() &&
|
|
source.Repositories.HasChild();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has MongoDB Convention Packs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasConventionPacks(this XDatabaseDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.HasProvider() &&
|
|
source.Provider == XDbProviders.MongoDB &&
|
|
!source.ConventionPacks.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XDataServiceConfigurationExtensions.cs
|
|
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Constants;
|
|
|
|
namespace xDataService.Extensions {
|
|
public static class XDataServiceConfigurationExtensions {
|
|
/// <summary>
|
|
/// Extract Provider enum from Provider Type ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XDbProviders ToDbProvider (this string source) {
|
|
//
|
|
if (source.IsNullOrEmpty ()) {
|
|
return XDbProviders.None;
|
|
}
|
|
|
|
//
|
|
source = source.ToNormalString ();
|
|
|
|
//
|
|
var result = source == ProviderType.MySQL.ToNormalString () ?
|
|
XDbProviders.MySQL :
|
|
source == ProviderType.SQLite.ToNormalString () ?
|
|
XDbProviders.SQLite :
|
|
source == ProviderType.SQLServer.ToNormalString () ?
|
|
XDbProviders.SQLServer :
|
|
source == ProviderType.MongoDB.ToNormalString () ?
|
|
XDbProviders.MongoDB :
|
|
XDbProviders.None;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Mongo URI from ConnectionString
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetMongoDbURI (this XDataBaseConfiguration source) {
|
|
//
|
|
var parts = source.GetConnectionParts ();
|
|
var result = parts
|
|
.Where (p => p.Trim ().StartsWith ("Uri="))
|
|
.FirstOrDefault ();
|
|
result = result.Replace ("Uri=", "").Trim ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Mongo Database Name from Connaction string
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string GetMongoDbDatabase (this XDataBaseConfiguration source) {
|
|
//
|
|
var parts = source.GetConnectionParts ();
|
|
var result = parts
|
|
.Where (p => p.Trim ().StartsWith ("Database="))
|
|
.FirstOrDefault ();
|
|
result = result.Replace ("Database=", "").Trim ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static string[] GetConnectionParts (this XDataBaseConfiguration source) {
|
|
//
|
|
var result = source.ConnectionString.Split (';');
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XGraphQLExtensions.cs
|
|
|
|
using GraphQL;
|
|
using GraphQL.Types;
|
|
using xDataService.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Extensions {
|
|
public static class XGraphQLExtensions {
|
|
public static TKey GetIdArgument<TKey> (this IResolveFieldContext<object> source) {
|
|
return source.GetArgument<TKey> (XGraphQLHelper.GetIdArgument<IntGraphType>().Name);
|
|
}
|
|
|
|
public static bool GetIgnoreSoftDeletedArgument<T> (this IResolveFieldContext<T> source) {
|
|
return source.GetArgument<bool> (XGraphQLHelper.IgnoreSoftDeletedArgument.Name);
|
|
}
|
|
|
|
public static string GetSearchQueryArgument<T> (this IResolveFieldContext<T> source) {
|
|
return source.GetArgument<string> (XGraphQLHelper.SearchQueryArgument.Name);
|
|
}
|
|
|
|
public static XQuery GetQueryArgument<T> (this IResolveFieldContext<T> source) {
|
|
return source.GetArgument<XQuery> (XGraphQLHelper.QueryArgument.Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XMongoDbExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using MongoDB.Driver.Core.Bindings;
|
|
using MongoDB.Driver.Core.Clusters;
|
|
using MongoDB.Driver.Core.Servers;
|
|
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
|
|
using MongoDB.Driver.Linq;
|
|
using xDataService.Mongo;
|
|
|
|
namespace xDataService.Extensions {
|
|
public static class XMongoDbExtensions {
|
|
public static Guid ToGuid (this ObjectId source) {
|
|
//
|
|
var bytes = source
|
|
.ToByteArray ()
|
|
.Concat (new byte[] { 5, 5, 5, 5 })
|
|
.ToArray ();
|
|
|
|
//
|
|
var result = new Guid (bytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static ObjectId ToObjectId (this Guid source) {
|
|
//
|
|
var bytes = source
|
|
.ToByteArray ()
|
|
.Take (12)
|
|
.ToArray ();
|
|
|
|
//
|
|
var result = new ObjectId (bytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static IAsyncEnumerable<T> ToAsyncEnumerable<T> (this IAsyncCursorSource<T> asyncCursorSource) {
|
|
return new XAsyncEnumerableAdapter<T> (asyncCursorSource);
|
|
}
|
|
|
|
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T> (this IAsyncCursor<T> source) {
|
|
while (await source.MoveNextAsync ()) {
|
|
foreach (var current in source.Current) {
|
|
yield return current;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static XMongoAsyncCursor<T> ToAsyncCursor<T> (this IQueryable<T> source) {
|
|
return new XMongoAsyncCursor<T> (source);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XReferenceExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xDataService.Models;
|
|
|
|
namespace xDataService.Extensions
|
|
{
|
|
public static class XReferenceExtensions
|
|
{
|
|
/// <summary>
|
|
/// Converts an XReference<T> to String Representation ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="splitter"></param>
|
|
/// <returns></returns>
|
|
public static string ToXReferenceString<T>(
|
|
this XReference<T> source,
|
|
char? splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
// Normalize Splitter ...
|
|
if (!splitter.HasValue)
|
|
{
|
|
splitter = '_';
|
|
}
|
|
|
|
//
|
|
if (!source.IsNullOrDefault() && source.Index >= 0 && !source.ReferencedTo.IsNull())
|
|
{
|
|
result = $"{source.ProvidedFor}{splitter.Value}{source.ReferencedTo}{splitter.Value}{source.Index}";
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse an String and Extract to XReference<T> if it's Described ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="splitter"></param>
|
|
/// <returns></returns>
|
|
public static XReference<T> FromXReference<T>(
|
|
this string source,
|
|
char? splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
XReference<T> result = null;
|
|
|
|
//
|
|
// Normalize Splitter ...
|
|
if (!splitter.HasValue)
|
|
{
|
|
splitter = '_';
|
|
}
|
|
|
|
//
|
|
if (!source.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var parts = source.Split(splitter.Value);
|
|
if (parts.Count() >= 3)
|
|
{
|
|
//
|
|
T referencedTo;
|
|
try
|
|
{
|
|
referencedTo = (T)Convert.ChangeType(parts[1], typeof(T));
|
|
} catch
|
|
{
|
|
referencedTo = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(parts[1]);
|
|
}
|
|
|
|
//
|
|
// Parse String Parts ...
|
|
result = new XReference<T>
|
|
{
|
|
ReferencedTo = referencedTo,
|
|
Index = (int)Convert.ChangeType(parts[2], typeof(int)),
|
|
ProvidedFor = (string)Convert.ChangeType(parts[0], typeof(string)),
|
|
};
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a Collection of XReference<T> to it's String Representation ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static string ToXReferenceString<T>(this IEnumerable<XReference<T>> source)
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
if (!source.IsNull() && source.HasChild())
|
|
{
|
|
//
|
|
var stringList = new List<string>();
|
|
foreach (var s in source)
|
|
{
|
|
//
|
|
var sr = ToXReferenceString(s);
|
|
if (!sr.IsNullOrEmpty())
|
|
{
|
|
stringList.Add(sr);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = stringList.ToListString();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
public static string ToXReferenceString<T>(this ICollection<XReference<T>> source)
|
|
{
|
|
//
|
|
var result = source
|
|
.AsEnumerable()
|
|
.ToXReferenceString();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
public static string ToXReferenceString<T>(this IList<XReference<T>> source)
|
|
{
|
|
//
|
|
var result = source
|
|
.AsEnumerable()
|
|
.ToXReferenceString();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse an string to XReference<T> Collection Representation ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<T>> ParseXReferenceList<T>(this string source)
|
|
{
|
|
//
|
|
var result = new List<XReference<T>>();
|
|
|
|
//
|
|
if (!source.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var stringList = source.ParseListString<string>();
|
|
if (!stringList.IsNull() && stringList.HasChild())
|
|
{
|
|
//
|
|
foreach (var s in stringList)
|
|
{
|
|
//
|
|
var sr = FromXReference<T>(s);
|
|
if (!sr.IsNullOrDefault())
|
|
{
|
|
result.Add(sr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XRepositoryDescriptorExtensions.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Extensions
|
|
{
|
|
public static class XRepositoryDescriptorExtensions
|
|
{
|
|
//
|
|
#region Hasers ...
|
|
/// <summary>
|
|
/// Validate a Descriptor ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValid(this XRepositoryDescriptor source)
|
|
{
|
|
var result =
|
|
!source.IsNull() &&
|
|
!source.Key.IsNull() &&
|
|
!source.Entity.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has Events Service or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasEvents(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
!source.EventsService.IsNull() &&
|
|
!source.EventsImplementation.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has EF Core Context or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasContext(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
!source.Context.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has GraphQL Support or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasGraphSupport(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.HasRepository() &&
|
|
!source.GraphType.IsNull() &&
|
|
!source.GraphQuery.IsNull() &&
|
|
!source.GraphSchema.IsNull() &&
|
|
!source.GraphTypeKey.IsNull() &&
|
|
!source.GraphTypeHelperService.IsNull() &&
|
|
!source.GraphTypeHelperImplementation.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has Key Generator Service or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasKeyGenerator(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
!source.KeyGeneratorService.IsNull() &&
|
|
!source.KeyGeneratorImplementation.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has Repository Service or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasRepository(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
!source.RepositoryService.IsNull() &&
|
|
!source.RepositoryImplementation.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Descriptor Has Seeder or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool HasSeeder(this XRepositoryDescriptor source)
|
|
{
|
|
//
|
|
var result =
|
|
source.IsValid() &&
|
|
source.HasRepository() &&
|
|
!source.SeederService.IsNull() &&
|
|
!source.SeederImplementation.IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Builders ...
|
|
public static XRepositoryDescriptor AddEntity<TEntity, TKey>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
source = new XRepositoryDescriptor();
|
|
}
|
|
|
|
//
|
|
source.Key = typeof(TKey);
|
|
source.Entity = typeof(TEntity);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.EventsService = typeof(TEventsService);
|
|
source.EventsImplementation = typeof(TEventsImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.KeyGeneratorService = typeof(TKeyGeneratorService);
|
|
source.KeyGeneratorImplementation = typeof(TKeyGeneratorImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddSeeder<TEntity, TKey, TSeederService, TSeederImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.SeederService = typeof(TSeederService);
|
|
source.SeederImplementation = typeof(TSeederImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddEFRepository<TEntity, TKey, TContext, TRepositoryService, TRepositoryImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TContext : XDbContext
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseEFRepository<TEntity, TKey, TContext>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.RepositoryService = typeof(TRepositoryService);
|
|
source.RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddMongoRepository<TEntity, TKey, TRepositoryService, TRepositoryImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseMongoRepository<TEntity, TKey>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.RepositoryService = typeof(TRepositoryService);
|
|
source.RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XRepositoryDescriptor AddInMemoryRepository<TEntity, TKey, TRepositoryService, TRepositoryImplementation>(
|
|
this XRepositoryDescriptor source
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseInMemoryRepository<TEntity, TKey>
|
|
{
|
|
//
|
|
if (source.IsNull())
|
|
{
|
|
//
|
|
source = new XRepositoryDescriptor();
|
|
source = source.AddEntity<TEntity, TKey>();
|
|
}
|
|
|
|
//
|
|
source.RepositoryService = typeof(TRepositoryService);
|
|
source.RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\GraphQL\XBaseGraphObjectType.cs
|
|
|
|
using GraphQL.Types;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.GraphQL
|
|
{
|
|
/// <summary>
|
|
/// Base Entity GraphType Object ...
|
|
/// </summary>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseGraphObjectType<TEntity, TKey> : ObjectGraphType<TEntity>
|
|
where TEntity : XBaseEntity<TKey> {
|
|
public XBaseGraphObjectType () {
|
|
//
|
|
Name = $"{typeof(TEntity).Name}GraphType";
|
|
|
|
//
|
|
Field (x => x.Id);
|
|
Field (x => x.Deleted);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\GraphQL\XBaseGraphQLEventType.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.GraphQL {
|
|
public class XBaseGraphQLEventType<TEntity, TKey, TGraphType> : ObjectGraphType<XBaseEventModel<TEntity>>
|
|
where TGraphType : IGraphType
|
|
where TEntity : XBaseEntity<TKey> {
|
|
public XBaseGraphQLEventType () {
|
|
//
|
|
Name = nameof (XBaseGraphQLEventType<TEntity, TKey, TGraphType>);
|
|
|
|
//
|
|
Field (x => x.Model, type : typeof (TGraphType));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\GraphQL\XBaseGraphQLQuery.cs
|
|
|
|
using System;
|
|
using System.Linq.Expressions;
|
|
using GraphQL.Types;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Constants;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.GraphQL
|
|
{
|
|
public abstract class XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey> : ObjectGraphType, IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : IGraphType
|
|
where TGraphKey : IGraphType
|
|
{
|
|
//
|
|
protected readonly XDataServiceConfiguration configuration;
|
|
protected readonly IXBaseRepository<TEntity, TKey> repository;
|
|
protected readonly IXBaseGraphQLTypeHelper<TEntity, TKey> helper;
|
|
|
|
//
|
|
public XBaseGraphQLQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
IXBaseGraphQLTypeHelper<TEntity, TKey> helper
|
|
)
|
|
{
|
|
//
|
|
this.helper = helper;
|
|
this.repository = repository;
|
|
this.configuration = configuration;
|
|
|
|
//
|
|
Name = GetType().Name;
|
|
|
|
//
|
|
#region Retrieve ...
|
|
//
|
|
// Get ...
|
|
FieldAsync<TGraph>(
|
|
name: helper.GetInQuerySingleName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.GetIdArgument<TGraphKey>(),
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async context =>
|
|
await repository
|
|
.GetAsync(
|
|
includeBuilder: null,
|
|
id: context.GetIdArgument<TKey>(),
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
.ToDynamicObject()
|
|
);
|
|
|
|
//
|
|
// GetAll ...
|
|
FieldAsync<ListGraphType<TGraph>>(
|
|
name: helper.GetInQueryCollectionName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async context =>
|
|
await repository
|
|
.GetAllAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
.ToDynamicObject()
|
|
);
|
|
|
|
//
|
|
// FindOne ...
|
|
FieldAsync<TGraph>(
|
|
name: helper.GetFindOneName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.SearchQueryArgument,
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async (context) =>
|
|
{
|
|
//
|
|
var searchQuery = context.GetSearchQueryArgument();
|
|
Expression<Func<TEntity, bool>> whereClase = pe => pe
|
|
.PropValuesContains(searchQuery);
|
|
|
|
//
|
|
return await repository
|
|
.FindOneAsync(
|
|
includeBuilder: null,
|
|
predicate: whereClase,
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
.ToDynamicObject();
|
|
}
|
|
);
|
|
|
|
//
|
|
// FindMany ...
|
|
FieldAsync<ListGraphType<TGraph>>(
|
|
name: helper.GetFindManyName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.SearchQueryArgument,
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async (context) =>
|
|
{
|
|
//
|
|
var searchQuery = context.GetSearchQueryArgument();
|
|
Expression<Func<TEntity, bool>> whereClase = pe => pe
|
|
.PropValuesContains(searchQuery);
|
|
|
|
//
|
|
return await repository
|
|
.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: whereClase,
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
.ToDynamicObject();
|
|
}
|
|
);
|
|
|
|
//
|
|
// Query ...
|
|
FieldAsync<XGraphQueryResult<TEntity, TGraph>>(
|
|
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<IntGraphType>(
|
|
name: helper.GetCountName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async context =>
|
|
await repository
|
|
.CountAsync(
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
);
|
|
|
|
//
|
|
// Exists ...
|
|
FieldAsync<BooleanGraphType>(
|
|
name: helper.GetExistsName(),
|
|
arguments: new QueryArguments(
|
|
XGraphQLHelper.GetIdArgument<TGraphKey>(),
|
|
XGraphQLHelper.IgnoreSoftDeletedArgument
|
|
),
|
|
resolve: async context =>
|
|
await repository.IsExistsAsync(
|
|
id: context.GetIdArgument<TKey>(),
|
|
ignoreSoftDeleteds: context.GetIgnoreSoftDeletedArgument()
|
|
)
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\GraphQL\XBaseGraphQLSubscription.cs
|
|
|
|
using System.Collections.Generic;
|
|
using GraphQL.Resolvers;
|
|
using GraphQL.Types;
|
|
using xCommons.Extensions;
|
|
using xDataService.Providers;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.GraphQL {
|
|
public abstract class XBaseGraphQLSubscription<TEntity, TKey, TGraph> : ObjectGraphType
|
|
where TGraph : IGraphType
|
|
where TEntity : XBaseEntity<TKey> {
|
|
public XBaseGraphQLSubscription (IXBaseRepositoryEvents<TEntity> eventProvider = null) {
|
|
//
|
|
Name = GetType ().Name;
|
|
|
|
//
|
|
// Check if base repository patter registered ...
|
|
if (!eventProvider.IsNull ()) {
|
|
//
|
|
// Add ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.AddEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<TEntity>> (
|
|
context => context.Source as XBaseEventModel<TEntity>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<TEntity>> (context => {
|
|
return eventProvider.OnAddObservable;
|
|
})
|
|
});
|
|
|
|
//
|
|
// Add Many ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.AddManyEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<IEnumerable<TEntity>>> (
|
|
context => context.Source as XBaseEventModel<IEnumerable<TEntity>>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<IEnumerable<TEntity>>> (context => {
|
|
return eventProvider.OnAddManyObservable;
|
|
})
|
|
});
|
|
|
|
//
|
|
// Update ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.UpdateEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<TEntity>> (
|
|
context => context.Source as XBaseEventModel<TEntity>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<TEntity>> (context => {
|
|
return eventProvider.OnUpdateObservable;
|
|
})
|
|
});
|
|
|
|
//
|
|
// Update Mnay ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.UpdateManyEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<IEnumerable<TEntity>>> (
|
|
context => context.Source as XBaseEventModel<IEnumerable<TEntity>>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<IEnumerable<TEntity>>> (context => {
|
|
return eventProvider.OnUpdateManyObservable;
|
|
})
|
|
});
|
|
|
|
//
|
|
// Remove ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.RemoveEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<TEntity>> (
|
|
context => context.Source as XBaseEventModel<TEntity>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<TEntity>> (context => {
|
|
return eventProvider.OnRemoveObservable;
|
|
})
|
|
});
|
|
|
|
//
|
|
// Remove Many ...
|
|
AddField (new EventStreamFieldType {
|
|
//
|
|
Name = nameof (XBaseRepositoryEvents<TEntity>.RemoveManyEvent),
|
|
Type = typeof (XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
Resolver = new FuncFieldResolver<XBaseEventModel<IEnumerable<TEntity>>> (
|
|
context => context.Source as XBaseEventModel<IEnumerable<TEntity>>
|
|
),
|
|
Subscriber = new EventStreamResolver<XBaseEventModel<IEnumerable<TEntity>>> (context => {
|
|
return eventProvider.OnRemoveManyObservable;
|
|
})
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\GraphQL\XBaseGraphQLTypeHelper.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.GraphQL
|
|
{
|
|
public abstract class XBaseGraphQLTypeHelper<TEntity, TKey> : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
private readonly XDataServiceConfiguration configuration;
|
|
|
|
//
|
|
protected 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()}";
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Helpers\XCursorHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xDataService.Helpers {
|
|
public partial class XCursorHelper {
|
|
public static string ToCursor<T> (T id) {
|
|
//
|
|
// Check Numbers ...
|
|
if (id.ToString ().IsDigits ()) {
|
|
return Convert
|
|
.ToBase64String (BitConverter
|
|
.GetBytes (Convert.ToInt32 (id))
|
|
);
|
|
} else
|
|
//
|
|
// Check Guid ...
|
|
if (id.ToString ().IsGuid ()) {
|
|
return Convert
|
|
.ToBase64String (new Guid (id.ToString ())
|
|
.ToByteArray ());
|
|
} else
|
|
//
|
|
// Assume as String ...
|
|
{
|
|
return Convert
|
|
.ToBase64String (id
|
|
.ToString ().ToBytes ());
|
|
}
|
|
}
|
|
|
|
public static T FromCursor<T> (string cursor) {
|
|
//
|
|
// Check Numbers ...
|
|
var returnType = typeof (T);
|
|
if (returnType == typeof (int) ||
|
|
returnType == typeof (long) ||
|
|
returnType == typeof (decimal)) {
|
|
return Convert.ChangeType ((BitConverter
|
|
.ToInt32 (Convert
|
|
.FromBase64String (cursor),
|
|
0
|
|
))
|
|
.ToDynamicObject (), returnType);
|
|
} else
|
|
//
|
|
// Check Guid ...
|
|
if (returnType == typeof (Guid)) {
|
|
return Convert.ChangeType ((new Guid (
|
|
Convert.FromBase64String (cursor)
|
|
))
|
|
.ToDynamicObject (), returnType);
|
|
} else
|
|
//
|
|
// Assume as String ...
|
|
{
|
|
return Convert.ChangeType ((
|
|
Convert.FromBase64String (cursor)
|
|
)
|
|
.ToDynamicObject (), returnType);
|
|
}
|
|
}
|
|
|
|
public static (string firstCursor, string lastCursor) GetFirstAndLastCursor<T> (IEnumerable<T> ids) {
|
|
//
|
|
if (ids?.Any () != true) {
|
|
return (null, null);
|
|
}
|
|
|
|
//
|
|
var firstCursor = ToCursor (ids.First ());
|
|
var lastCursor = ToCursor (ids.Last ());
|
|
|
|
//
|
|
return (firstCursor, lastCursor);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Helpers\XDataServiceHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using GraphQL;
|
|
using GraphQL.Server;
|
|
using GraphQL.Server.Ui.Playground;
|
|
using GraphQL.Server.Ui.Voyager;
|
|
using GraphQL.Types;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using MongoDB.Bson.Serialization;
|
|
using MongoDB.Bson.Serialization.Conventions;
|
|
using MySql.EntityFrameworkCore.Extensions;
|
|
using xCommons.Extensions;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.Extensions;
|
|
using xDataService.GraphQL;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Helpers
|
|
{
|
|
public static class XDataServiceHelper
|
|
{
|
|
/// <summary>
|
|
/// Register DbContext ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="databaseDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
public static void AddXDbContext<TContext>(
|
|
IServiceCollection source,
|
|
XDatabaseDescriptor databaseDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var isValid =
|
|
databaseDescriptor.IsValid() &&
|
|
databaseDescriptor.HasProvider();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidConfiguration.Throw();
|
|
}
|
|
|
|
//
|
|
switch (databaseDescriptor.Provider)
|
|
{
|
|
//
|
|
// MySQL ...
|
|
case XDbProviders.MySQL:
|
|
//
|
|
source.AddEntityFrameworkMySQL();
|
|
source.AddDbContext<TContext>(cfg =>
|
|
{
|
|
//
|
|
cfg.UseMySQL(
|
|
databaseDescriptor.ConnectionString,
|
|
databaseDescriptor.OptionsBuilder
|
|
);
|
|
}, lifetime);
|
|
break;
|
|
|
|
//
|
|
// SQLite ...
|
|
case XDbProviders.SQLite:
|
|
//
|
|
source.AddEntityFrameworkSqlite();
|
|
source.AddDbContext<TContext>(cfg =>
|
|
{
|
|
//
|
|
cfg.UseSqlite(
|
|
databaseDescriptor.ConnectionString,
|
|
databaseDescriptor.OptionsBuilder
|
|
);
|
|
}, lifetime);
|
|
break;
|
|
|
|
//
|
|
// Oracle ...
|
|
case XDbProviders.Oracle:
|
|
//
|
|
source.AddEntityFrameworkOracle();
|
|
source.AddDbContext<TContext>(cfg =>
|
|
{
|
|
//
|
|
cfg.UseOracle(
|
|
databaseDescriptor.ConnectionString,
|
|
databaseDescriptor.OptionsBuilder
|
|
);
|
|
}, lifetime);
|
|
break;
|
|
|
|
//
|
|
// SQLServer ...
|
|
case XDbProviders.SQLServer:
|
|
//
|
|
source.AddEntityFrameworkSqlServer();
|
|
source.AddDbContext<TContext>(cfg =>
|
|
{
|
|
//
|
|
cfg.UseSqlServer(
|
|
databaseDescriptor.ConnectionString,
|
|
databaseDescriptor.OptionsBuilder
|
|
);
|
|
}, lifetime);
|
|
break;
|
|
|
|
//
|
|
// Mongo DB ...
|
|
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<long>>(cm =>
|
|
{
|
|
//
|
|
cm.AutoMap();
|
|
cm.MapIdMember(c => c.Id);
|
|
});
|
|
BsonClassMap.RegisterClassMap<XBaseEntity<string>>(cm =>
|
|
{
|
|
//
|
|
cm.AutoMap();
|
|
cm.MapIdMember(c => c.Id);
|
|
});
|
|
#endregion
|
|
|
|
//
|
|
// Check Has Convention Packs ...
|
|
isValid = databaseDescriptor.HasConventionPacks();
|
|
if (isValid)
|
|
{
|
|
//
|
|
ConventionRegistry.Register(
|
|
nameof(
|
|
databaseDescriptor.ConventionPacks
|
|
),
|
|
databaseDescriptor.ConventionPacks,
|
|
type => !type.FullName
|
|
.IsNullOrEmpty()
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
isValid =
|
|
databaseDescriptor.Provider == XDbProviders.MySQL ||
|
|
databaseDescriptor.Provider == XDbProviders.SQLite ||
|
|
databaseDescriptor.Provider == XDbProviders.Oracle ||
|
|
databaseDescriptor.Provider == XDbProviders.SQLServer;
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXUnitOfWorks<TContext>(
|
|
source,
|
|
lifetime
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Repository ...
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<TEntity, TKey>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XInMemoryRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseInMemoryRepository<TEntity, TKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <typeparam name="TSeederService"></typeparam>
|
|
/// <typeparam name="TSeederImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XInMemoryRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TSeederService, TSeederImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseInMemoryRepository<TEntity, TKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
//
|
|
// DbSeeder ...
|
|
isValid = repositoryDescriptor.HasSeeder();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.SeederService,
|
|
repositoryDescriptor.SeederImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XMongoRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseMongoRepository<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <typeparam name="TSeederService"></typeparam>
|
|
/// <typeparam name="TSeederImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XMongoRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TSeederService, TSeederImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseMongoRepository<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
//
|
|
// DbSeeder ...
|
|
isValid = repositoryDescriptor.HasSeeder();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.SeederService,
|
|
repositoryDescriptor.SeederImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TContext
|
|
>(
|
|
IServiceCollection source,
|
|
XEFRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TContext> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TContext : XDbContext
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseEFRepository<TEntity, TKey, TContext>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Repository ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <typeparam name="TRepositoryService"></typeparam>
|
|
/// <typeparam name="TRepositoryImplementation"></typeparam>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <typeparam name="TSeederService"></typeparam>
|
|
/// <typeparam name="TSeederImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXRepository<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TContext,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XEFRepositoryDescriptor<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation, TEventsService, TEventsImplementation, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema, TRepositoryService, TRepositoryImplementation, TContext, TSeederService, TSeederImplementation> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TContext : XDbContext
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseEFRepository<TEntity, TKey, TContext>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
var isValid = repositoryDescriptor.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register KeyGenerator ...
|
|
isValid = repositoryDescriptor.HasKeyGenerator();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXKeyGenerator<TEntity, TKey, TKeyGeneratorService, TKeyGeneratorImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Events ...
|
|
isValid = repositoryDescriptor.HasEvents();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXEvents<TEntity, TKey, TEventsService, TEventsImplementation>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Graph ...
|
|
isValid = repositoryDescriptor.HasGraphSupport();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddXGraphQL<TEntity, TKey, TGraph, TGraphKey, TGraphQuery, TGraphTypeHelperService, TGraphTypeHelperImplementation, TGraphSchema>(
|
|
source,
|
|
repositoryDescriptor,
|
|
lifetime
|
|
);
|
|
}
|
|
|
|
//
|
|
// Register Repository ...
|
|
isValid = repositoryDescriptor.HasRepository();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.RepositoryService,
|
|
repositoryDescriptor.RepositoryImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
//
|
|
// DbSeeder ...
|
|
isValid = repositoryDescriptor.HasSeeder();
|
|
if (isValid)
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.SeederService,
|
|
repositoryDescriptor.SeederImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use GraphQL ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <param name="source"></param>
|
|
/// <param name="graphBasePath"></param>
|
|
/// <param name="graphPath"></param>
|
|
/// <param name="withPlayGround"></param>
|
|
/// <param name="options"></param>
|
|
public static void UseXGraphQL<
|
|
TEntity,
|
|
TKey,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>(
|
|
IApplicationBuilder source,
|
|
string graphBasePath,
|
|
string graphPath,
|
|
bool withPlayGround = false
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
source.UseGraphQL<TGraphSchema>(graphPath);
|
|
source.UseGraphQLWebSockets<TGraphSchema>();
|
|
|
|
//
|
|
if (withPlayGround)
|
|
{
|
|
//
|
|
source.UseGraphQLPlayground(new GraphQLPlaygroundOptions
|
|
{
|
|
Path = "/ui/playground",
|
|
GraphQLEndPoint = graphBasePath
|
|
});
|
|
|
|
//
|
|
source.UseGraphQLVoyager(new GraphQLVoyagerOptions
|
|
{
|
|
Path = "/ui/voyager",
|
|
GraphQLEndPoint = graphBasePath
|
|
});
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Entity Assembly Detector ...
|
|
/// <summary>
|
|
/// Extract Assemblies which Contains Entity ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static List<Assembly> ExtractEntityAssemblies()
|
|
{
|
|
//
|
|
var result = new List<Assembly>();
|
|
|
|
//
|
|
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
foreach (var assembly in allAssemblies)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
bool hasEntity = assembly
|
|
.GetExportedTypes()
|
|
.Any(t => t.IsXEntity());
|
|
if (hasEntity)
|
|
{
|
|
result.Add(assembly);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register All Entities using Model Builder ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public static void RegisterAllEntities(this ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Extract Entity Container Assemblies ...
|
|
var entityAssemblies = ExtractEntityAssemblies();
|
|
foreach(var assembly in entityAssemblies)
|
|
{
|
|
modelBuilder.ApplyConfigurationsFromAssembly(assembly);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Register Unit of Works ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
public static void AddXUnitOfWorks<TContext>(
|
|
IServiceCollection source,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
typeof(IXUnitOfWorks<TContext>),
|
|
typeof(XUnitOfWorks<TContext>),
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Key Generator Service ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorService"></typeparam>
|
|
/// <typeparam name="TKeyGeneratorImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXKeyGenerator<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!source.IsNull() &&
|
|
!repositoryDescriptor.IsNull() &&
|
|
!repositoryDescriptor.KeyGeneratorService.IsNull() &&
|
|
!repositoryDescriptor.KeyGeneratorImplementation.IsNull();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.KeyGeneratorService,
|
|
repositoryDescriptor.KeyGeneratorImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Events Service ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TEventsService"></typeparam>
|
|
/// <typeparam name="TEventsImplementation"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXEvents<
|
|
TEntity,
|
|
TKey,
|
|
TEventsService,
|
|
TEventsImplementation
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!source.IsNull() &&
|
|
!repositoryDescriptor.IsNull() &&
|
|
!repositoryDescriptor.EventsService.IsNull() &&
|
|
!repositoryDescriptor.EventsImplementation.IsNull();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
repositoryDescriptor.EventsService,
|
|
repositoryDescriptor.EventsImplementation,
|
|
lifetime
|
|
)
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register GraphQL Service ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="repositoryDescriptor"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TGraph"></typeparam>
|
|
/// <typeparam name="TGraphKey"></typeparam>
|
|
/// <typeparam name="TGraphQuery"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperService"></typeparam>
|
|
/// <typeparam name="TGraphTypeHelperImplementation"></typeparam>
|
|
/// <typeparam name="TGraphSchema"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXGraphQL<
|
|
TEntity,
|
|
TKey,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>(
|
|
IServiceCollection source,
|
|
XRepositoryDescriptor<TEntity, TKey> repositoryDescriptor,
|
|
ServiceLifetime lifetime = ServiceLifetime.Scoped
|
|
)
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!source.IsNull() &&
|
|
!repositoryDescriptor.IsNull() &&
|
|
!repositoryDescriptor.GraphType.IsNull() &&
|
|
!repositoryDescriptor.GraphQuery.IsNull() &&
|
|
!repositoryDescriptor.GraphSchema.IsNull() &&
|
|
!repositoryDescriptor.GraphTypeKey.IsNull() &&
|
|
!repositoryDescriptor.GraphTypeHelperService.IsNull() &&
|
|
!repositoryDescriptor.GraphTypeHelperImplementation.IsNull();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Register Graph Type ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
lifetime: lifetime, // ServiceLifetime.Singleton,
|
|
serviceType: repositoryDescriptor.GraphType,
|
|
implementationType: repositoryDescriptor.GraphType
|
|
)
|
|
);
|
|
|
|
//
|
|
// Register Graph Events ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
lifetime: lifetime, // ServiceLifetime.Singleton,
|
|
serviceType: typeof(XBaseGraphQLEventType<TEntity, TKey, TGraph>),
|
|
implementationType: typeof(XBaseGraphQLEventType<TEntity, TKey, TGraph>)
|
|
)
|
|
);
|
|
|
|
//
|
|
// Register Graph Type Helper ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
lifetime: ServiceLifetime.Singleton,
|
|
serviceType: repositoryDescriptor.GraphTypeHelperService,
|
|
implementationType: repositoryDescriptor.GraphTypeHelperImplementation
|
|
)
|
|
);
|
|
|
|
//
|
|
// Register Graph Query ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
lifetime: lifetime,
|
|
serviceType: repositoryDescriptor.GraphQuery,
|
|
implementationType: repositoryDescriptor.GraphQuery
|
|
)
|
|
);
|
|
|
|
//
|
|
// Register Graph Schema ...
|
|
source.Add(
|
|
new ServiceDescriptor(
|
|
lifetime: lifetime,
|
|
serviceType: repositoryDescriptor.GraphSchema,
|
|
implementationType: repositoryDescriptor.GraphSchema
|
|
)
|
|
);
|
|
|
|
//
|
|
source.AddScoped<IDocumentExecuter, DocumentExecuter>();
|
|
|
|
//
|
|
// Register Graph Type Schema ...
|
|
var builder = source.GetRegisteredService<IGraphQLBuilder>();
|
|
if (builder.IsNull())
|
|
{
|
|
//
|
|
Action<GraphQLOptions> options = x =>
|
|
{
|
|
//
|
|
x.EnableMetrics = true;
|
|
x.UnhandledExceptionDelegate = context =>
|
|
{
|
|
Console.WriteLine("XGraphQL Error: " + context.OriginalException.Message);
|
|
};
|
|
};
|
|
builder = source.AddGraphQL(options)
|
|
.AddNewtonsoftJson(deserializerSettings => { }, serializerSettings => { })
|
|
.AddWebSockets()
|
|
.AddDataLoader()
|
|
.AddGraphTypes(lifetime);
|
|
}
|
|
builder.AddGraphTypes(
|
|
serviceLifetime: lifetime,
|
|
typeFromAssembly: repositoryDescriptor.GraphSchema
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Helpers\XGraphQLHelper.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Constants {
|
|
public static class XGraphQLHelper {
|
|
public static QueryArgument<TKey> GetIdArgument<TKey> ()
|
|
where TKey : IGraphType {
|
|
return new QueryArgument<TKey> {
|
|
Name = "id",
|
|
Description = "the id of entity, which you want to retrieve ..."
|
|
};
|
|
}
|
|
|
|
public static QueryArgument<BooleanGraphType> IgnoreSoftDeletedArgument = new QueryArgument<BooleanGraphType> {
|
|
Name = "ignoreSoftDeleteds",
|
|
DefaultValue = true,
|
|
Description = "determines result should ignore soft deleted items or not ..."
|
|
};
|
|
|
|
public static QueryArgument<StringGraphType> SearchQueryArgument = new QueryArgument<StringGraphType> {
|
|
Name = "searchQuery",
|
|
Description = "the value which had to looking for ..."
|
|
};
|
|
|
|
public static QueryArgument<XGraphQueryType> QueryArgument = new QueryArgument<XGraphQueryType> {
|
|
Name = "query",
|
|
DefaultValue = new XQuery (),
|
|
Description = "determines query structure info for retrieving data ..."
|
|
};
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseDbSeeder.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xDataService.Configuration;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// Db Seeder used to seed data on Database on startup time ...
|
|
/// </summary>
|
|
public interface IXBaseDbSeeder<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Holds Entity Name ...
|
|
/// </summary>
|
|
string Entity { get; }
|
|
|
|
/// <summary>
|
|
/// Holds Database Name ...
|
|
/// </summary>
|
|
string Database { get; }
|
|
|
|
/// <summary>
|
|
/// Repository Service for Data Manipulation ...
|
|
/// </summary>
|
|
IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
|
|
/// <summary>
|
|
/// DataServiceConfiguration ...
|
|
/// </summary>
|
|
XDataServiceConfiguration DataServiceConfiguration { get; }
|
|
|
|
/// <summary>
|
|
/// do all seeding action by helping of Repositories here ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
Task Seed();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseGraphQLQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
public interface IXBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : IGraphType
|
|
where TGraphKey : IGraphType
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseGraphQLTypeHelper.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
public interface IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
string GetInQuerySingleName();
|
|
|
|
string GetInQueryCollectionName();
|
|
|
|
string GetFindOneName();
|
|
|
|
string GetFindManyName();
|
|
|
|
string GetQueryName();
|
|
|
|
string GetCountName();
|
|
|
|
string GetExistsName();
|
|
|
|
string GetGraphQLPath(string baseGraphPath = null);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseReferencedProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// in Some Cases we have Entities Which Can Referenced for Specified
|
|
/// Provider and Types ...
|
|
/// this interface Globaly introduce all available Actions for those ...
|
|
///
|
|
/// TKey: type of Provider Models Keys ...
|
|
/// TModel: type of Dto which Referenced ...
|
|
/// </summary>
|
|
public interface IXBaseReferencedProvider<TModel, TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Provider Identifier ...
|
|
/// </summary>
|
|
string Provider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TModel> GetReference(
|
|
TKey providedForId,
|
|
int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TModel>> GetAllReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XReference<TKey>>> GetAllReferencings(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TModel>> QueryReferences(
|
|
XQuery query,
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
TModel model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
TModel model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
TModel model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
TModel model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReferences(
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseRepository.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
public interface IXBaseRepository : IDisposable { }
|
|
|
|
/// <summary>
|
|
/// Base Repository Pattern Contracts in XDashboard's Data Service ...
|
|
/// use for Data Manipulation ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseRepository<T, TKey> : IXBaseRepository
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> AddAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// add or update an Entity (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> AddOrUpdateAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// add a range of new Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Entity values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> UpdateAsync(
|
|
TKey id,
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update a range of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> UpdateRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> RemoveAsync(
|
|
T item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve whole items as queryable ...
|
|
/// </summary>
|
|
/// <param name="asNoTracking">a flag for Tracking behaviour</param>
|
|
/// <param name="predicate">an Expression for Filter Items ...</param>
|
|
/// <param name="orderBuilder">an Order Builder expression for Ordering Query ...</param>
|
|
/// <param name="includeBuilder">an Include Builder expression for Including Navigation Properties ...</param>
|
|
/// <returns></returns>
|
|
IQueryable<T> AsQueryable(
|
|
bool asNoTracking = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<T>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<T> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Entity by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> FindOneAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Entities by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<T>> FindManyAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Entities based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<T>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check an Entity exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Unit Of Work ...
|
|
/// <summary>
|
|
/// Save all unsaved Transactions on DbContext ...
|
|
/// used fo Unit Of Works Design Pattern ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> SaveChangesAsync(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Key ...
|
|
/// <summary>
|
|
/// Retrieve Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
TKey GetKey(T item);
|
|
|
|
/// <summary>
|
|
/// Set Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="id"></param>
|
|
void SetKey(
|
|
ref T item,
|
|
TKey id
|
|
);
|
|
|
|
/// <summary>
|
|
/// Handle Checking Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<T> HandleKeyAsync(
|
|
T item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Detach ...
|
|
/// <summary>
|
|
/// Detach an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
void Detach(T item);
|
|
|
|
/// <summary>
|
|
/// Detach an Enumerable of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
void Detach(IEnumerable<T> items);
|
|
|
|
/// <summary>
|
|
/// Detach a Query Result of Entity ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
void Detach(XQueryResult<T> query);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseRepositoryController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface for Base Repository Actions Providing Using Controllers ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseRepositoryController<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
|
|
//
|
|
#region Add ...
|
|
Task<ActionResult<TEntity>> Add(
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<TEntity>> AddOrUpdate(
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult> AddMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
Task<ActionResult<TEntity>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<IEnumerable<TEntity>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<TEntity>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<IEnumerable<TEntity>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<XQueryResult<TEntity>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
Task<ActionResult<TEntity>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<bool>> UpdateMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
Task<ActionResult<TEntity>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult> RemoveMany(
|
|
[FromBody] XBaseRangeRequest<TEntity> request,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseRepositoryEvents.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xDataService.Models;
|
|
|
|
namespace xDataService.Interfaces {
|
|
public interface IXBaseRepositoryEvents<T> {
|
|
//
|
|
void AddEvent (XBaseEventModel<T> model);
|
|
void UpdateEvent (XBaseEventModel<T> model);
|
|
void RemoveEvent (XBaseEventModel<T> model);
|
|
|
|
//
|
|
void AddManyEvent (XBaseEventModel<IEnumerable<T>> model);
|
|
void UpdateManyEvent (XBaseEventModel<IEnumerable<T>> model);
|
|
void RemoveManyEvent (XBaseEventModel<IEnumerable<T>> model);
|
|
|
|
//
|
|
IObservable<XBaseEventModel<T>> OnAddObservable { get; }
|
|
IObservable<XBaseEventModel<T>> OnUpdateObservable { get; }
|
|
IObservable<XBaseEventModel<T>> OnRemoveObservable { get; }
|
|
|
|
//
|
|
IObservable<XBaseEventModel<IEnumerable<T>>> OnAddManyObservable { get; }
|
|
IObservable<XBaseEventModel<IEnumerable<T>>> OnUpdateManyObservable { get; }
|
|
IObservable<XBaseEventModel<IEnumerable<T>>> OnRemoveManyObservable { get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AutoMapper;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface for Manipulating Data Using Services based on Dto Mapping ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseRepositoryService<TEntity, TDto, TKey> : IDisposable
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
/// <summary>
|
|
/// Mapper Instance ...
|
|
/// </summary>
|
|
IMapper Mapper { get; }
|
|
|
|
/// <summary>
|
|
/// Repository Implementation for Data Manipulations ...
|
|
/// </summary>
|
|
IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
|
|
/// <summary>
|
|
/// Mapping Profile Configuration ...
|
|
///
|
|
/// this Configuration used for Mapping TEntity to Dto and reverse ...
|
|
/// default mapping prepared on Constructing time, other custom maps
|
|
/// must handled manually if required ...
|
|
/// </summary>
|
|
MapperConfiguration MapperConfiguration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// add or update a Dto (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> AddOrUpdateAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// add a range of new Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Dto values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update a range of Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> UpdateRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> RemoveAsync(
|
|
TDto item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Dto by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Dtos by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Dtos based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check a Dto exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXBaseServiceController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface for Base RepositoryService Actions Providing Using Controllers ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseServiceController<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
IXBaseRepositoryService<TEntity, TDto, TKey> RepositoryService { get; }
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
|
|
//
|
|
#region Add ...
|
|
Task<ActionResult<TDto>> Add(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<TDto>> AddOrUpdate(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult> AddMany(
|
|
XBaseRangeRequest<TDto> request,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult<bool>> UpdateMany(
|
|
[FromBody] XBaseRangeRequest<TDto> request,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeletedss = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
Task<ActionResult> RemoveMany(
|
|
[FromBody] XBaseRangeRequest<TDto> request,
|
|
[FromQuery] bool softDelete = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXDatabaseDescriptor.cs
|
|
|
|
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
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXEntityRegisterar.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface to Intruduce Entities for Dynamic Registration ...
|
|
/// </summary>
|
|
public interface IXEntityRegisterar
|
|
{
|
|
/// <summary>
|
|
/// Database Name ...
|
|
/// </summary>
|
|
string Name { get; }
|
|
|
|
/// <summary>
|
|
/// Returns all entity types this plugin wants registered in the DbContext
|
|
/// </summary>
|
|
IEnumerable<Type> GetEntityTypes();
|
|
|
|
/// <summary>
|
|
/// Optional: Apply additional per-entity configuration
|
|
/// </summary>
|
|
void ConfigureEntities(ModelBuilder modelBuilder);
|
|
|
|
/// <summary>
|
|
/// Add XDataService Based Entity to List ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
void AddEntity<TEntity, TKey>()
|
|
where TEntity : XBaseEntity<TKey>;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXKeyGenerator.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// Typed Base Key Generator ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXKeyGenerator<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
bool IsEmpty(TKey id);
|
|
Task<TKey> GenerateKey(
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXSequentialGuid.cs
|
|
|
|
using System;
|
|
|
|
namespace xDataService.Interfaces {
|
|
/// <summary>
|
|
/// this service provide Sequential GUID mechanism for Entity Ids ...
|
|
/// </summary>
|
|
public interface IXSequentialGuid {
|
|
Guid GetCurrentGuid ();
|
|
Guid Next ();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Interfaces\IXUnitOfWorks.cs
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Db;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Interfaces {
|
|
/// <summary>
|
|
/// Provide Unit Of Works Design Pattern for Db Transactions ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <typeparam name="TDbContext"></typeparam>
|
|
public interface IXUnitOfWorks<TDbContext> : IDisposable
|
|
where TDbContext : XDbContext {
|
|
TDbContext DbContext { get; }
|
|
DbSet<T> GetDbSet<T, TKey> () where T : XBaseEntity<TKey>;
|
|
int SaveChanges ();
|
|
Task<int> SaveChangesAsync (
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XBaseEventModel.cs
|
|
|
|
namespace xDataService.Models {
|
|
/// <summary>
|
|
/// Pass Data on Repository Events ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class XBaseEventModel<T> {
|
|
public T Model { get; set; }
|
|
|
|
public XBaseEventModel (T model) {
|
|
Model = model;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XDatabaseDescriptor.cs
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XGraphQueryResult.cs
|
|
|
|
using GraphQL.Types;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Models {
|
|
public class XGraphQueryResult<TEntity, TGraph> : ObjectGraphType<XQueryResult<TEntity>>
|
|
where TGraph : IGraphType {
|
|
public XGraphQueryResult () {
|
|
//
|
|
Name = $"{typeof(TGraph).Name}QueryResult";
|
|
|
|
//
|
|
Field<ListGraphType<TGraph>> (nameof (XQueryResult<TEntity>.Items));
|
|
Field (x => x.Page);
|
|
Field (x => x.PageSize);
|
|
Field (x => x.TotalPages);
|
|
Field (x => x.TotalFilteredItems);
|
|
Field (x => x.TotalItems);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XGraphQueryType.cs
|
|
|
|
using GraphQL.Types;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Models {
|
|
public class XGraphQueryType : InputObjectGraphType<XQuery> {
|
|
public XGraphQueryType () {
|
|
//
|
|
Name = "query";
|
|
|
|
//
|
|
Field (x => x.Filter);
|
|
Field (x => x.ContainsDetail);
|
|
Field (x => x.SortBy);
|
|
Field (x => x.IsAscending);
|
|
Field (x => x.Page);
|
|
Field (x => x.PageSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XReference.cs
|
|
|
|
namespace xDataService.Models
|
|
{
|
|
public class XReference<T>
|
|
{
|
|
public int Index { get; set; }
|
|
public T ReferencedTo { get; set; }
|
|
public string ProvidedFor { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Models\XRepositoryDescriptor.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Db;
|
|
using xDataService.GraphQL;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Models
|
|
{
|
|
/// <summary>
|
|
/// a Global non Generic Repository Descriptor ...
|
|
/// </summary>
|
|
public class XRepositoryDescriptor
|
|
{
|
|
/// <summary>
|
|
/// Entity Key Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type Key { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Entity Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type Entity { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Context Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type Context { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Graph Type Key ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphTypeKey { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Graph Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphType { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Entity Type GraphQL Schema ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphSchema { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Entity GraphQL Type Helper ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphTypeHelperService { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Entity GraphQL Type Helper ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphTypeHelperImplementation { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Entity GrapQL Query ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type GraphQuery { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Event Provider ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type EventsService { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Event Provider ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type EventsImplementation { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Key Generator for Entity ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type KeyGeneratorService { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Key Generator for Entity ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type KeyGeneratorImplementation { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Data Access Design Pattern ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type RepositoryService { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Repository Data Access Design Pattern ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type RepositoryImplementation { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Database Data Seeder ...
|
|
/// </summary>
|
|
public Type SeederService { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Database Data Seeder ...
|
|
/// </summary>
|
|
public Type SeederImplementation { get; set; } = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public class XRepositoryDescriptor<TEntity, TKey> : XRepositoryDescriptor
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
public XRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
Key = typeof(TKey);
|
|
Entity = typeof(TEntity);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation
|
|
> : XRepositoryDescriptor<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
public XRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
KeyGeneratorService = typeof(TKeyGeneratorService);
|
|
KeyGeneratorImplementation = typeof(TKeyGeneratorImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation
|
|
>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
{
|
|
public XRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
EventsService = typeof(TEventsService);
|
|
EventsImplementation = typeof(TEventsImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
GraphType = typeof(TGraph);
|
|
GraphTypeKey = typeof(TGraphKey);
|
|
GraphQuery = typeof(TGraphQuery);
|
|
GraphSchema = typeof(TGraphSchema);
|
|
GraphTypeHelperService = typeof(TGraphTypeHelperService);
|
|
GraphTypeHelperImplementation = typeof(TGraphTypeHelperImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XInMemoryRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseInMemoryRepository<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XInMemoryRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XInMemoryRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseInMemoryRepository<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XInMemoryRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
SeederService = typeof(TSeederService);
|
|
SeederImplementation = typeof(TSeederImplementation);
|
|
|
|
//
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XMongoRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseMongoRepository<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XMongoRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XMongoRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TRepositoryImplementation : XBaseMongoRepository<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XMongoRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
SeederService = typeof(TSeederService);
|
|
SeederImplementation = typeof(TSeederImplementation);
|
|
|
|
//
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XEFRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TContext
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TContext : XDbContext
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseEFRepository<TEntity, TKey, TContext>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XEFRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
Context = typeof(TContext);
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// a Repository Descriptor ...
|
|
/// </summary>
|
|
public class XEFRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema,
|
|
TRepositoryService,
|
|
TRepositoryImplementation,
|
|
TContext,
|
|
TSeederService,
|
|
TSeederImplementation
|
|
> : XRepositoryDescriptor<
|
|
TEntity,
|
|
TKey,
|
|
TKeyGeneratorService,
|
|
TKeyGeneratorImplementation,
|
|
TEventsService,
|
|
TEventsImplementation,
|
|
TGraph,
|
|
TGraphKey,
|
|
TGraphQuery,
|
|
TGraphTypeHelperService,
|
|
TGraphTypeHelperImplementation,
|
|
TGraphSchema
|
|
>
|
|
where TGraphSchema : Schema
|
|
where TContext : XDbContext
|
|
where TGraphKey : IGraphType
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TGraph : XBaseGraphObjectType<TEntity, TKey>
|
|
where TSeederService : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEventsService : IXBaseRepositoryEvents<TEntity>
|
|
where TSeederImplementation : XBaseDbSeeder<TEntity, TKey>
|
|
where TKeyGeneratorService : IXKeyGenerator<TEntity, TKey>
|
|
where TRepositoryService : IXBaseRepository<TEntity, TKey>
|
|
where TEventsImplementation : XBaseRepositoryEvents<TEntity>
|
|
where TKeyGeneratorImplementation : XKeyGenerator<TEntity, TKey>
|
|
where TGraphTypeHelperService : IXBaseGraphQLTypeHelper<TEntity, TKey>
|
|
where TGraphQuery : XBaseGraphQLQuery<TEntity, TKey, TGraph, TGraphKey>
|
|
where TRepositoryImplementation : XBaseEFRepository<TEntity, TKey, TContext>
|
|
where TGraphTypeHelperImplementation : XBaseGraphQLTypeHelper<TEntity, TKey>
|
|
{
|
|
public XEFRepositoryDescriptor() : base()
|
|
{
|
|
//
|
|
SeederService = typeof(TSeederService);
|
|
SeederImplementation = typeof(TSeederImplementation);
|
|
|
|
//
|
|
Context = typeof(TContext);
|
|
RepositoryService = typeof(TRepositoryService);
|
|
RepositoryImplementation = typeof(TRepositoryImplementation);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Mongo\XAsyncEnumerableAdapter.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MongoDB.Driver;
|
|
|
|
namespace xDataService.Mongo {
|
|
public class XAsyncEnumerableAdapter<T> : IAsyncEnumerable<T> {
|
|
//
|
|
private readonly IAsyncCursorSource<T> asyncCursorSource;
|
|
|
|
//
|
|
public XAsyncEnumerableAdapter (IAsyncCursorSource<T> asyncCursorSource) {
|
|
this.asyncCursorSource = asyncCursorSource;
|
|
}
|
|
|
|
//
|
|
public IAsyncEnumerator<T> GetAsyncEnumerator (CancellationToken cancellationToken) =>
|
|
new XAsyncEnumeratorAdapter<T> (asyncCursorSource, cancellationToken);
|
|
}
|
|
|
|
public class XAsyncEnumeratorAdapter<T> : IAsyncEnumerator<T> {
|
|
private readonly IAsyncCursorSource<T> asyncCursorSource;
|
|
private readonly CancellationToken cancellationToken;
|
|
private IAsyncCursor<T> asyncCursor;
|
|
private IEnumerator<T> batchEnumerator;
|
|
|
|
public T Current => batchEnumerator.Current;
|
|
|
|
public XAsyncEnumeratorAdapter (
|
|
IAsyncCursorSource<T> asyncCursorSource,
|
|
CancellationToken cancellationToken
|
|
) {
|
|
//
|
|
this.asyncCursorSource = asyncCursorSource;
|
|
this.cancellationToken = cancellationToken;
|
|
}
|
|
|
|
public async ValueTask<bool> MoveNextAsync () {
|
|
//
|
|
if (asyncCursor == null) {
|
|
asyncCursor = await asyncCursorSource
|
|
.ToCursorAsync (cancellationToken);
|
|
}
|
|
|
|
//
|
|
if (batchEnumerator != null &&
|
|
batchEnumerator.MoveNext ()) {
|
|
return true;
|
|
}
|
|
|
|
//
|
|
if (asyncCursor != null &&
|
|
await asyncCursor.MoveNextAsync (cancellationToken)) {
|
|
//
|
|
batchEnumerator?.Dispose ();
|
|
batchEnumerator = asyncCursor.Current.GetEnumerator ();
|
|
|
|
//
|
|
return batchEnumerator.MoveNext ();
|
|
}
|
|
|
|
//
|
|
return false;
|
|
}
|
|
|
|
public async ValueTask DisposeAsync () {
|
|
//
|
|
await Task.CompletedTask;
|
|
asyncCursor?.Dispose ();
|
|
asyncCursor = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Mongo\XMongoAsyncCursor.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MongoDB.Driver;
|
|
|
|
namespace xDataService.Mongo {
|
|
public class XMongoAsyncCursor<T> : IAsyncCursor<T> {
|
|
public IEnumerable<T> Current { get; }
|
|
private IEnumerator<T> CurrentEnumerator { get; }
|
|
|
|
public XMongoAsyncCursor (IEnumerable<T> source) {
|
|
this.Current = source;
|
|
this.CurrentEnumerator = source.GetEnumerator ();
|
|
}
|
|
|
|
public void Dispose () {
|
|
CurrentEnumerator.Dispose ();
|
|
}
|
|
|
|
public bool MoveNext (CancellationToken cancellationToken = default) {
|
|
return CurrentEnumerator.MoveNext ();
|
|
}
|
|
|
|
public Task<bool> MoveNextAsync (CancellationToken cancellationToken = default) {
|
|
return Task.Run (
|
|
() => CurrentEnumerator.MoveNext (),
|
|
cancellationToken : cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Mongo\XMongoQueryable.cs
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MongoDB.Driver;
|
|
using MongoDB.Driver.Linq;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Mongo {
|
|
public class XMongoQueryable<TEntity, TKey> : IMongoQueryable<TEntity>
|
|
where TEntity : XBaseEntity<TKey> {
|
|
private readonly IMongoCollection<TEntity> collection;
|
|
|
|
public Type ElementType { get; }
|
|
public IQueryable<TEntity> Items { get; }
|
|
public Expression Expression { get; }
|
|
public IQueryProvider Provider { get; }
|
|
|
|
public XMongoQueryable (
|
|
IQueryable<TEntity> items,
|
|
IMongoCollection<TEntity> collection
|
|
) {
|
|
//
|
|
this.Items = items;
|
|
this.collection = collection;
|
|
|
|
//
|
|
Provider = items.Provider;
|
|
Expression = items.Expression;
|
|
ElementType = items.ElementType;
|
|
}
|
|
|
|
public IEnumerator<TEntity> GetEnumerator () {
|
|
return Items.GetEnumerator ();
|
|
}
|
|
|
|
public QueryableExecutionModel GetExecutionModel () {
|
|
return collection.AsQueryable ().GetExecutionModel ();
|
|
}
|
|
|
|
public IAsyncCursor<TEntity> ToCursor (CancellationToken cancellationToken = default) {
|
|
return new XMongoAsyncCursor<TEntity> (Items);
|
|
}
|
|
|
|
public Task<IAsyncCursor<TEntity>> ToCursorAsync (CancellationToken cancellationToken = default) {
|
|
return Task.Run (() => new XMongoAsyncCursor<TEntity> (Items) as IAsyncCursor<TEntity>);
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator () {
|
|
return Items.GetEnumerator ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Mongo\XMongoReadPreferenceResolver.cs
|
|
|
|
using MongoDB.Driver;
|
|
|
|
namespace xDataService.Mongo {
|
|
public static class XMongoReadPreferenceResolver {
|
|
public static ReadPreference GetEffectiveReadPreference (
|
|
IClientSessionHandle session,
|
|
ReadPreference explicitReadPreference,
|
|
ReadPreference defaultReadPreference) {
|
|
if (explicitReadPreference != null) {
|
|
return explicitReadPreference;
|
|
}
|
|
|
|
if (session.IsInTransaction) {
|
|
var transactionReadPreference = session.WrappedCoreSession.CurrentTransaction.TransactionOptions.ReadPreference;
|
|
if (transactionReadPreference != null) {
|
|
return transactionReadPreference;
|
|
}
|
|
}
|
|
|
|
return defaultReadPreference ?? ReadPreference.Primary;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseDbSeeder.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Constants;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
public abstract class XBaseDbSeeder<TEntity, TKey> : IXBaseDbSeeder<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
/// <summary>
|
|
/// Holds Entity Name ...
|
|
/// </summary>
|
|
public string Entity { get; }
|
|
|
|
/// <summary>
|
|
/// Holds Database Name ...
|
|
/// </summary>
|
|
public string Database { get; }
|
|
|
|
/// <summary>
|
|
/// Repository Service for Data Manipulation ...
|
|
/// </summary>
|
|
public IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
|
|
/// <summary>
|
|
/// DataServiceConfiguration ...
|
|
/// </summary>
|
|
public XDataServiceConfiguration DataServiceConfiguration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseDbSeeder(
|
|
string entity,
|
|
string database,
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
)
|
|
{
|
|
//
|
|
this.Entity = entity;
|
|
this.Database = database;
|
|
this.Repository = repository;
|
|
this.DataServiceConfiguration = dataServiceConfiguration;
|
|
}
|
|
#endregion
|
|
|
|
public async Task Seed()
|
|
{
|
|
//
|
|
// Validate Seed ...
|
|
var isValid =
|
|
DataServiceConfiguration.SeedingMode != XDbSeedingMode.None &&
|
|
DataServiceConfiguration
|
|
.Databases
|
|
.Any(db =>
|
|
db.Key == Database &&
|
|
db.Value.SeedItems
|
|
.Any(si =>
|
|
si.Key == Entity &&
|
|
si.Value.HasChild()));
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Extract Seeding Items ...
|
|
var seedItems = DataServiceConfiguration
|
|
.Databases[Database]
|
|
.SeedItems[Entity]
|
|
.ToList();
|
|
foreach (var item in seedItems)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = item
|
|
.ToJSON()
|
|
.FromJSON<TEntity>();
|
|
|
|
//
|
|
// Check Item Exists or not ...
|
|
var isExist = false;
|
|
TEntity exists = null;
|
|
var asyncEnumerable = this.Repository.GetAllAsAsyncEnumerable();
|
|
await foreach (var e in asyncEnumerable)
|
|
{
|
|
//
|
|
isExist = e.IsSameContent(
|
|
dest: entity,
|
|
propertyBlackList: new List<string>
|
|
{
|
|
nameof(entity.Id),
|
|
nameof(entity.Deleted)
|
|
});
|
|
if (isExist)
|
|
{
|
|
exists = e;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Seed Based on Seed Mode ...
|
|
var seedMode = DataServiceConfiguration.SeedingMode;
|
|
switch (seedMode)
|
|
{
|
|
//
|
|
case XDbSeedingMode.AddIfNotExists:
|
|
//
|
|
if (!isExist)
|
|
{
|
|
//
|
|
exists = await Repository.AddAsync(
|
|
item: entity,
|
|
saveChanges: true
|
|
);
|
|
}
|
|
break;
|
|
|
|
//
|
|
case XDbSeedingMode.AddOrUpdate:
|
|
//
|
|
exists = exists.UpdateData(
|
|
updateWith: entity,
|
|
propertyBlackList: new List<string>
|
|
{
|
|
nameof(entity.Id),
|
|
nameof(entity.Deleted)
|
|
}
|
|
);
|
|
|
|
//
|
|
await Repository.AddOrUpdateAsync(exists);
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseEFRepository.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// a Base Repository Pattern Implementation Specially for EF DBs using
|
|
/// EF Core Capabilities ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="TDbContext"></typeparam>
|
|
public abstract class XBaseEFRepository<T, TKey, TDbContext> : IXBaseRepository<T, TKey>
|
|
where T : XBaseEntity<TKey>
|
|
where TDbContext : XDbContext
|
|
{
|
|
//
|
|
#region Properties ...
|
|
//
|
|
public readonly DbSet<T> dbSet;
|
|
private readonly IXKeyGenerator<T, TKey> keyGenerator;
|
|
public readonly IXUnitOfWorks<TDbContext> unitOfWorks;
|
|
public readonly XDataServiceConfiguration configuration;
|
|
private readonly IXBaseRepositoryEvents<T> baseRepositoryEvents;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseEFRepository(
|
|
IXUnitOfWorks<TDbContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXKeyGenerator<T, TKey> keyGenerator = null,
|
|
IXBaseRepositoryEvents<T> baseRepositoryEvents = null
|
|
)
|
|
{
|
|
//
|
|
this.unitOfWorks = unitOfWorks;
|
|
this.keyGenerator = keyGenerator;
|
|
this.configuration = configuration;
|
|
this.dbSet = unitOfWorks.GetDbSet<T, TKey>();
|
|
this.baseRepositoryEvents = baseRepositoryEvents;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> AddAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Handle Key ...
|
|
item = await HandleKeyAsync(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var entry = await dbSet.AddAsync(
|
|
entity: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddEvent(new XBaseEventModel<T>(entry.Entity));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
entry.Entity :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add or update an Entity (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> AddOrUpdateAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(
|
|
id: GetKey(item),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
//
|
|
return await AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
return await UpdateAsync(
|
|
item: item,
|
|
id: GetKey(item),
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// add a range of new Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Preparing Ids and Keys ...
|
|
await dbSet.AddRangeAsync(
|
|
await Task
|
|
.WhenAll(
|
|
items
|
|
.Select(async i => await HandleKeyAsync(i))
|
|
),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddManyEvent(new XBaseEventModel<IEnumerable<T>>(null));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Entity values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> UpdateAsync(
|
|
TKey id,
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Get Exists Entity ...
|
|
var existsEntity = await GetAsync(
|
|
id: id,
|
|
ignoreSoftDeleteds: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Update Data ...
|
|
existsEntity.UpdateData(item);
|
|
var entry = dbSet.Attach(existsEntity);
|
|
entry.State = EntityState.Modified;
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateEvent(new XBaseEventModel<T>(entry.Entity));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
entry.Entity :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a range of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> UpdateRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
items
|
|
.ToList()
|
|
.ForEach(i =>
|
|
{
|
|
var entry = dbSet.Attach(i);
|
|
entry.State = EntityState.Modified;
|
|
});
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateManyEvent(new XBaseEventModel<IEnumerable<T>>(null));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Retrieve Item ...
|
|
var item = await GetAsync(
|
|
id,
|
|
ignoreSoftDeleteds: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (item.IsNullOrDefault())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Handle Remove ...
|
|
EntityEntry<T> entry = null;
|
|
if (softDelete && configuration.EnableSoftDelete)
|
|
{
|
|
//
|
|
item.Deleted = true;
|
|
entry = dbSet.Update(item);
|
|
}
|
|
else
|
|
{
|
|
entry = dbSet.Remove(item);
|
|
}
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.RemoveEvent(new XBaseEventModel<T>(entry.Entity));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
entry.Entity :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> RemoveAsync(
|
|
T item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Handle Remove ...
|
|
if (softDelete && configuration.EnableSoftDelete)
|
|
{
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
item.Deleted = true;
|
|
}
|
|
|
|
//
|
|
dbSet.UpdateRange(items);
|
|
}
|
|
else
|
|
{
|
|
dbSet.RemoveRange(items);
|
|
}
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.RemoveManyEvent(new XBaseEventModel<IEnumerable<T>>(null));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = 0;
|
|
|
|
//
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
//
|
|
result = await dbSet.CountAsync(
|
|
predicate: x => !x.Deleted,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
result = await dbSet.CountAsync(cancellationToken);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
int count = totalItems.HasValue ? totalItems.Value : await CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve whole items as queryable ...
|
|
/// </summary>
|
|
/// <param name="asNoTracking">a flag for Tracking behaviour</param>
|
|
/// <param name="predicate">an Expression for Filter Items ...</param>
|
|
/// <param name="orderBuilder">an Order Builder expression for Ordering Query ...</param>
|
|
/// <param name="includeBuilder">an Include Builder expression for Including Navigation Properties ...</param>
|
|
/// <returns></returns>
|
|
public IQueryable<T> AsQueryable(
|
|
bool asNoTracking = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
var result = dbSet
|
|
.AsQueryable();
|
|
|
|
//
|
|
// Apply Predicate ...
|
|
if (!predicate.IsNull())
|
|
{
|
|
result = result
|
|
.Where(predicate);
|
|
}
|
|
|
|
//
|
|
// Apply Includes ...
|
|
if (!includeBuilder.IsNull())
|
|
{
|
|
result = includeBuilder(result);
|
|
}
|
|
|
|
//
|
|
// Apply Ordering ...
|
|
if (!orderBuilder.IsNull())
|
|
{
|
|
result = orderBuilder(result);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = (await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken))
|
|
.FirstOrDefault(x => GetKey(x).ToString() == id.ToString());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<T>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <returns></returns>
|
|
public IAsyncEnumerable<T> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.AsAsyncEnumerable();
|
|
|
|
//
|
|
return result;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Entity by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> FindOneAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = (await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken))
|
|
.FirstOrDefault(predicate.Compile());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Entities by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<T>> FindManyAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = (await AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken))
|
|
.Where(predicate.Compile());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Entities based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<T>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize Query ...
|
|
query = query.NormalizeQuery(configuration);
|
|
|
|
//
|
|
var items = await GetAllAsync();
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<T>
|
|
{
|
|
Page = query.Page,
|
|
Items = items.ToList(),
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check an Entity exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = (await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: predicator
|
|
)
|
|
.ToListAsync(cancellationToken))
|
|
.Any(predicate: x => GetKey(x).ToString() == id.ToString());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Unit Of Work ...
|
|
/// <summary>
|
|
/// Save all unsaved Transactions on DbContext ...
|
|
/// used fo Unit Of Works Design Pattern ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> SaveChangesAsync(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
return await unitOfWorks.SaveChangesAsync(cancellationToken);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Key ...
|
|
/// <summary>
|
|
/// Retrieve Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public TKey GetKey(T item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
|
|
//
|
|
var keyString = string.Empty;
|
|
if (keyProp.IsNull())
|
|
{
|
|
keyString = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
keyString = keyProp.GetValue(item).ToString();
|
|
}
|
|
|
|
//
|
|
if (keyString.IsNullOrEmpty())
|
|
{
|
|
return default(TKey);
|
|
}
|
|
|
|
//
|
|
// Prevent Deserializing issues throug JsonReader ...
|
|
if (keyString.IsGuid() && typeof(TKey) == typeof(Guid))
|
|
{
|
|
return item.Id;
|
|
}
|
|
|
|
//
|
|
return keyString.FromJSON<TKey>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="id"></param>
|
|
public void SetKey(
|
|
ref T item,
|
|
TKey id
|
|
)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
if (keyProp.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Type t = Nullable.GetUnderlyingType(keyProp.PropertyType) ?? keyProp.PropertyType;
|
|
object safeValue = (id == null) ? null : Convert.ChangeType(id, t);
|
|
keyProp.SetValue(item, safeValue, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Checking Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> HandleKeyAsync(
|
|
T item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var keyType = typeof(TKey);
|
|
|
|
//
|
|
// Handle Guid Key Type ...
|
|
// Since EFCore has AutoIncrement on int Ids, there is no need to handle int Key types ...
|
|
if (
|
|
(
|
|
keyType == typeof(Guid) ||
|
|
keyType == typeof(string)
|
|
) &&
|
|
keyGenerator.IsEmpty(item.Id)
|
|
)
|
|
{
|
|
//
|
|
var newKey = await keyGenerator.GenerateKey(this);
|
|
|
|
//
|
|
SetKey(ref item, newKey);
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Detach ...
|
|
/// <summary>
|
|
/// Detach an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
public void Detach(T item)
|
|
{
|
|
//
|
|
if (item.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Entry(item).State = EntityState.Detached;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach an Enumerable of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
public void Detach(IEnumerable<T> items)
|
|
{
|
|
//
|
|
if (items.IsNull() || !items.HasChild())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
items
|
|
.ToList()
|
|
.ForEach(item =>
|
|
{
|
|
Detach(item);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach a Query Result of Entity ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
public void Detach(XQueryResult<T> query)
|
|
{
|
|
//
|
|
if (query.IsNull() || query.Items.HasChild())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Detach(query.Items);
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region Others ...
|
|
public void Dispose()
|
|
{
|
|
unitOfWorks.Dispose();
|
|
}
|
|
|
|
public string GetPropValues(T item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var vals = props.Select(p => p.GetValue(p.Name));
|
|
|
|
//
|
|
return vals.ToJSON();
|
|
}
|
|
|
|
public EntityEntry<T> Entry(T item)
|
|
{
|
|
return unitOfWorks.DbContext.Entry(item);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseEntityRegisterar.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Base Entity Registerar ...
|
|
/// </summary>
|
|
public abstract class XBaseEntityRegisterar : IXEntityRegisterar
|
|
{
|
|
/// <summary>
|
|
/// Private Entity Types Collection ...
|
|
/// </summary>
|
|
private readonly List<Type> entityTypes = [];
|
|
|
|
/// <summary>
|
|
/// Name ...
|
|
/// </summary>
|
|
public string Name { get; }
|
|
|
|
protected XBaseEntityRegisterar(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Specified Entity to Collection ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public void AddEntity<TEntity, TKey>()
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
entityTypes.Add(typeof(TEntity));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Registered Entity Types ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<Type> GetEntityTypes()
|
|
{
|
|
return entityTypes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Dynamic Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public virtual void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseEntityTypeConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Configure an Entity Specifications ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseEntityTypeConfiguration<TEntity, TKey> : IEntityTypeConfiguration<TEntity>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
public abstract void Configure(EntityTypeBuilder<TEntity> builder);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseInMemoryRepository.cs
|
|
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// a Base Repository Pattern Implementation Specially for InMemory Stores using
|
|
/// EF Core Capabilities ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseInMemoryRepository<TEntity, TKey> : IXBaseRepository<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
private readonly XDataServiceConfiguration configuration;
|
|
private readonly IXKeyGenerator<TEntity, TKey> keyGenerator;
|
|
private readonly IXBaseRepositoryEvents<TEntity> baseRepositoryEvents;
|
|
private static readonly ConcurrentDictionary<TKey, TEntity> store = new ConcurrentDictionary<TKey, TEntity>();
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXKeyGenerator<TEntity, TKey> keyGenerator = null,
|
|
IXBaseRepositoryEvents<TEntity> baseRepositoryEvents = null
|
|
)
|
|
{
|
|
this.keyGenerator = keyGenerator;
|
|
this.configuration = configuration;
|
|
this.baseRepositoryEvents = baseRepositoryEvents;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> AddAsync(
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Handle Key ...
|
|
item = await HandleKeyAsync(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isSucceed = false;
|
|
|
|
//
|
|
// Add Item to Dictionary ...
|
|
try
|
|
{
|
|
//
|
|
store[item.Id] = item;
|
|
isSucceed = true;
|
|
}
|
|
catch
|
|
{
|
|
isSucceed = false;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddEvent(new XBaseEventModel<TEntity>(item));
|
|
}
|
|
|
|
//
|
|
// Return Item ...
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add or update an Entity (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> AddOrUpdateAsync(
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(
|
|
id: item.Id,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isSucceed = false;
|
|
if (isExists)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
item = await UpdateAsync(
|
|
item: item,
|
|
id: item.Id,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isSucceed = true;
|
|
}
|
|
catch
|
|
{
|
|
isSucceed = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
item = await AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
isSucceed = true;
|
|
}
|
|
catch
|
|
{
|
|
isSucceed = false;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
if (isExists)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateEvent(new XBaseEventModel<TEntity>(item));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddEvent(new XBaseEventModel<TEntity>(item));
|
|
}
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add a range of new Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddRangeAsync(
|
|
IEnumerable<TEntity> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isValid = !items.IsNull() && items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
await AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isValid &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddManyEvent(new XBaseEventModel<IEnumerable<TEntity>>(null));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Entity values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> UpdateAsync(
|
|
TKey id,
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(
|
|
id: id,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var isSucceed = false;
|
|
var exists = store[id];
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
exists = exists.UpdateData(
|
|
exists,
|
|
propertyBlackList: new List<string> { nameof(exists.Id) }
|
|
);
|
|
store[id] = exists;
|
|
|
|
//
|
|
isSucceed = true;
|
|
}
|
|
catch
|
|
{
|
|
isSucceed = false;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateEvent(new XBaseEventModel<TEntity>(item));
|
|
}
|
|
|
|
//
|
|
return exists;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a range of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> UpdateRangeAsync(
|
|
IEnumerable<TEntity> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var isValid = !items.IsNull() && items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
var updated = await UpdateAsync(
|
|
item: item,
|
|
id: item.Id,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!updated.IsNullOrDefault() && !result)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
TEntity result = null;
|
|
if (softDelete && configuration.EnableSoftDelete)
|
|
{
|
|
//
|
|
store[id].Deleted = true;
|
|
result = store[id];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = store[id];
|
|
store.TryRemove(id, out _);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> RemoveAsync(
|
|
TEntity item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveRangeAsync(
|
|
IEnumerable<TEntity> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isValid = !items.IsNull() && items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
await RemoveAsync(
|
|
item: item,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: predicator
|
|
)
|
|
.CountAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
int count = totalItems.HasValue ? totalItems.Value : await CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check an Entity exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: predicator
|
|
)
|
|
.AnyAsync(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => GetKey(x).ToString() == id.ToString());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve whole items as queryable ...
|
|
/// </summary>
|
|
/// <param name="asNoTracking">a flag for Tracking behaviour</param>
|
|
/// <param name="predicate">an Expression for Filter Items ...</param>
|
|
/// <param name="orderBuilder">an Order Builder expression for Ordering Query ...</param>
|
|
/// <param name="includeBuilder">an Include Builder expression for Including Navigation Properties ...</param>
|
|
/// <returns></returns>
|
|
public IQueryable<TEntity> AsQueryable(
|
|
bool asNoTracking = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
var result = store.Values.AsQueryable();
|
|
|
|
//
|
|
// Predicate ...
|
|
if (!predicate.IsNull())
|
|
{
|
|
result = result.Where(predicate);
|
|
}
|
|
|
|
//
|
|
// Apply Orders ...
|
|
if (!orderBuilder.IsNull())
|
|
{
|
|
result = orderBuilder(result);
|
|
}
|
|
|
|
//
|
|
// Apply Includes ...
|
|
if (!includeBuilder.IsNull())
|
|
{
|
|
result = includeBuilder(result);
|
|
}
|
|
|
|
//
|
|
if (asNoTracking)
|
|
{
|
|
result = result.AsNoTracking();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(x => GetKey(x).ToString() == id.ToString())
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TEntity>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <returns></returns>
|
|
public IAsyncEnumerable<TEntity> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.AsAsyncEnumerable();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Entity by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(predicate)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Entities by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TEntity>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<TEntity, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(predicate)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Entities based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<TEntity>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize Query ...
|
|
query = query.NormalizeQuery(configuration);
|
|
|
|
//
|
|
var items = await GetAllAsync();
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<TEntity>
|
|
{
|
|
Page = query.Page,
|
|
Items = items.ToList(),
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Unit Of Work ...
|
|
/// <summary>
|
|
/// Save all unsaved Transactions on DbContext ...
|
|
/// used fo Unit Of Works Design Pattern ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> SaveChangesAsync(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await Task.Run(
|
|
() => 0,
|
|
cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Key ...
|
|
/// <summary>
|
|
/// Retrieve Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public TKey GetKey(TEntity item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
|
|
//
|
|
var keyString = string.Empty;
|
|
if (keyProp.IsNull())
|
|
{
|
|
keyString = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
keyString = keyProp.GetValue(item).ToString();
|
|
}
|
|
|
|
//
|
|
if (keyString.IsNullOrEmpty())
|
|
{
|
|
return default(TKey);
|
|
}
|
|
|
|
//
|
|
// Prevent Deserializing issues throug JsonReader ...
|
|
if (keyString.IsGuid() && typeof(TKey) == typeof(Guid))
|
|
{
|
|
return item.Id;
|
|
}
|
|
|
|
//
|
|
return keyString.FromJSON<TKey>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="id"></param>
|
|
public void SetKey(
|
|
ref TEntity item,
|
|
TKey id
|
|
)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
if (keyProp.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Type t = Nullable.GetUnderlyingType(keyProp.PropertyType) ?? keyProp.PropertyType;
|
|
object safeValue = (id == null) ? null : Convert.ChangeType(id, t);
|
|
keyProp.SetValue(item, safeValue, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Checking Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TEntity> HandleKeyAsync(
|
|
TEntity item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var keyType = typeof(TKey);
|
|
|
|
//
|
|
// Handle Guid Key Type ...
|
|
// Since EFCore has AutoIncrement on int Ids, there is no need to handle int Key types ...
|
|
if (
|
|
(
|
|
keyType == typeof(Guid) ||
|
|
keyType == typeof(string)
|
|
) &&
|
|
keyGenerator.IsEmpty(item.Id)
|
|
)
|
|
{
|
|
//
|
|
var newKey = await keyGenerator.GenerateKey(this);
|
|
|
|
//
|
|
SetKey(ref item, newKey);
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Detach ...
|
|
/// <summary>
|
|
/// Detach an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
public void Detach(TEntity item) { }
|
|
|
|
/// <summary>
|
|
/// Detach an Enumerable of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
public void Detach(IEnumerable<TEntity> items) { }
|
|
|
|
/// <summary>
|
|
/// Detach a Query Result of Entity ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
public void Detach(XQueryResult<TEntity> query) { }
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region Others ...
|
|
public void Dispose()
|
|
{ }
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseMongoRepository.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using MongoDB.Driver;
|
|
using MongoDB.Driver.Linq;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// a Base Repository Pattern Implementation Specially for Mongo DBs using
|
|
/// EF Core Capabilities ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseMongoRepository<T, TKey> : IXBaseRepository<T, TKey>
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
private readonly string collectionName;
|
|
public List<WriteModel<T>> bulkCollection;
|
|
public readonly IMongoCollection<T> collection;
|
|
private readonly IXKeyGenerator<T, TKey> keyGenerator;
|
|
public readonly XDataBaseConfiguration dbConfiguration;
|
|
public readonly XDataServiceConfiguration configuration;
|
|
private readonly IXBaseRepositoryEvents<T> baseRepositoryEvents;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXKeyGenerator<T, TKey> keyGenerator = null,
|
|
IXBaseRepositoryEvents<T> baseRepositoryEvents = null
|
|
)
|
|
{
|
|
//
|
|
this.keyGenerator = keyGenerator;
|
|
this.configuration = configuration;
|
|
this.collectionName = collectionName
|
|
.IsNullOrEmpty() ?
|
|
typeof(T).Name :
|
|
collectionName;
|
|
this.dbConfiguration = dbConfiguration;
|
|
this.baseRepositoryEvents = baseRepositoryEvents;
|
|
|
|
//
|
|
var client = new MongoClient(dbConfiguration.GetMongoDbURI());
|
|
var database = client.GetDatabase(dbConfiguration.GetMongoDbDatabase());
|
|
|
|
//
|
|
bulkCollection = new List<WriteModel<T>>();
|
|
collection = database.GetCollection<T>(
|
|
this.collectionName
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> AddAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Handle Key ...
|
|
item = await HandleKeyAsync(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new InsertOneModel<T>(item));
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddEvent(new XBaseEventModel<T>(item));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
item :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add or update an Entity (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> AddOrUpdateAsync(
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(
|
|
id: GetKey(item),
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
//
|
|
// Handle Key ...
|
|
item = await HandleKeyAsync(
|
|
item: item,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection
|
|
.Add(new InsertOneModel<T>(item));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Filter ...
|
|
var filter = Builders<T>.Filter.Eq(i => i.Id, item.Id);
|
|
|
|
//
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection
|
|
.Add(new ReplaceOneModel<T>(filter, item) { IsUpsert = true });
|
|
}
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
if (isExists)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateEvent(new XBaseEventModel<T>(item));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddEvent(new XBaseEventModel<T>(item));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
item :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add a range of new Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isValid = !items.IsNull() && items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
await AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isValid &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.AddManyEvent(new XBaseEventModel<IEnumerable<T>>(null));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Entity values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> UpdateAsync(
|
|
TKey id,
|
|
T item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Filter ...
|
|
var filter = Builders<T>.Filter.Eq(i => i.Id, id);
|
|
|
|
//
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new ReplaceOneModel<T>(filter, item) { IsUpsert = false });
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.UpdateEvent(new XBaseEventModel<T>(item));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
item :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a range of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> UpdateRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var isValid = !items.IsNull() && items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
var updated = await UpdateAsync(
|
|
item: item,
|
|
id: item.Id,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!updated.IsNullOrDefault() && !result)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Retrieve Item ...
|
|
var item = await GetAsync(
|
|
id: id,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (item.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Filter ...
|
|
var filter = Builders<T>.Filter.Eq(i => i.Id, id);
|
|
|
|
//
|
|
// Check SoftDelete ...
|
|
if (softDelete && configuration.EnableSoftDelete)
|
|
{
|
|
//
|
|
// Set Soft Delete ...
|
|
item.Deleted = true;
|
|
|
|
//
|
|
// Update ...
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new ReplaceOneModel<T>(filter, item) { IsUpsert = true });
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Delete ...
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new DeleteOneModel<T>(filter));
|
|
}
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.RemoveEvent(new XBaseEventModel<T>(item));
|
|
}
|
|
|
|
//
|
|
// Return result base on action Succeed ...
|
|
return isSucceed ?
|
|
item :
|
|
null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> RemoveAsync(
|
|
T item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveRangeAsync(
|
|
IEnumerable<T> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// loop through items ...
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
// Filter ...
|
|
var filter = Builders<T>.Filter.Eq(i => i.Id, item.Id);
|
|
|
|
//
|
|
// Check Soft Delete ...
|
|
if (softDelete && configuration.EnableSoftDelete)
|
|
{
|
|
//
|
|
// Set Soft Delete ...
|
|
item.Deleted = true;
|
|
|
|
//
|
|
// Update ...
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new ReplaceOneModel<T>(filter, item) { IsUpsert = true });
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Delete ...
|
|
// Add Action model to Bulk Collection ...
|
|
bulkCollection.Add(new DeleteOneModel<T>(filter));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check action is Succeeded or not ...
|
|
var isSucceed = false;
|
|
if (saveChanges)
|
|
{
|
|
//
|
|
// Get Modified Count ...
|
|
var qResult = await SaveChangesAsync(cancellationToken);
|
|
|
|
//
|
|
// set isSucceed Value based on Changes ...
|
|
isSucceed = qResult > 0;
|
|
}
|
|
|
|
//
|
|
// Notify Event ...
|
|
if (
|
|
isSucceed &&
|
|
!baseRepositoryEvents.IsNull()
|
|
)
|
|
{
|
|
//
|
|
baseRepositoryEvents
|
|
.RemoveManyEvent(new XBaseEventModel<IEnumerable<T>>(null));
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: predicator
|
|
)
|
|
.CountAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
int count = totalItems.HasValue ? totalItems.Value : await CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve whole items as queryable ...
|
|
/// </summary>
|
|
/// <param name="asNoTracking">a flag for Tracking behaviour</param>
|
|
/// <param name="predicate">an Expression for Filter Items ...</param>
|
|
/// <param name="orderBuilder">an Order Builder expression for Ordering Query ...</param>
|
|
/// <param name="includeBuilder">an Include Builder expression for Including Navigation Properties ...</param>
|
|
/// <returns></returns>
|
|
public IQueryable<T> AsQueryable(
|
|
bool asNoTracking = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
var result = collection
|
|
.AsQueryable();
|
|
|
|
//
|
|
// Apply Predicate ...
|
|
if (!predicate.IsNull())
|
|
{
|
|
result = result
|
|
.Where(predicate);
|
|
}
|
|
|
|
//
|
|
// Apply Includes ...
|
|
if (!includeBuilder.IsNull())
|
|
{
|
|
//
|
|
// Since Mongo Queryable doesnt Support Includes ...
|
|
// we ignore this ...
|
|
result = (IMongoQueryable<T>)includeBuilder(result);
|
|
}
|
|
|
|
//
|
|
// Apply Ordering ...
|
|
if (!orderBuilder.IsNull())
|
|
{
|
|
result = (IMongoQueryable<T>)orderBuilder(result);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Entity by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(x => GetKey(x).ToString() == id.ToString())
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<T>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Entities
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <returns></returns>
|
|
public IAsyncEnumerable<T> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.AsAsyncEnumerable();
|
|
|
|
//
|
|
return result;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Entity by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> FindOneAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
predicate: predicator,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(predicate)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Entities by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<T>> FindManyAsync(
|
|
Expression<Func<T, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
predicate: predicator,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder
|
|
)
|
|
.Where(predicate)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Entities based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<T>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<T, bool>> predicate = null,
|
|
Func<IQueryable<T>, IOrderedQueryable<T>> orderBuilder = null,
|
|
Func<IQueryable<T>, IIncludableQueryable<T, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize Query ...
|
|
query = query.NormalizeQuery(configuration);
|
|
|
|
//
|
|
var items = await GetAllAsync();
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<T>
|
|
{
|
|
Page = query.Page,
|
|
Items = items.ToList(),
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check an Entity exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Prepare Ignore Soft Deleted Predicator ...
|
|
Expression<Func<T, bool>> predicator = null;
|
|
if (ignoreSoftDeleteds)
|
|
{
|
|
predicator = x => !x.Deleted;
|
|
}
|
|
var result = await AsQueryable(
|
|
asNoTracking: true,
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
predicate: predicator
|
|
)
|
|
.AnyAsync(
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => GetKey(x).ToString() == id.ToString());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Unit Of Work ...
|
|
/// <summary>
|
|
/// Save all unsaved Transactions on DbContext ...
|
|
/// used fo Unit Of Works Design Pattern ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> SaveChangesAsync(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Write all Bulk Models which stored inside bulkCollection ...
|
|
var result = await collection
|
|
.BulkWriteAsync(
|
|
options: null,
|
|
requests: bulkCollection,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Clear Bulk Collection ...
|
|
bulkCollection.Clear();
|
|
|
|
//
|
|
// Return number of Modified Documents ...
|
|
var resultCount = (int)result.ModifiedCount +
|
|
(int)result.InsertedCount +
|
|
(int)result.DeletedCount;
|
|
|
|
//
|
|
return resultCount;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
// Log Thrown Exception ...
|
|
Console.WriteLine($"XMongo Repository Exception: {ex.Message} ...");
|
|
|
|
//
|
|
// Return less than zero value ...
|
|
return -1;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Key ...
|
|
/// <summary>
|
|
/// Retrieve Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public TKey GetKey(T item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
|
|
//
|
|
var keyString = string.Empty;
|
|
if (keyProp.IsNull())
|
|
{
|
|
keyString = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
keyString = keyProp.GetValue(item).ToString();
|
|
}
|
|
|
|
//
|
|
if (keyString.IsNullOrEmpty())
|
|
{
|
|
return default(TKey);
|
|
}
|
|
|
|
//
|
|
// Prevent Deserializing issues throug JsonReader ...
|
|
if (keyString.IsGuid() && typeof(TKey) == typeof(Guid))
|
|
{
|
|
return item.Id;
|
|
}
|
|
|
|
//
|
|
return keyString.FromJSON<TKey>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Key of Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="id"></param>
|
|
public void SetKey(
|
|
ref T item,
|
|
TKey id
|
|
)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
if (keyProp.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Type t = Nullable.GetUnderlyingType(keyProp.PropertyType) ?? keyProp.PropertyType;
|
|
object safeValue = (id == null) ? null : Convert.ChangeType(id, t);
|
|
keyProp.SetValue(item, safeValue, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Checking Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<T> HandleKeyAsync(
|
|
T item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var keyType = typeof(TKey);
|
|
|
|
//
|
|
// Handle Guid Key Type ...
|
|
// Since EFCore has AutoIncrement on int Ids, there is no need to handle int Key types ...
|
|
if (
|
|
(
|
|
keyType == typeof(Guid) ||
|
|
keyType == typeof(string)
|
|
) &&
|
|
keyGenerator.IsEmpty(item.Id)
|
|
)
|
|
{
|
|
//
|
|
var newKey = await keyGenerator.GenerateKey(this);
|
|
|
|
//
|
|
SetKey(ref item, newKey);
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Detach ...
|
|
/// <summary>
|
|
/// Detach an Entity ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
public void Detach(T item) { }
|
|
|
|
/// <summary>
|
|
/// Detach an Enumerable of Entities ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
public void Detach(IEnumerable<T> items) { }
|
|
|
|
/// <summary>
|
|
/// Detach a Query Result of Entity ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
public void Detach(XQueryResult<T> query) { }
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region Others ...
|
|
public void Dispose() { }
|
|
|
|
public string GetPropValues(T item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var vals = props.Select(p => p.GetValue(p.Name));
|
|
|
|
//
|
|
return vals.ToJSON();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseRepositoryEvents.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
|
|
namespace xDataService.Providers {
|
|
/// <summary>
|
|
/// Some Events can be Raised on Some Actions Happens on Repositories ...
|
|
/// this is the Base Events Class ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public abstract class XBaseRepositoryEvents<T> : IXBaseRepositoryEvents<T> {
|
|
//
|
|
private readonly ISubject<XBaseEventModel<T>> onAddSubject;
|
|
private readonly ISubject<XBaseEventModel<T>> onUpdateSubject;
|
|
private readonly ISubject<XBaseEventModel<T>> onRemoveSubject;
|
|
|
|
//
|
|
private readonly ISubject<XBaseEventModel<IEnumerable<T>>> onAddManySubject;
|
|
private readonly ISubject<XBaseEventModel<IEnumerable<T>>> onUpdateManySubject;
|
|
private readonly ISubject<XBaseEventModel<IEnumerable<T>>> onRemoveManySubject;
|
|
|
|
//
|
|
protected XBaseRepositoryEvents () {
|
|
//
|
|
onAddSubject = new ReplaySubject<XBaseEventModel<T>> (1);
|
|
onUpdateSubject = new ReplaySubject<XBaseEventModel<T>> (1);
|
|
onRemoveSubject = new ReplaySubject<XBaseEventModel<T>> (1);
|
|
|
|
//
|
|
onAddManySubject = new ReplaySubject<XBaseEventModel<IEnumerable<T>>> (1);
|
|
onUpdateManySubject = new ReplaySubject<XBaseEventModel<IEnumerable<T>>> (1);
|
|
onRemoveManySubject = new ReplaySubject<XBaseEventModel<IEnumerable<T>>> (1);
|
|
}
|
|
|
|
//
|
|
public void AddEvent (XBaseEventModel<T> model) => onAddSubject.OnNext (model);
|
|
|
|
public void UpdateEvent (XBaseEventModel<T> model) => onUpdateSubject.OnNext (model);
|
|
|
|
public void RemoveEvent (XBaseEventModel<T> model) => onRemoveSubject.OnNext (model);
|
|
|
|
//
|
|
public void AddManyEvent (XBaseEventModel<IEnumerable<T>> model) => onAddManySubject.OnNext (model);
|
|
public void UpdateManyEvent (XBaseEventModel<IEnumerable<T>> model) => onUpdateManySubject.OnNext (model);
|
|
public void RemoveManyEvent (XBaseEventModel<IEnumerable<T>> model) => onRemoveManySubject.OnNext (model);
|
|
|
|
//
|
|
public IObservable<XBaseEventModel<T>> OnAddObservable => onAddSubject.AsObservable ();
|
|
|
|
public IObservable<XBaseEventModel<T>> OnUpdateObservable => onUpdateSubject.AsObservable ();
|
|
|
|
public IObservable<XBaseEventModel<T>> OnRemoveObservable => onRemoveSubject.AsObservable ();
|
|
|
|
//
|
|
public IObservable<XBaseEventModel<IEnumerable<T>>> OnAddManyObservable => onAddManySubject.AsObservable ();
|
|
public IObservable<XBaseEventModel<IEnumerable<T>>> OnUpdateManyObservable => onUpdateManySubject.AsObservable ();
|
|
public IObservable<XBaseEventModel<IEnumerable<T>>> OnRemoveManyObservable => onRemoveManySubject.AsObservable ();
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XBaseRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AutoMapper;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// a Base Repository Service Implementation which Use a Repository Patterns Implementatin
|
|
/// and provides Data Manipulation Methods using Dtos instead of Entities ...
|
|
///
|
|
/// it can be use of following Repository Patterns Implementation:
|
|
/// <see cref="XBaseEFRepository"/>>
|
|
/// <see cref="XBaseMongoRepository"/>>
|
|
/// <see cref="XBaseInMemoryRepository"/>>
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseRepositoryService<TEntity, TDto, TKey> : IXBaseRepositoryService<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
/// <summary>
|
|
/// Mapper Instance ...
|
|
/// </summary>
|
|
public IMapper Mapper { get; }
|
|
|
|
/// <summary>
|
|
/// Repository Implementation for Data Manipulations ...
|
|
/// </summary>
|
|
public IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
|
|
/// <summary>
|
|
/// Mapping Profile Configuration ...
|
|
///
|
|
/// this Configuration used for Mapping TEntity to Dto and reverse ...
|
|
/// default mapping prepared on Constructing time, other custom maps
|
|
/// must handled manually if required ...
|
|
/// </summary>
|
|
public MapperConfiguration MapperConfiguration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseRepositoryService(
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
)
|
|
{
|
|
//
|
|
Repository = repository;
|
|
|
|
//
|
|
// Preparing Mapping Configurations ...
|
|
MapperConfiguration = new MapperConfiguration(cfg =>
|
|
{
|
|
//
|
|
// Add Default Profiles ...
|
|
|
|
//
|
|
// Entity To Dto ...
|
|
cfg.CreateMap<TEntity, TDto>()
|
|
.ForMember(dest => dest.Deleted, opt => opt.Ignore());
|
|
cfg.CreateMap<XQueryResult<TEntity>, XQueryResult<TDto>>();
|
|
|
|
//
|
|
// Dto to Entity ...
|
|
cfg.CreateMap<TDto, TEntity>()
|
|
.ForMember(dest => dest.Deleted, opt => opt.Ignore());
|
|
cfg.CreateMap<XQueryResult<TDto>, XQueryResult<TEntity>>();
|
|
|
|
//
|
|
// Add Provided Profiles if Provided ...
|
|
// if Same Profiles Provided, here resolved ...
|
|
if (!mapperProfiles.IsNull() &&
|
|
mapperProfiles.HasChild())
|
|
{
|
|
cfg.AddProfiles(mapperProfiles);
|
|
}
|
|
});
|
|
|
|
//
|
|
// Make Mapper Instance using prepared Configuration ...
|
|
Mapper = MapperConfiguration.CreateMapper();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add a new Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
// Validate ...
|
|
bool isValid = !item.IsNull();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = Mapper.Map<TEntity>(item);
|
|
|
|
//
|
|
entity = await Repository.AddAsync(
|
|
item: entity,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add or update a Dto (add if not exists/update if exists) ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> AddOrUpdateAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
// Validate ...
|
|
bool isValid = !item.IsNull();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = Mapper.Map<TEntity>(item);
|
|
|
|
//
|
|
entity = await Repository.AddOrUpdateAsync(
|
|
item: entity,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// add a range of new Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!items.IsNull() &&
|
|
items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entities = Mapper.Map<IEnumerable<TEntity>>(items);
|
|
|
|
//
|
|
await Repository.AddRangeAsync(
|
|
items: entities,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update an Dto values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = Mapper.Map<TEntity>(item);
|
|
|
|
//
|
|
entity = await Repository.UpdateAsync(
|
|
id: item.Id,
|
|
item: entity,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a range of Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> UpdateRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!items.IsNull() &&
|
|
items.HasChild();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entitis = Mapper.Map<IEnumerable<TEntity>>(items);
|
|
|
|
//
|
|
result = await Repository.UpdateRangeAsync(
|
|
items: entitis,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// remove an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = await Repository.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> RemoveAsync(
|
|
TDto item,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = Mapper.Map<TEntity>(item);
|
|
|
|
//
|
|
entity = await Repository.RemoveAsync(
|
|
item: entity,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove a range of exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveRangeAsync(
|
|
IEnumerable<TDto> items,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!items.IsNull() &&
|
|
items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var entities = Mapper.Map<IEnumerable<TEntity>>(items);
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await Repository.RemoveRangeAsync(
|
|
items: entities,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// count all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Entities Pages by providing page size ...
|
|
/// </summary>
|
|
/// <param name="pageSize"></param>
|
|
/// <param name="totalItems"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> PagesCountAsync(
|
|
int pageSize,
|
|
int? totalItems = null,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.PagesCountAsync(
|
|
pageSize: pageSize,
|
|
totalItems: totalItems,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// Check a Dto exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// retrieve an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = await Repository.GetAsync(
|
|
id: id,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
IEnumerable<TDto> result = Enumerable.Empty<TDto>();
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entities = await Repository.GetAllAsync(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<IEnumerable<TDto>>(entities);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var entityEnumerable = Repository.GetAllAsAsyncEnumerable(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
await foreach (var entity in entityEnumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
var dto = Mapper.Map<TDto>(entity);
|
|
yield return dto;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Dto by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
TDto result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entity = await Repository.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<TDto>(entity);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Dtos by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
IEnumerable<TDto> result = Enumerable.Empty<TDto>();
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entities = await Repository.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<IEnumerable<TDto>>(entities);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Dtos based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
XQueryResult<TDto> result = null;
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var entityResult = await Repository.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
result = Mapper.Map<XQueryResult<TDto>>(entityResult);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
public virtual void Dispose()
|
|
{ }
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XEntityRegisterarHandlerService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
public class XEntityRegisterarHandlerService
|
|
{
|
|
/// <summary>
|
|
/// a Collection for Extract Registerars Services ...
|
|
/// </summary>
|
|
private readonly List<IXEntityRegisterar> registerars = [];
|
|
|
|
/// <summary>
|
|
/// a Collection for Holding all Entity Types ...
|
|
/// </summary>
|
|
public IReadOnlyList<Type> AllEntityTypes { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Registerars Entity Types ...
|
|
/// </summary>
|
|
/// <param name="names"></param>
|
|
/// <returns></returns>
|
|
public IReadOnlyList<Type> GetEntityTypes(string[] names = null)
|
|
{
|
|
//
|
|
var items = new List<Type>();
|
|
|
|
//
|
|
if (!names.IsNull() && names.HasChild())
|
|
{
|
|
//
|
|
items = [.. registerars
|
|
.Where(r => names.Contains(r.Name))
|
|
.SelectMany(r => r.GetEntityTypes())];
|
|
}
|
|
|
|
//
|
|
return items.AsReadOnly();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load all Dynamically Registered Entities ...
|
|
/// </summary>
|
|
public void HandleRegisteredEntities()
|
|
{
|
|
//
|
|
var entityTypes = new List<Type>();
|
|
// path = Path.Combine (Directory.GetCurrentDirectory ());
|
|
var path = Path.Combine (AppContext.BaseDirectory);
|
|
var files = Directory.GetFiles(path, "*.dll");
|
|
foreach (var dll in files)
|
|
{
|
|
//
|
|
// Retrieve DLL Assembly ...
|
|
var assembly = Assembly.LoadFrom(dll);
|
|
|
|
//
|
|
// Extract Registerar Types ...
|
|
var registerarTypes = assembly
|
|
.GetExportedTypes()
|
|
.Where(t =>
|
|
!t.IsAbstract &&
|
|
typeof(IXEntityRegisterar).IsAssignableFrom(t));
|
|
foreach (var registerarType in registerarTypes)
|
|
{
|
|
//
|
|
// Create Instance of Registerar Type ...
|
|
var registerar = (IXEntityRegisterar)Activator.CreateInstance(registerarType);
|
|
if (!registerar.IsNull())
|
|
{
|
|
//
|
|
// Add Registerar Instance to Collection ...
|
|
registerars.Add(registerar);
|
|
|
|
//
|
|
// Add Registerar Provided Entities to Collection ...
|
|
entityTypes.AddRange(registerar.GetEntityTypes());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Converts to Readonly List ...
|
|
AllEntityTypes = entityTypes.AsReadOnly();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure all Dynamically Registered Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
/// <param name="names"></param>
|
|
public void HandleApplyRegisteredEntitiesConfigurations(
|
|
ModelBuilder modelBuilder,
|
|
string[] names = null
|
|
)
|
|
{
|
|
//
|
|
var selectedRegisterars =
|
|
!names.IsNull() &&
|
|
names.HasChild()
|
|
? registerars
|
|
.Where(r => names.Contains(r.Name))
|
|
: registerars;
|
|
|
|
//
|
|
// Loop Through Extracted Registerars ...
|
|
foreach(var registerar in selectedRegisterars)
|
|
{
|
|
//
|
|
// Configure Specified Registerars Entities ...
|
|
registerar.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XGuidKeyGenerator.cs
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Default Guid Key Generator ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
public class XGuidKeyGenerator<TEntity> : XKeyGenerator<TEntity, Guid>, IXKeyGenerator<TEntity, Guid>
|
|
where TEntity : XBaseEntity<Guid>
|
|
{
|
|
private readonly IXSequentialGuid sequentialGuid;
|
|
|
|
public XGuidKeyGenerator(
|
|
IXSequentialGuid sequentialGuid = null
|
|
)
|
|
{
|
|
this.sequentialGuid = sequentialGuid;
|
|
}
|
|
|
|
public override async Task<Guid> GenerateKey(
|
|
IXBaseRepository<TEntity, Guid> repository,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
return await Task.Run(() =>
|
|
{
|
|
//
|
|
// Check if provided SequentialGuid ...
|
|
if (sequentialGuid.IsNull())
|
|
{
|
|
return Guid.NewGuid();
|
|
}
|
|
else
|
|
{
|
|
return sequentialGuid.Next();
|
|
}
|
|
}, cancellationToken: cancellationToken);
|
|
}
|
|
|
|
public override bool IsEmpty(Guid id)
|
|
{
|
|
//
|
|
var result = id.IsNull() || id.IsDefaultGuid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XIntKeyGenerator.cs
|
|
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Default Int Key Generator ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
public class XIntKeyGenerator<TEntity> : XKeyGenerator<TEntity, int>, IXKeyGenerator<TEntity, int>
|
|
where TEntity : XBaseEntity<int>
|
|
{
|
|
public override async Task<int> GenerateKey(
|
|
IXBaseRepository<TEntity, int> repository,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var items = (await repository.GetAllAsync())
|
|
.OrderByDescending(nameof(XBaseEntity<int>.Id));
|
|
var last = items
|
|
.FirstOrDefault();
|
|
|
|
//
|
|
var result = last.IsNull() ? 1 : last.Id + 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public override bool IsEmpty(int id)
|
|
{
|
|
//
|
|
var result = id <= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XKeyGenerator.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
public abstract class XKeyGenerator<TEntity, TKey> : IXKeyGenerator<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
public abstract Task<TKey> GenerateKey(
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
public abstract bool IsEmpty(TKey id);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XLongKeyGenerator.cs
|
|
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Default Long Key Generator ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
public class XLongKeyGenerator<TEntity> : XKeyGenerator<TEntity, long>, IXKeyGenerator<TEntity, long>
|
|
where TEntity : XBaseEntity<long>
|
|
{
|
|
public override async Task<long> GenerateKey(
|
|
IXBaseRepository<TEntity, long> repository,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var items = (await repository.GetAllAsync())
|
|
.OrderByDescending(nameof(XBaseEntity<long>.Id));
|
|
var last = items
|
|
.FirstOrDefault();
|
|
|
|
//
|
|
var result = last.IsNull() ? 1 : last.Id + 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public override bool IsEmpty(long id)
|
|
{
|
|
//
|
|
var result = id <= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XSequentialGuid.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
|
|
namespace xDataService.Helpers
|
|
{
|
|
/// <summary>
|
|
/// this service provide Sequential GUID mechanism for Entity Ids ...
|
|
/// </summary>
|
|
public class XSequentialGuid : IXSequentialGuid
|
|
{
|
|
private static int[] sqlOrderMap = null;
|
|
private static int[] SQLORDERMAP
|
|
{
|
|
get
|
|
{
|
|
if (sqlOrderMap == null)
|
|
{
|
|
sqlOrderMap = new int[16] {
|
|
3,
|
|
2,
|
|
1,
|
|
0,
|
|
5,
|
|
4,
|
|
7,
|
|
6,
|
|
9,
|
|
8,
|
|
15,
|
|
14,
|
|
13,
|
|
12,
|
|
11,
|
|
10
|
|
};
|
|
// 3 - the least significant byte in Guid ByteArray [for SQL Server ORDER BY clause]
|
|
// 10 - the most significant byte in Guid ByteArray [for SQL Server ORDERY BY clause]
|
|
}
|
|
return sqlOrderMap;
|
|
}
|
|
}
|
|
|
|
private Guid currentGuid;
|
|
|
|
public XSequentialGuid()
|
|
{
|
|
currentGuid = Guid.NewGuid();
|
|
}
|
|
|
|
public Guid GetCurrentGuid()
|
|
{
|
|
return currentGuid;
|
|
}
|
|
|
|
public Guid Next()
|
|
{
|
|
byte[] bytes = currentGuid.ToByteArray();
|
|
for (int mapIndex = 0; mapIndex < 16; mapIndex++)
|
|
{
|
|
int bytesIndex = SQLORDERMAP[mapIndex];
|
|
bytes[bytesIndex]++;
|
|
if (bytes[bytesIndex] != 0)
|
|
{
|
|
break; // No need to increment more significant bytes
|
|
}
|
|
}
|
|
currentGuid = new Guid(bytes);
|
|
return currentGuid;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Providers\XStringKeyGenerator.cs
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Interfaces;
|
|
using xModels.Base;
|
|
|
|
namespace xDataService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Default Guid Key Generator ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
|
|
public class XStringKeyGenerator<TEntity> : XKeyGenerator<TEntity, string>, IXKeyGenerator<TEntity, string>
|
|
where TEntity : XBaseEntity<string>
|
|
{
|
|
private readonly IXSequentialGuid sequentialGuid;
|
|
|
|
public XStringKeyGenerator(IXSequentialGuid sequentialGuid = null)
|
|
{
|
|
this.sequentialGuid = sequentialGuid;
|
|
}
|
|
|
|
public override async Task<string> GenerateKey(
|
|
IXBaseRepository<TEntity, string> repository,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await Task.CompletedTask;
|
|
|
|
//
|
|
if (sequentialGuid.IsNull())
|
|
{
|
|
return Guid.NewGuid().ToString();
|
|
}
|
|
else
|
|
{
|
|
return sequentialGuid.Next().ToString();
|
|
}
|
|
}
|
|
|
|
public override bool IsEmpty(string id)
|
|
{
|
|
return id.IsNullOrEmpty();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Base\XBaseEvent.cs
|
|
|
|
using System;
|
|
|
|
namespace xEventService.Base {
|
|
public abstract class XBaseEvent {
|
|
public string Type { get; protected set; }
|
|
public DateTime Timestamp { get; protected set; }
|
|
|
|
protected XBaseEvent () {
|
|
//
|
|
Type = GetType ().Name;
|
|
Timestamp = DateTime.UtcNow;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Configuration\XEventServiceConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using RabbitMQ.Client;
|
|
|
|
namespace xEventService.Configuration {
|
|
/// <summary>
|
|
/// a configuration class for describing how to connect rabbit mq server
|
|
/// and how channels must be declared ...
|
|
/// </summary>
|
|
public class XEventServiceConfiguration {
|
|
public string Server { get; set; }
|
|
public int Port { get; set; }
|
|
public string Username { get; set; }
|
|
public string Password { get; set; }
|
|
|
|
//
|
|
public bool AllowDynamicQueues { get; set; } = true;
|
|
public XQueueArgs DefaultQueueArgs { get; set; } = new XQueueArgs ();
|
|
public IDictionary<string, XQueueArgs> Queues { get; set; }
|
|
|
|
//
|
|
public bool AllowDynamicExchangess { get; set; } = true;
|
|
public XExchangeArgs DefaultExchangeArgs { get; set; } = new XExchangeArgs ();
|
|
public IDictionary<string, XExchangeArgs> Exchanges { get; set; }
|
|
|
|
//
|
|
public static XEventServiceConfiguration GetDefaults () {
|
|
return new XEventServiceConfiguration {
|
|
Port = 5672,
|
|
Username = "guest",
|
|
Password = "guest",
|
|
Server = "localhost",
|
|
Queues = new Dictionary<string, XQueueArgs> { { "XMainQueue", new XQueueArgs { Name = "XMainQueue" } }
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
public class XQueueArgs {
|
|
public string Name { get; set; }
|
|
public bool Durable { get; set; } = false;
|
|
public bool Exclusive { get; set; } = false;
|
|
public bool AutoDelete { get; set; } = true;
|
|
}
|
|
|
|
public class XExchangeArgs {
|
|
public string Name { get; set; }
|
|
public string Type { get; set; } = ExchangeType.Fanout;
|
|
public bool Durable { get; set; } = false;
|
|
public bool AutoDelete { get; set; } = true;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xEventService.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string EVENT_SERVICE_NODE_NAME = "EventServiceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xEventService.Configuration;
|
|
using xEventService.Constants;
|
|
using xEventService.Interfaces;
|
|
using xEventService.Models;
|
|
using xEventService.Providers;
|
|
|
|
namespace xEventService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Extract EventService Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XEventServiceConfiguration GetXEventServiceConfigurations (this IConfiguration source) {
|
|
//
|
|
var configSection = source
|
|
.GetSection (ConfigurationNodeNames.EVENT_SERVICE_NODE_NAME);
|
|
var result = configSection.Get<XEventServiceConfiguration> ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Event Service Configurations ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXEventServiceConfigurations (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
var config = configuration.GetXEventServiceConfigurations ();
|
|
services.AddXEventServiceConfigurations (config);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Event Service Configurations ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXEventServiceConfigurations (
|
|
this IServiceCollection services,
|
|
XEventServiceConfiguration configuration
|
|
) {
|
|
//
|
|
services.AddSingleton<XEventServiceConfiguration> (configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Event Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXEventService (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Check Configuration Registered ...
|
|
var config = services.GetRegisteredService<XEventServiceConfiguration> ();
|
|
if (config.IsNull ()) {
|
|
//
|
|
Console.WriteLine ($"XEventService: there is no provided XEventServiceConfiguration, using default ...");
|
|
|
|
//
|
|
// Register Default Configuration ...
|
|
services.AddXEventServiceConfigurations (configuration);
|
|
}
|
|
|
|
//
|
|
// Register IXEventBus ...
|
|
var serviceBas = services.GetRegisteredService<IXEventBus> ();
|
|
if (serviceBas.IsNull ()) {
|
|
services.AddSingleton<IXEventBus, XEventBus> ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register an Event Handler ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="lifetime"></param>
|
|
/// <typeparam name="TEvent"></typeparam>
|
|
/// <typeparam name="THandler"></typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXEventHandler<TEvent, THandler> (
|
|
this IServiceCollection services,
|
|
ServiceLifetime lifetime = ServiceLifetime.Transient
|
|
)
|
|
where TEvent : XEvent
|
|
where THandler : IXEventHandler<TEvent> {
|
|
//
|
|
services.Add (new ServiceDescriptor (
|
|
serviceType: typeof (THandler),
|
|
implementationType: typeof (THandler),
|
|
lifetime: lifetime
|
|
));
|
|
|
|
//
|
|
services.Add (new ServiceDescriptor (
|
|
serviceType: typeof (IXEventHandler<TEvent>),
|
|
implementationType: typeof (THandler),
|
|
lifetime: lifetime
|
|
));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subscribe to specific Event ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <typeparam name="TEvent"></typeparam>
|
|
/// <typeparam name="THandler"></typeparam>
|
|
/// <returns></returns>
|
|
public static void XEventSubscribe<TEvent, THandler> (
|
|
this IApplicationBuilder app,
|
|
bool toExchange = true
|
|
)
|
|
where TEvent : XEvent
|
|
where THandler : IXEventHandler<TEvent> {
|
|
//
|
|
var eventName = typeof (TEvent).Name;
|
|
|
|
//
|
|
// Retrieve EventBus from IOC ...
|
|
var eventBus = app.ApplicationServices.GetRequiredService<IXEventBus> ();
|
|
|
|
//
|
|
// Subscribe to Event Handler ...
|
|
var isSubscribed = eventBus.Subscribe<TEvent, THandler> ();
|
|
Console.WriteLine ($"XEventService: Event Handler subscription result: {eventName} => {isSubscribed} ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Extensions\ConfigurationExtensions.cs
|
|
|
|
using System;
|
|
using RabbitMQ.Client;
|
|
using xCommons.Extensions;
|
|
using xEventService.Configuration;
|
|
using xEventService.Models;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xEventService.Extensions {
|
|
public static class ConfigurationExtensions {
|
|
/// <summary>
|
|
/// Create Connection Factory Based on
|
|
/// provided Configuration ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static ConnectionFactory GetConnectionFactory (this XEventServiceConfiguration source) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull ()) {
|
|
XException.InvalidConfiguration.Throw ();
|
|
}
|
|
|
|
//
|
|
// Create Connection Factory ...
|
|
var result = new ConnectionFactory {
|
|
Port = source.Port,
|
|
HostName = source.Server,
|
|
UserName = source.Username,
|
|
Password = source.Password
|
|
};
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a Connection to Server ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IConnection Connect (this XEventServiceConfiguration source) {
|
|
//
|
|
// Open Connection ...
|
|
IConnection result = null;
|
|
try {
|
|
//
|
|
// Retrieve Connection Factory ...
|
|
var connectionFactory = source.GetConnectionFactory ();
|
|
|
|
//
|
|
// Create Connection ...
|
|
result = connectionFactory.CreateConnection ();
|
|
} catch (Exception ex) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Connection Failed, {ex.Message} ...");
|
|
|
|
//
|
|
XException.ActionFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Queue Name based on Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="queueName"></param>
|
|
public static void ValidateQueue (
|
|
this XEventServiceConfiguration source,
|
|
string queueName
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Validate Queues ...
|
|
if ((source.Queues.IsNull () &&
|
|
!source.AllowDynamicQueues) ||
|
|
(!source.Queues.IsNull () &&
|
|
!source.Queues.Keys.HasChild () &&
|
|
!source.AllowDynamicQueues)) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: there isn't any configured Queue ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Check queueName not empty ...
|
|
if (queueName.IsNullOrEmpty ()) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Invalid QueueName ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Check queueName Exists ...
|
|
if (!source.Queues.IsNull () &&
|
|
!source.Queues.ContainsKey (queueName) &&
|
|
!source.AllowDynamicQueues) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: QueueName {queueName} not found ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Exchange Name based on Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="exchangeName"></param>
|
|
public static void ValidateExchange (
|
|
this XEventServiceConfiguration source,
|
|
string exchangeName
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Validate Exchanges ...
|
|
if ((source.Exchanges.IsNull () &&
|
|
!source.AllowDynamicExchangess) ||
|
|
(!source.Exchanges.IsNull () &&
|
|
!source.Exchanges.Keys.HasChild () &&
|
|
!source.AllowDynamicExchangess)) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: there isn't any configured Exchanges ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Check exchangeName not empty ...
|
|
if (exchangeName.IsNullOrEmpty ()) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Invalid ExchangeName ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Check exchangeName Exists ...
|
|
if (!source.Exchanges.IsNull () &&
|
|
!source.Exchanges.ContainsKey (exchangeName) &&
|
|
!source.AllowDynamicExchangess) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: ExchangeName {exchangeName} not found ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve specific QueueArgs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="queueName"></param>
|
|
/// <returns></returns>
|
|
public static XQueueArgs GetQueueArgs (
|
|
this XEventServiceConfiguration source,
|
|
string queueName
|
|
) {
|
|
//
|
|
// Validate Queue Name ...
|
|
source.ValidateQueue (queueName);
|
|
|
|
//
|
|
var result = source.Queues
|
|
.IsNull () ? null : source
|
|
.Queues[queueName];
|
|
if (result.IsNull ()) {
|
|
//
|
|
// Prepare Default Queue ...
|
|
result = source.DefaultQueueArgs;
|
|
if (result.IsNull ()) {
|
|
result = new XQueueArgs () {
|
|
Name = queueName
|
|
};
|
|
} else {
|
|
result.Name = queueName;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve specific ExchangeArgs ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="exchangeName"></param>
|
|
/// <returns></returns>
|
|
public static XExchangeArgs GetExchangeArgs (
|
|
this XEventServiceConfiguration source,
|
|
string exchangeName
|
|
) {
|
|
//
|
|
// Validate Exchange Name ...
|
|
source.ValidateExchange (exchangeName);
|
|
|
|
//
|
|
var result = source.Exchanges
|
|
.IsNull () ? null : source
|
|
.Exchanges[exchangeName];
|
|
if (result.IsNull ()) {
|
|
//
|
|
// Prepare Default Queue ...
|
|
result = source.DefaultExchangeArgs;
|
|
if (result.IsNull ()) {
|
|
result = new XExchangeArgs () {
|
|
Name = exchangeName,
|
|
Type = ExchangeType.Fanout
|
|
};
|
|
} else {
|
|
result.Name = exchangeName;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a Channel ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="exchangeName"></param>
|
|
/// <returns></returns>
|
|
public static XChannel CreateChannel (
|
|
this XEventServiceConfiguration source,
|
|
string exchangeName = null
|
|
) {
|
|
//
|
|
// Validate ExchangeName and Retrieve ExchangeArgs if provided ...
|
|
var exchangeArgs = exchangeName
|
|
.IsNullOrEmpty () ?
|
|
null :
|
|
source.GetExchangeArgs (exchangeName);
|
|
|
|
//
|
|
// Create Connection ...
|
|
var connection = source.Connect ();
|
|
var channel = connection.CreateModel ();
|
|
|
|
//
|
|
// Create XChannel Model ...
|
|
var result = new XChannel (
|
|
exchangeName: exchangeName,
|
|
connection: connection
|
|
);
|
|
|
|
//
|
|
// Declaring Queue if Provided ...
|
|
if (!exchangeArgs.IsNull () &&
|
|
!exchangeName.IsNullOrEmpty ()) {
|
|
//
|
|
// Declaring Queue ...
|
|
result.Channel.ExchangeDeclare (
|
|
exchange: exchangeName,
|
|
type: exchangeArgs.Type,
|
|
durable: exchangeArgs.Durable,
|
|
autoDelete: exchangeArgs.AutoDelete
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Extensions\XEventModelExtensions.cs
|
|
|
|
using System;
|
|
using System.Text;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xEventService.Extensions {
|
|
public static class XEventModelExtensions {
|
|
/// <summary>
|
|
/// Convert an Object to bytes array for publishing
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static byte[] ToBody<T> (this T source) {
|
|
//
|
|
var json = source
|
|
.ToJSON ();
|
|
|
|
//
|
|
var result = json
|
|
.ToBytes ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert Recieved Bytes to Specific Type ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T FromBody<T> (this ReadOnlyMemory<byte> source) {
|
|
//
|
|
var jsonString = Encoding.UTF8
|
|
.GetString (
|
|
source.ToArray ()
|
|
);
|
|
var result = jsonString.FromJSON<T> ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Interfaces\IXEventBus.cs
|
|
|
|
using xEventService.Models;
|
|
|
|
namespace xEventService.Interfaces {
|
|
public interface IXEventBus {
|
|
bool Publish<T> (T @event) where T : XEvent;
|
|
|
|
bool Subscribe<TEvent, THandler> ()
|
|
where TEvent : XEvent
|
|
where THandler : IXEventHandler<TEvent>;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Interfaces\IXEventHandler.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xEventService.Models;
|
|
|
|
namespace xEventService.Interfaces {
|
|
public interface IXEventHandler<in TEvent> : IXEventHandler
|
|
where TEvent : XEvent {
|
|
Task HandleAsync (TEvent @event);
|
|
}
|
|
|
|
public interface IXEventHandler { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Models\XChannel.cs
|
|
|
|
using System;
|
|
using RabbitMQ.Client;
|
|
using RabbitMQ.Client.Events;
|
|
using xCommons.Extensions;
|
|
using xEventService.Configuration;
|
|
using xEventService.Extensions;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xEventService.Models {
|
|
public class XChannel {
|
|
//
|
|
public IModel Channel { get; protected set; }
|
|
public string QueueName { get; protected set; }
|
|
public string ExchangeName { get; protected set; }
|
|
public IConnection Connection { get; protected set; }
|
|
|
|
//
|
|
#region Constructors ...
|
|
public XChannel (
|
|
string exchangeName = null,
|
|
IConnection connection = null,
|
|
IModel channel = null,
|
|
EventingBasicConsumer consumer = null
|
|
) {
|
|
//
|
|
// Validate Connection ...
|
|
if (connection.IsNull ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
Connection = connection;
|
|
|
|
//
|
|
// Validate Channel ...
|
|
if (channel.IsNull ()) {
|
|
channel = connection.CreateModel ();
|
|
}
|
|
Channel = channel;
|
|
|
|
//
|
|
// Check Queue Name and it's Declaration ...
|
|
if (!exchangeName.IsNullOrEmpty ()) {
|
|
//
|
|
ExchangeName = exchangeName;
|
|
}
|
|
}
|
|
|
|
public XChannel (
|
|
XEventServiceConfiguration configuration,
|
|
bool dispatchConsumersAsync = true,
|
|
string exchangeName = null
|
|
) {
|
|
//
|
|
// Generate Factory ...
|
|
var factory = configuration.GetConnectionFactory ();
|
|
if (dispatchConsumersAsync) {
|
|
factory.DispatchConsumersAsync = true;
|
|
}
|
|
|
|
//
|
|
// Create Cahnnel ...
|
|
Connection = factory.CreateConnection ();
|
|
Channel = Connection.CreateModel ();
|
|
|
|
//
|
|
// Check Exchange Declaration if provided ...
|
|
if (!exchangeName.IsNullOrEmpty ()) {
|
|
//
|
|
ExchangeName = exchangeName;
|
|
var exchangeArgs = configuration.GetExchangeArgs (ExchangeName);
|
|
|
|
//
|
|
// Declaring Exchange ...
|
|
Channel.ExchangeDeclare (
|
|
exchange: exchangeName,
|
|
type: exchangeArgs.Type,
|
|
durable: exchangeArgs.Durable,
|
|
autoDelete: exchangeArgs.AutoDelete
|
|
);
|
|
|
|
//
|
|
// Create a Queue ...
|
|
var queueName = $"{exchangeName}[{Guid.NewGuid().ToString().GetDigits()}]";
|
|
var queueArgs = configuration.GetQueueArgs (queueName);
|
|
QueueName = queueName;
|
|
Channel.QueueDeclare (
|
|
queue: queueName,
|
|
durable: queueArgs.Durable,
|
|
exclusive: queueArgs.Exclusive,
|
|
autoDelete: queueArgs.AutoDelete
|
|
);
|
|
|
|
//
|
|
// Bind Queue to Exchange ...
|
|
Channel.QueueBind (
|
|
queue: queueName,
|
|
exchange: exchangeName,
|
|
routingKey: ""
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Close Channel ...
|
|
/// </summary>
|
|
public void CloseChannel () {
|
|
//
|
|
// Check Channel Exists ...
|
|
if (!this.Channel.IsNull ()) {
|
|
//
|
|
// Close Channel if it's Open ...
|
|
if (this.Channel.IsOpen) {
|
|
this.Channel.Close ();
|
|
}
|
|
|
|
//
|
|
this.Channel.Dispose ();
|
|
this.Channel = null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close Connection ...
|
|
/// </summary>
|
|
public void CloseConnection () {
|
|
//
|
|
// Check Connection Exists ...
|
|
if (!this.Connection.IsNull ()) {
|
|
//
|
|
// Close Connection if it's Open ...
|
|
if (this.Connection.IsOpen) {
|
|
this.Connection.Close ();
|
|
}
|
|
|
|
//
|
|
this.Connection.Dispose ();
|
|
this.Connection = null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Publish a Message through Channel on Declare Queue ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public bool Publish<T> (T message) {
|
|
//
|
|
// Validate Args ...
|
|
if (this.Connection.IsNull () ||
|
|
!this.Connection.IsOpen ||
|
|
this.Channel.IsNull () ||
|
|
!this.Channel.IsOpen) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Publish Failed ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
// Check Publish Method ...
|
|
//
|
|
// Check Exchange Name ...
|
|
if (this.ExchangeName.IsNullOrEmpty ()) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Publish Failed, Invalid Exchange Name {ExchangeName} ...");
|
|
|
|
//
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
try {
|
|
//
|
|
// Publish Message through Channel to Declared Queue ...
|
|
var body = message.ToBody ();
|
|
this.Channel.BasicPublish (
|
|
exchange: ExchangeName,
|
|
routingKey: "",
|
|
basicProperties : null,
|
|
body : body
|
|
);
|
|
|
|
//
|
|
return true;
|
|
} catch (Exception ex) {
|
|
//
|
|
Console.WriteLine ($"XEventService Exception: Publish Failed, {ex.Message} ...");
|
|
|
|
//
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Consume (EventingBasicConsumer consumer) {
|
|
Channel.BasicConsume (
|
|
queue: QueueName,
|
|
autoAck: true,
|
|
consumer: consumer
|
|
);
|
|
}
|
|
|
|
public void ConsumeAsync (AsyncEventingBasicConsumer consumer) {
|
|
Channel.BasicConsume (
|
|
queue: QueueName,
|
|
autoAck: true,
|
|
consumer: consumer
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose XChannel ...
|
|
/// </summary>
|
|
public void Dispose () {
|
|
//
|
|
this.CloseChannel ();
|
|
this.CloseConnection ();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Models\XEvent.cs
|
|
|
|
using xEventService.Base;
|
|
|
|
namespace xEventService.Models {
|
|
public class XEvent : XBaseEvent { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xEventService\Providers\XEventBus.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using RabbitMQ.Client.Events;
|
|
using xCommons.Extensions;
|
|
using xEventService.Configuration;
|
|
using xEventService.Extensions;
|
|
using xEventService.Interfaces;
|
|
using xEventService.Models;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xEventService.Providers {
|
|
public sealed class XEventBus : IXEventBus {
|
|
//
|
|
#region Properties ...
|
|
private readonly List<Type> events;
|
|
private readonly ILogger<XEventBus> logger;
|
|
private readonly IServiceScopeFactory serviceScopeFactory;
|
|
private readonly XEventServiceConfiguration configuration;
|
|
private readonly IDictionary<string, List<Type>> handlers;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructors ...
|
|
public XEventBus (
|
|
ILoggerFactory loggerFactory,
|
|
IServiceScopeFactory serviceScopeFactory,
|
|
XEventServiceConfiguration configuration
|
|
) {
|
|
//
|
|
this.configuration = configuration;
|
|
this.serviceScopeFactory = serviceScopeFactory;
|
|
|
|
//
|
|
events = new List<Type> ();
|
|
handlers = new Dictionary<string, List<Type>> ();
|
|
logger = loggerFactory.CreateLogger<XEventBus> ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Abstracts ...
|
|
public bool Publish<T> (T @event) where T : XEvent {
|
|
//
|
|
// Validate Args ...
|
|
if (@event.IsNull ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Prepare Channel ...
|
|
XChannel channel = null;
|
|
|
|
//
|
|
// Extract event name ...
|
|
var exchangeName = @event.GetType ().Name;
|
|
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Get XChannel Model ...
|
|
channel = configuration.CreateChannel (exchangeName);
|
|
|
|
//
|
|
// Publish Command ...
|
|
channel.Publish (message: @event);
|
|
|
|
//
|
|
// Return Result ...
|
|
return true;
|
|
} catch (Exception ex) {
|
|
//
|
|
logger.LogError ($"XEventService Exception: Publishing Failed {exchangeName}/{ex.Message} ...");
|
|
|
|
//
|
|
return false;
|
|
} finally {
|
|
//
|
|
if (!channel.IsNull ()) {
|
|
channel.Dispose ();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool Subscribe<TEvent, THandler> ()
|
|
where TEvent : XEvent
|
|
where THandler : IXEventHandler<TEvent> {
|
|
//
|
|
// Extract required data ...
|
|
var eventType = typeof (TEvent);
|
|
var eventName = eventType.Name;
|
|
var handlerType = typeof (THandler);
|
|
|
|
//
|
|
// Check event exists in list or not ...
|
|
if (!events.Contains (eventType)) {
|
|
//
|
|
// Add it if not exists ...
|
|
events.Add (eventType);
|
|
}
|
|
|
|
//
|
|
// Check handlers Dictionary contains list or not ...
|
|
if (!handlers.ContainsKey (eventName)) {
|
|
handlers.Add (eventName, new List<Type> ());
|
|
}
|
|
|
|
//
|
|
// Check handlers Subscribed before or not ...
|
|
var isHandlerSubscribed = handlers[eventName]
|
|
.Any (h => h.GetType () == handlerType);
|
|
if (isHandlerSubscribed) {
|
|
//
|
|
logger.LogError ($"XEventService Exception: Duplicate Event Handler Subscription {eventName}/{handlerType.Name} ...");
|
|
|
|
//
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Register Handler ...
|
|
handlers[eventName].Add (handlerType);
|
|
|
|
//
|
|
// Do Consuming Handler ...
|
|
ConsumeEvent<TEvent> ();
|
|
|
|
//
|
|
return true;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Consume Specific Event ...
|
|
/// </summary>
|
|
/// <typeparam name="TEvent"></typeparam>
|
|
private void ConsumeEvent<TEvent> ()
|
|
where TEvent : XEvent {
|
|
//
|
|
// Extract required data ...
|
|
var eventType = typeof (TEvent);
|
|
var eventName = eventType.Name;
|
|
|
|
//
|
|
// Create ChannelObject ...
|
|
var channel = new XChannel (
|
|
exchangeName: eventName,
|
|
configuration: configuration,
|
|
dispatchConsumersAsync: true
|
|
);
|
|
|
|
//
|
|
// Create Consumer ...
|
|
var consumer = new AsyncEventingBasicConsumer (channel.Channel);
|
|
|
|
//
|
|
// Set Consumer Delegate ...
|
|
consumer.Received += XConsumerReceivedDelegate;
|
|
|
|
//
|
|
// Consume Async Consumer ...
|
|
channel.ConsumeAsync (consumer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// this Delegate method calls when a message recieved ...
|
|
/// </summary>
|
|
private async Task XConsumerReceivedDelegate (
|
|
object sender,
|
|
BasicDeliverEventArgs ea
|
|
) {
|
|
//
|
|
// Generate Required Data ...
|
|
var eventName = ea.Exchange;
|
|
var json = Encoding.UTF8
|
|
.GetString (
|
|
ea.Body
|
|
.ToArray ()
|
|
);
|
|
|
|
//
|
|
// Do Processing Event ...
|
|
try {
|
|
//
|
|
// Process Event in non Blocking Tasks ...
|
|
await ProcessEvent (eventName, json)
|
|
.ConfigureAwait (false);
|
|
} catch (Exception ex) {
|
|
//
|
|
logger.LogError ($"XEventService Exception: Processing Event failed {eventName}/{ex.Message} ...");
|
|
|
|
//
|
|
XException.ActionFailed.Throw ();
|
|
} finally {
|
|
//
|
|
var channel = ((EventingBasicConsumer) sender).Model;
|
|
channel.BasicAck (
|
|
deliveryTag: ea.DeliveryTag,
|
|
multiple: false
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Here we must call registered Event Handlers to Handle the Event ...
|
|
/// </summary>
|
|
private async Task ProcessEvent (
|
|
string eventName,
|
|
string json
|
|
) {
|
|
//
|
|
// Check Handler Exists for current Event ...
|
|
var isExistsHandler = handlers.ContainsKey (eventName);
|
|
if (!isExistsHandler) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Using Service Scope Factory ...
|
|
using (var scope = serviceScopeFactory.CreateScope ()) {
|
|
//
|
|
// Get Handler Subscriptions ...
|
|
var subscriptions = handlers[eventName];
|
|
foreach (var subscription in subscriptions) {
|
|
//
|
|
// Inject Handler from Dependency Injections ...
|
|
var handler = scope.ServiceProvider.GetService (subscription);
|
|
if (handler.IsNull ()) {
|
|
//
|
|
logger.LogInformation ($"XEventService: there is no handler Registered in DependencyInjection for {eventName}/{subscription.Name}");
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Event Type ...
|
|
var eventType = events.SingleOrDefault (t => t.Name == eventName);
|
|
var @event = json.FromJSON (eventType);
|
|
var conreteType = typeof (IXEventHandler<>).MakeGenericType (eventType);
|
|
|
|
//
|
|
// Call EventHandler 'HandleAsync' method ...
|
|
await ((Task) conreteType
|
|
.GetMethod (nameof (IXEventHandler<XEvent>.HandleAsync))
|
|
.Invoke (handler, new object[] { @event }))
|
|
.ConfigureAwait (true);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xExceptions\Attributes\StringValueAttribute.cs
|
|
|
|
using System;
|
|
|
|
namespace xExceptions.Attributes
|
|
{
|
|
/// <summary>
|
|
/// an attribute which attached to enums to carry propper string
|
|
/// </summary>
|
|
public partial class StringValueAttribute : System.Attribute {
|
|
public string StringValue { get; set; }
|
|
|
|
public StringValueAttribute (string value) {
|
|
this.StringValue = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xExceptions\Constants\XException.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xExceptions.Constants
|
|
{
|
|
public enum XException {
|
|
//
|
|
#region Invalid Exceptions 1xx ...
|
|
[StringValue ("Invalid Data ...")]
|
|
InvalidData = 100,
|
|
|
|
//
|
|
[StringValue ("Invalid Date ...")]
|
|
InvalidDate = 101,
|
|
|
|
//
|
|
[StringValue ("Bad Request ...")]
|
|
BadRequest = 102,
|
|
|
|
//
|
|
[StringValue ("Invalid Args ...")]
|
|
InvalidArgs = 103,
|
|
|
|
//
|
|
[StringValue ("Invalid Message ...")]
|
|
InvalidMessage = 104,
|
|
|
|
//
|
|
[StringValue ("Invalid Token ...")]
|
|
InvalidToken = 105,
|
|
|
|
//
|
|
[StringValue ("Invalid Verification Code ...")]
|
|
InvalidVerificationCode = 106,
|
|
|
|
//
|
|
[StringValue ("Invalid Email Address ...")]
|
|
InvalidEmailAddress = 107,
|
|
|
|
//
|
|
[StringValue ("Invalid Mobile Number ...")]
|
|
InvalidMobileNumber = 108,
|
|
|
|
//
|
|
[StringValue ("Invalid Password ...")]
|
|
InvalidPassword = 109,
|
|
|
|
//
|
|
[StringValue ("Inavlid Url ...")]
|
|
InavlidUrl = 110,
|
|
|
|
//
|
|
[StringValue ("Invalid Device ...")]
|
|
InvalidDevice = 111,
|
|
|
|
//
|
|
[StringValue ("Invalid Profile Image ...")]
|
|
InvalidProfileImage = 112,
|
|
|
|
//
|
|
[StringValue ("Invalid File ...")]
|
|
InavlidFile = 113,
|
|
|
|
//
|
|
[StringValue ("Invalid Username ...")]
|
|
InvalidUserName = 114,
|
|
#endregion
|
|
|
|
//
|
|
#region Not (...) Exceptions 2xx ...
|
|
//
|
|
[StringValue ("Not Found ...")]
|
|
NotFound = 200,
|
|
|
|
//
|
|
[StringValue ("Not Allowed ...")]
|
|
NotAllowed = 201,
|
|
|
|
//
|
|
[StringValue ("Not Authorized ...")]
|
|
NotAuthorized = 202,
|
|
|
|
//
|
|
[StringValue ("Not Visible ...")]
|
|
NotVisible = 203,
|
|
#endregion
|
|
|
|
//
|
|
#region User/Registration/Account/Bann Exceptions 3xx ...
|
|
//
|
|
[StringValue ("Account Locked out Until:{0}")]
|
|
AccountLockedOut = 300,
|
|
|
|
//
|
|
[StringValue ("Login Failed ...")]
|
|
LoginFailed = 301,
|
|
|
|
//
|
|
[StringValue ("User Registered Before ...")]
|
|
UserRegisteredBefore = 302,
|
|
|
|
//
|
|
[StringValue ("User Disabled ...")]
|
|
UserDisabled = 303,
|
|
//
|
|
[StringValue ("Device Banned Until:{0}")]
|
|
DeviceBanned = 304,
|
|
|
|
//
|
|
[StringValue ("You can't Request Verification code Until:{0}")]
|
|
VerificationCodeResendNotAllowed = 305,
|
|
|
|
//
|
|
[StringValue ("Passwords Same ...")]
|
|
PasswordsSame = 306,
|
|
|
|
//
|
|
[StringValue ("Mobiles Same ...")]
|
|
MobilesSame = 307,
|
|
|
|
//
|
|
[StringValue ("Emails Same ...")]
|
|
EmailsSame = 308,
|
|
|
|
//
|
|
[StringValue ("Mobile In Used ...")]
|
|
MobileInUsed = 309,
|
|
|
|
//
|
|
[StringValue ("Email In Used ...")]
|
|
EmailInUsed = 310,
|
|
|
|
//
|
|
[StringValue ("Mobile Not Confirmed ...")]
|
|
MobileNotConfirmed = 311,
|
|
|
|
//
|
|
[StringValue ("Email Not Confirmed ...")]
|
|
EmailNotConfirmed = 312,
|
|
|
|
//
|
|
[StringValue ("Post Banned ...")]
|
|
PostBanned = 313,
|
|
|
|
//
|
|
[StringValue ("User Banned ...")]
|
|
UserBanned = 314,
|
|
#endregion
|
|
|
|
//
|
|
#region General Exceptions 4xx ...
|
|
//
|
|
[StringValue ("Unknown Error ...")]
|
|
Unknown = 400,
|
|
|
|
//
|
|
[StringValue ("Duplicate ...")]
|
|
Duplicate = 401,
|
|
|
|
//
|
|
[StringValue ("Action Failed ...")]
|
|
ActionFailed = 402,
|
|
|
|
//
|
|
[StringValue ("Expired Date ...")]
|
|
ExpiredDate = 403,
|
|
|
|
//
|
|
[StringValue ("Unavailable ...")]
|
|
Unavailable = 404,
|
|
|
|
//
|
|
[StringValue ("Max Allowed Tag Exceeded ...")]
|
|
MaxAllowedTagExceeded = 405,
|
|
|
|
//
|
|
[StringValue ("Timed out ...")]
|
|
Timeout = 406,
|
|
#endregion
|
|
|
|
//
|
|
#region File Exceptions 5xx ...
|
|
//
|
|
[StringValue ("Empty File ...")]
|
|
EmptyFile = 500,
|
|
|
|
//
|
|
[StringValue ("max File size exceeded ...")]
|
|
MaxFileSizeExceeded = 501,
|
|
|
|
//
|
|
[StringValue ("Unsupported File Type ...")]
|
|
UnsupportedFileType = 502,
|
|
|
|
//
|
|
[StringValue ("Max Allowed Media Exceeded ...")]
|
|
MaxAllowedMediaExceeded = 503,
|
|
#endregion
|
|
|
|
//
|
|
#region Configuration Exceptions 6xx ...
|
|
//
|
|
[StringValue ("Invalid Configuration ...")]
|
|
InvalidConfiguration = 600,
|
|
|
|
//
|
|
[StringValue ("Storage Service Initiallization Failed ...")]
|
|
StorageServiceInitialFailed = 601,
|
|
|
|
//
|
|
[StringValue ("Message Service Initialization Failed ...")]
|
|
MessageServiceInitialFailed = 602,
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xExceptions\Models\XError.cs
|
|
|
|
namespace xExceptions.Models {
|
|
public partial class XError {
|
|
/// <summary>
|
|
/// th ID of Error
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// the String Value of Error
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Message { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Configurations\Entities\XFileEntityConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xFileService.Constants;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Configurations.Entities
|
|
{
|
|
public class XFileEntityConfiguration : XBaseEntityTypeConfiguration<XFile, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XFile> builder)
|
|
{
|
|
builder.ToTable(XFileServiceConstants.XFileTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Constants\XFileServiceConstants.cs
|
|
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Constants
|
|
{
|
|
public struct XFileServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XFileServiceDILogTag = "XFileService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XFileTable = "Files";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XFileSingleName = "file";
|
|
public const string XFileCollectionName = "files";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XFileDtoHub = "fileDto";
|
|
public const string XFileEntityHub = "fileEntity";
|
|
|
|
//
|
|
// Custome Constants ...
|
|
public const string XFileTagProvided = nameof(XFile);
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXFileEFRepositoryDescriptor = "GetXFileEFRepositoryDescriptor";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityService.Interfaces;
|
|
using xTagService.Controllers;
|
|
|
|
namespace xFileService.Controllers
|
|
{
|
|
public abstract class XFileProviderControllerBase : XBaseProvidedHasTagControllerBase<XFile, XFileDto, Guid, XFileDtoHub>, IXFileProviderController
|
|
{
|
|
private readonly IXFileProvider provider;
|
|
|
|
protected XFileProviderControllerBase(
|
|
ILogger<XFileProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXFileProvider provider,
|
|
IXFileTagProvided tagProvided,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
tagProvided,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Stream/ById")]
|
|
public virtual async Task<ActionResult> Stream(
|
|
[FromRoute] Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider.Stream(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{name}/Stream/ByName")]
|
|
public virtual async Task<ActionResult> Stream(
|
|
[FromRoute] string name,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider.Stream(
|
|
name: name,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Download/ById")]
|
|
public virtual async Task<ActionResult> Download(
|
|
[FromRoute] Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider.Download(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{name}/Download/ByName")]
|
|
public virtual async Task<ActionResult> Download(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider.Download(
|
|
name: name,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload Files ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Upload")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
public virtual async Task<ActionResult<IEnumerable<XFileDto>>> Upload(
|
|
[FromForm] IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Retrieve User Info ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Upload(
|
|
files: files,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Files ...
|
|
/// </summary>
|
|
/// <param name="ids"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("")]
|
|
public virtual async Task<ActionResult<IEnumerable<Guid>>> Remove(
|
|
[FromQuery] string ids,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Retrieve User Info ...
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Remove(
|
|
ids: ids,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Reference ...
|
|
/// <summary>
|
|
/// Check an Item Has Reference to Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Reference/IsProvidedFor")]
|
|
public virtual async Task<ActionResult<bool>> IsProvidedFor(
|
|
[FromRoute] Guid id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotEmpty(providedFor)
|
|
.AddNotNull(forProvidedId)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.IsProvidedFor(
|
|
id: id,
|
|
providedFor: providedFor,
|
|
forProvidedId: forProvidedId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Reference to Item for Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/Reference")]
|
|
public virtual async Task<ActionResult> AddReference(
|
|
[FromRoute] Guid id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
[FromQuery] int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotEmpty(providedFor)
|
|
.AddNotNull(forProvidedId)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
await provider.AddReference(
|
|
id: id,
|
|
forIndex: forIndex,
|
|
userInfo: userInfo,
|
|
providedFor: providedFor,
|
|
connectionId: connectionId,
|
|
forProvidedId: forProvidedId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Reference from Item for Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}/Reference")]
|
|
public virtual async Task<ActionResult> RemoveReference(
|
|
[FromRoute] Guid id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
[FromQuery] int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotEmpty(providedFor)
|
|
.AddNotNull(forProvidedId)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
await provider.RemoveReference(
|
|
id: id,
|
|
forIndex: forIndex,
|
|
userInfo: userInfo,
|
|
providedFor: providedFor,
|
|
connectionId: connectionId,
|
|
forProvidedId: forProvidedId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specified Itemfor providedFor ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="TReferenceKey"></typeparam>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/References")]
|
|
public virtual async Task<ActionResult<IEnumerable<XReference<string>>>> GetReferences(
|
|
[FromRoute] Guid id,
|
|
[FromQuery] string providedFor,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotEmpty(providedFor)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.GetReferences(
|
|
id: id,
|
|
providedFor: providedFor,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileRepositoryControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Controllers
|
|
{
|
|
public abstract class XFileRepositoryControllerBase : XBaseRepositoryController<XFile, Guid>, IXBaseRepositoryController<XFile, Guid>
|
|
{
|
|
protected XFileRepositoryControllerBase(
|
|
ILogger<XFileRepositoryControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXFileRepository repository,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repository,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileRepositoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Entities;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Controllers
|
|
{
|
|
public abstract class XFileRepositoryProviderControllerBase : XBaseRepositoryProviderController<XFile, Guid, XFileEntityHub>, IXBaseRepositoryProviderController<XFile, Guid, XFileEntityHub>
|
|
{
|
|
protected XFileRepositoryProviderControllerBase(
|
|
ILogger<XFileRepositoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXFileRepositoryProvider provider,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileServiceControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Controllers
|
|
{
|
|
public abstract class XFileServiceControllerBase : XBaseServiceController<XFile, XFileDto, Guid>, IXBaseServiceController<XFile, XFileDto, Guid>
|
|
{
|
|
protected XFileServiceControllerBase(
|
|
ILogger<XFileServiceControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXFileRepositoryService repositoryService,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repositoryService,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileServiceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Controllers
|
|
{
|
|
public abstract class XFileServiceProviderControllerBase : XBaseServiceProviderController<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseServiceProviderController<XFile, XFileDto, Guid, XFileDtoHub>
|
|
{
|
|
protected XFileServiceProviderControllerBase(
|
|
ILogger<XFileServiceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXFileServiceProvider provider,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
using xFileService.Helpers;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xFileService.Providers.Entities;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Providers;
|
|
using xFileService.Constants;
|
|
|
|
namespace xFileService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXFileService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddFileService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXFileService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddFileService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XFileService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXFileService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using XFile Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
pushHelper.AddHub<XFileDtoHub>(XFileServiceConstants.XFileDtoHub);
|
|
pushHelper.AddHub<XFileEntityHub>(XFileServiceConstants.XFileEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XFile Repository Descriptor ...
|
|
if (!descriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: descriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor descriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XFileServiceConstants.XFileServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddFileService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch (repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
descriptor = typeof(XFileServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XFileServiceConstants.GetXFileEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
descriptor = XFileServiceHelper.GetXFileMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
descriptor = XFileServiceHelper.GetXFileInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Register XFile Repository Descriptor ...
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: descriptor
|
|
);
|
|
|
|
//
|
|
// Register Dto Services ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileServiceProvider), typeof(XFileServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileRepositoryService), typeof(XFileRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileRepositoryProvider), typeof(XFileRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Register Additional Service ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileTagProvider), typeof(XFileTagProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileTagProvided), typeof(XFileTagProvided), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXFileProvider), typeof(XFileProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Extensions\XModelExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XFile source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XFileDto source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XFile UpdateReferences(
|
|
this XFile source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XFile result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XFileDto UpdateReferences(
|
|
this XFileDto source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XFileDto result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Helpers\XFileServiceHelper.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Entities;
|
|
using xFileService.Providers.GraphQL;
|
|
|
|
namespace xFileService.Helpers
|
|
{
|
|
public static class XFileServiceHelper
|
|
{
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileEFRepository<TContext>,
|
|
TContext
|
|
> GetXFileEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileEFRepository<TContext>,
|
|
TContext,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
> GetXFileEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileEFRepository<TContext>,
|
|
TContext,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileMongoRepository
|
|
> GetXFileMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileMongoRepository,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
> GetXFileMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileMongoRepository,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileInMemoryRepository
|
|
> GetXFileInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileInMemoryRepository,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
> GetXFileInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XFile,
|
|
Guid,
|
|
IXFileKeyGenerator,
|
|
XFileKeyGenerator,
|
|
IXFileRepositoryEvents,
|
|
XFileRepositoryEvents,
|
|
XFileGraphType,
|
|
GuidGraphType,
|
|
XFileGraphQuery,
|
|
IXFileGraphQLTypeHelper,
|
|
XFileGraphQLTypeHelper,
|
|
XFileGraphSchema,
|
|
IXFileRepository,
|
|
XFileInMemoryRepository,
|
|
IXFileSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileDtoHub.cs
|
|
|
|
using System;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces.Dtos
|
|
{
|
|
public interface IXFileDtoHub : IXBaseDtoHub<XFile, XFileDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileRepositoryService.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Dtos
|
|
{
|
|
public interface IXFileRepositoryService : IXBaseRepositoryService<XFile, XFileDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileServiceProvider.cs
|
|
|
|
using System;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces.Dtos
|
|
{
|
|
public interface IXFileServiceProvider : IXBaseDtoProvider<XFile, XFileDto, Guid, XFileDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileEntityHub.cs
|
|
|
|
using System;
|
|
using xFileService.Models.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileEntityHub : IXBaseEntityHub<XFile, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XFile, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileKeyGenerator.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileKeyGenerator : IXKeyGenerator<XFile, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileRepository : IXBaseRepository<XFile, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileRepositoryEvents : IXBaseRepositoryEvents<XFile>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Entities;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileRepositoryProvider : IXBaseEntityProvider<XFile, Guid, XFileEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileSeeder.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Interfaces.Entities
|
|
{
|
|
public interface IXFileSeeder : IXBaseDbSeeder<XFile, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Interfaces;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces
|
|
{
|
|
public interface IXFileProvider : IXBaseProvidedHasTag<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseReferenced<XFile, Guid>
|
|
{
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<FileStreamResult> Stream(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<FileStreamResult> Stream(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<PhysicalFileResult> Download(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<PhysicalFileResult> Download(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Upload Files ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XFileDto>> Upload(
|
|
IFormFileCollection files,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Files ...
|
|
/// </summary>
|
|
/// <param name="ids"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<Guid>> Remove(
|
|
string ids,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XFileStreamDescriptorDto> GetFileDescriptor(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XFileStreamDescriptorDto> GetFileDescriptor(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileProviderController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityService.Interfaces;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces
|
|
{
|
|
public interface IXFileProviderController : IXBaseProvidedHasTagController<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseReferencedController<XFile, Guid>
|
|
{
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Stream/ById")]
|
|
Task<ActionResult> Stream(
|
|
[FromRoute] Guid id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{name}/Stream/ByName")]
|
|
Task<ActionResult> Stream(
|
|
[FromRoute] string name,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Download/ById")]
|
|
Task<ActionResult> Download(
|
|
[FromRoute] Guid id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{name}/Download/ByName")]
|
|
Task<ActionResult> Download(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Upload Files ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Upload")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
Task<ActionResult<IEnumerable<XFileDto>>> Upload(
|
|
[FromForm] IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Files ...
|
|
/// </summary>
|
|
/// <param name="ids"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("")]
|
|
Task<ActionResult<IEnumerable<Guid>>> Remove(
|
|
[FromQuery] string ids,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileTagProvided.cs
|
|
|
|
using System;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces
|
|
{
|
|
public interface IXFileTagProvided : IXTagProvided<XFile, XFileDto, Guid, XFileDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileTagProvider.cs
|
|
|
|
using System;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xFileService.Interfaces
|
|
{
|
|
public interface IXFileTagProvider : IXBaseTagProvider<Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Dtos\XFileDto.cs
|
|
|
|
using System;
|
|
using xCommons.Constants;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xFileService.Models.Dtos
|
|
{
|
|
public class XFileDto : XBaseGuidIDEntityDto
|
|
{
|
|
public XFileType Type { get; set; }
|
|
public string Name { get; set; }
|
|
public string Thumb { get; set; }
|
|
public string Path { get; set; }
|
|
public string ThumbPath { get; set; }
|
|
public DateTime UploadedOn { get; set; }
|
|
public string FileName { get; set; }
|
|
|
|
public string OwnerId { get; set; }
|
|
public XPersonDto Owner { get; set; }
|
|
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Dtos\XFileStreamDescriptorDto.cs
|
|
|
|
using System.IO;
|
|
using xModels.Base;
|
|
|
|
namespace xFileService.Models.Dtos
|
|
{
|
|
public class XFileStreamDescriptorDto : XBaseDto
|
|
{
|
|
public Stream Stream { get; set; }
|
|
public string MIMEType { get; set; }
|
|
public string Name { get; set; }
|
|
public string Path { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Entities\XFile.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xCommons.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xFileService.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Specified File in Server ...
|
|
/// </summary>
|
|
public class XFile : XBaseGuidIDEntity
|
|
{
|
|
/// <summary>
|
|
/// Specified File Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XFileType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// File Name on Server ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// File Path On Server ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
public string Path { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail FIle Name ...
|
|
/// if File Type Supported Thumbnail ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Thumb { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail File Path ...
|
|
/// if File Type Supported Thumbnail ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string ThumbPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// File Uploading Time ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public DateTime UploadedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Request For Upload File Name on Client ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string FileName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Comma Separated List Which Provides Pointer to Specified
|
|
/// Model for Describe ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xFileService.Providers.Dtos
|
|
{
|
|
public class XFileDtoHub : XBaseDtoHub<XFile, XFileDto, Guid>, IXFileDtoHub
|
|
{
|
|
public XFileDtoHub(
|
|
ILogger<XFileDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Dtos
|
|
{
|
|
public class XFileRepositoryService : XBaseRepositoryService<XFile, XFileDto, Guid>, IXFileRepositoryService
|
|
{
|
|
public XFileRepositoryService(
|
|
IXFileRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xFileService.Providers.Dtos
|
|
{
|
|
public class XFileServiceProvider : XBaseDtoProvider<XFile, XFileDto, Guid, XFileDtoHub>, IXFileServiceProvider
|
|
{
|
|
public XFileServiceProvider(
|
|
IHubContext<XFileDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXFileRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileEFRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileEFRepository<TContext> : XBaseEFRepository<XFile, Guid, TContext>, IXFileRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XFileEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXFileKeyGenerator keyGenerator = null,
|
|
IXFileRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
using xPushService.Base;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileEntityHub : XBaseEntityHub<XFile, Guid>, IXFileEntityHub
|
|
{
|
|
public XFileEntityHub(
|
|
ILogger<XFileEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileInMemoryRepository : XBaseInMemoryRepository<XFile, Guid>, IXFileRepository
|
|
{
|
|
public XFileInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXFileKeyGenerator keyGenerator = null,
|
|
IXFileRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileKeyGenerator : XGuidKeyGenerator<XFile>, IXFileKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileMongoRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileMongoRepository : XBaseMongoRepository<XFile, Guid>, IXFileRepository
|
|
{
|
|
public XFileMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXFileKeyGenerator keyGenerator = null,
|
|
IXFileRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileRepositoryEvents : XBaseRepositoryEvents<XFile>, IXFileRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public class XFileRepositoryProvider : XBaseEntityProvider<XFile, Guid, XFileEntityHub>, IXFileRepositoryProvider
|
|
{
|
|
public XFileRepositoryProvider(
|
|
IHubContext<XFileEntityHub> hub,
|
|
IXFileRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileSeederBase.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.Entities
|
|
{
|
|
public abstract class XFileSeederBase : XBaseDbSeeder<XFile, Guid>, IXFileSeeder
|
|
{
|
|
protected XFileSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXFileRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xFileService.Constants;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.GraphQL
|
|
{
|
|
public class XFileGraphQLTypeHelper : XBaseGraphQLTypeHelper<XFile, Guid>, IXFileGraphQLTypeHelper
|
|
{
|
|
public XFileGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XFileServiceConstants.XFileCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XFileServiceConstants.XFileSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xFileService.Interfaces.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.GraphQL
|
|
{
|
|
public class XFileGraphQuery : XBaseGraphQLQuery<XFile, Guid, XFileGraphType, GuidGraphType>
|
|
{
|
|
public XFileGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXFileRepository repository,
|
|
IXFileGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xFileService.Providers.GraphQL
|
|
{
|
|
public class XFileGraphSchema : Schema
|
|
{
|
|
public XFileGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XFileGraphQuery)services.GetService(typeof(XFileGraphQuery));
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphType.cs
|
|
|
|
using System;
|
|
using xDataService.GraphQL;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers.GraphQL
|
|
{
|
|
public class XFileGraphType : XBaseGraphObjectType<XFile, Guid>
|
|
{
|
|
public XFileGraphType() : base()
|
|
{
|
|
Field(x => x.Type);
|
|
Field(x => x.Name);
|
|
Field(x => x.Path);
|
|
Field(x => x.Thumb);
|
|
Field(x => x.OwnerId);
|
|
Field(x => x.FileName);
|
|
Field(x => x.ThumbPath);
|
|
Field(x => x.UploadedOn);
|
|
Field(x => x.References);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileEntityRegisterar.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xFileService.Configurations.Entities;
|
|
using xFileService.Models.Entities;
|
|
|
|
namespace xFileService.Providers
|
|
{
|
|
public class XFileEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XFileEntityRegisterar()
|
|
: base(nameof(XFileEntityRegisterar))
|
|
{
|
|
//
|
|
// Add XFile Entity ...
|
|
AddEntity<XFile, Guid>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XFileEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.StaticFiles;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Extensions;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xFileService.Extensions;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xStorageService.Interfaces;
|
|
using xTagService.Providers;
|
|
|
|
namespace xFileService.Providers
|
|
{
|
|
public class XFileProvider : XBaseProvidedHasTag<XFile, XFileDto, Guid, XFileDtoHub>, IXFileProvider
|
|
{
|
|
private readonly IXFileServiceProvider provider;
|
|
private readonly IXStorageProvider storageProvider;
|
|
|
|
public XFileProvider(
|
|
IXFileTagProvider tagProvider,
|
|
IXFileServiceProvider provider,
|
|
IXStorageProvider storageProvider
|
|
) : base(
|
|
provider: provider,
|
|
tagProvider: tagProvider,
|
|
permittedRoles: new string[] { "admin" }
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.storageProvider = storageProvider;
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XFile item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!item.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
!item.OwnerId.IsNullOrEmpty() &&
|
|
userInfo.UserId == item.OwnerId;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XFileDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!item.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
!item.OwnerId.IsNullOrEmpty() &&
|
|
userInfo.UserId == item.OwnerId;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<FileStreamResult> Stream(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !id.IsNull() &&
|
|
!id.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Stream Info and Validate it ...
|
|
var stream = await GetFileDescriptor(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (stream.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Result Model ...
|
|
var result = new FileStreamResult(
|
|
stream.Stream,
|
|
stream.MIMEType
|
|
)
|
|
{
|
|
FileDownloadName = stream.Name
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<FileStreamResult> Stream(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !name.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Stream Info and Validate it ...
|
|
var stream = await GetFileDescriptor(
|
|
fileName: name,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (stream.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Result Model ...
|
|
var result = new FileStreamResult(
|
|
stream.Stream,
|
|
stream.MIMEType
|
|
)
|
|
{
|
|
FileDownloadName = stream.Name
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<PhysicalFileResult> Download(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !id.IsNull() &&
|
|
!id.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Stream Info and Validate it ...
|
|
var stream = await GetFileDescriptor(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (stream.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Result Model ...
|
|
var result = new PhysicalFileResult(
|
|
stream.Path,
|
|
stream.MIMEType
|
|
)
|
|
{
|
|
FileDownloadName = stream.Name
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<PhysicalFileResult> Download(
|
|
string name,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !name.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Stream Info and Validate it ...
|
|
var stream = await GetFileDescriptor(
|
|
fileName: name,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (stream.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Result Model ...
|
|
var result = new PhysicalFileResult(
|
|
stream.Path,
|
|
stream.MIMEType
|
|
)
|
|
{
|
|
FileDownloadName = stream.Name
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload Files ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XFileDto>> Upload(
|
|
IFormFileCollection files,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !files.IsNull() &&
|
|
files.HasChild() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Save Files On Server Side Physically ...
|
|
// and Validate it ...
|
|
var uploadResults = await storageProvider
|
|
.HandleFilesSave(files);
|
|
isValid = uploadResults.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new List<XFileDto>();
|
|
foreach (var ur in uploadResults)
|
|
{
|
|
//
|
|
var fileType = storageProvider.GetFileType(ur.FileName);
|
|
|
|
//
|
|
// Create Item Model ...
|
|
var item = new XFileDto
|
|
{
|
|
Type = fileType,
|
|
FileName = ur.Name,
|
|
Name = ur.FileName,
|
|
Path = ur.FilePath,
|
|
Thumb = ur.Thmbnail,
|
|
OwnerId = userInfo.UserId,
|
|
ThumbPath = ur.ThmbnailPath,
|
|
UploadedOn = DateTime.UtcNow,
|
|
};
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Add Entity Model to DB ...
|
|
item = await Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result.Add(item);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Files ...
|
|
/// </summary>
|
|
/// <param name="ids"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<Guid>> Remove(
|
|
string ids,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isValid = !ids.IsNullOrEmpty() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Parse ID(s) List ...
|
|
var idsList = ids.ParseListGuid();
|
|
isValid = !idsList.IsNull() &&
|
|
idsList.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Loop Through Parsed Ids and Try to Remove ...
|
|
var result = new List<Guid>();
|
|
foreach (var id in idsList)
|
|
{
|
|
//
|
|
// Retrieve XFileDto and Validate it ...
|
|
var model = await Get(id);
|
|
isValid = !model.IsNull() && !model.Id.IsNull() && !model.Id.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Physical File Exists or not ...
|
|
var fileFullPath = storageProvider.GetFileFullPath(model.Name);
|
|
var thumbFullPath = model.Thumb.IsNullOrEmpty()
|
|
? ""
|
|
: storageProvider.GetThumbnailFileFullPath(model.Thumb);
|
|
var isFileExists = storageProvider.IsFileExists(fileFullPath);
|
|
var isThumbExists = model.Thumb.IsNullOrEmpty()
|
|
? false
|
|
: storageProvider.IsFileExists(thumbFullPath);
|
|
|
|
//
|
|
// Remove Physical Thumbnail File ...
|
|
if (isThumbExists)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Removed Stored Thumbnail ...
|
|
storageProvider.DeleteFile(
|
|
fileFullPath: thumbFullPath,
|
|
forceFileExists: false
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
// Remove Pgysical File ...
|
|
if (isFileExists)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Remove Stored File ...
|
|
storageProvider.DeleteFile(
|
|
fileFullPath: fileFullPath,
|
|
forceFileExists: false
|
|
);
|
|
|
|
//
|
|
// Remove Tags ...
|
|
await DetachTags(
|
|
id: id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
// Remove File Entty ...
|
|
var item = await provider.RemoveAsync(
|
|
id: model.Id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result.Add(model.Id);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XFileStreamDescriptorDto> GetFileDescriptor(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check File Model Exists or not ...
|
|
var isExists = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Item and Validate it ...
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (item.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Physical File Path and Validate it ...
|
|
var fileFullPath = storageProvider.GetFileFullPath(item.Name);
|
|
isExists = storageProvider.IsFileExists(fileFullPath);
|
|
var filePath = storageProvider.FilePathResolver(fileFullPath);
|
|
filePath = Path.Combine("wwwroot", filePath);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Physical File Info ...
|
|
IFileInfo fileInfo = storageProvider.FileProvider.GetFileInfo(filePath);
|
|
|
|
//
|
|
// Prepare Default Streaming Requirements ...
|
|
var mimeType = "application/octetstream";
|
|
var readStream = fileInfo.CreateReadStream();
|
|
var fileMimeProvider = new FileExtensionContentTypeProvider();
|
|
var fileName = item.Name;
|
|
|
|
//
|
|
// Try to Find Physical File's Content Type ...
|
|
fileMimeProvider.TryGetContentType(
|
|
filePath,
|
|
out mimeType
|
|
);
|
|
|
|
//
|
|
// Prepare Result Model ...
|
|
var result = new XFileStreamDescriptorDto
|
|
{
|
|
Stream = readStream,
|
|
MIMEType = mimeType,
|
|
Name = fileName,
|
|
Path = fileFullPath
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XFileStreamDescriptorDto> GetFileDescriptor(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
var item = await FindOne(
|
|
includeBuilder: null,
|
|
predicate: e =>
|
|
e.Name.Contains(fileName) ||
|
|
e.Path.Contains(fileName) ||
|
|
e.Thumb.Contains(fileName) ||
|
|
e.FileName.Contains(fileName) ||
|
|
e.ThumbPath.Contains(fileName),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var isExists = !item.IsNullOrDefault();
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract File Name ...
|
|
fileName = Path.GetFileName(fileName);
|
|
|
|
//
|
|
// Check File is Thumbnail or File ...
|
|
var isThumb = fileName.StartsWith(storageProvider.Configuration.ThumbPrefix);
|
|
var isFile = fileName.StartsWith(storageProvider.Configuration.FilePrefix);
|
|
|
|
//
|
|
// Check File Type is Valid ...
|
|
isExists = isThumb || isFile;
|
|
if (!isExists)
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract File Full Path ...
|
|
var fileFullPath = "";
|
|
if (isThumb)
|
|
{
|
|
fileFullPath = storageProvider.GetThumbnailFileFullPath(fileName);
|
|
}
|
|
else
|
|
{
|
|
fileFullPath = storageProvider.GetFileFullPath(fileName);
|
|
}
|
|
|
|
//
|
|
// Check Physical File Exists or Not ...
|
|
isExists = storageProvider.IsFileExists(fileFullPath);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Generate Physical File Info ...
|
|
var filePath = storageProvider.FilePathResolver(fileFullPath);
|
|
filePath = Path.Combine("wwwroot", filePath);
|
|
IFileInfo fileInfo = storageProvider.FileProvider.GetFileInfo(filePath);
|
|
|
|
//
|
|
// Prepare Default Streaming Requirements ...
|
|
var mimeType = "application/octetstream";
|
|
var readStream = fileInfo.CreateReadStream();
|
|
var fileMimeProvider = new FileExtensionContentTypeProvider();
|
|
|
|
//
|
|
// Try to Find Physical File's Content Type ...
|
|
fileMimeProvider.TryGetContentType(filePath, out mimeType);
|
|
|
|
//
|
|
// Prepare Result Model ...
|
|
var result = new XFileStreamDescriptorDto
|
|
{
|
|
Stream = readStream,
|
|
MIMEType = mimeType,
|
|
Name = fileName,
|
|
Path = fileFullPath
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Reference Identifier for Specified Provider and Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <returns></returns>
|
|
public string GetIdentifier<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId
|
|
)
|
|
{
|
|
//
|
|
var result = $"{providedFor}_{forProvidedId}";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified Item has Refernce to Provider ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsProvidedFor<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!id.IsDefaultGuid() &&
|
|
!forProvidedId.IsNull() &&
|
|
!providedFor.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Exists ...
|
|
isValid = await IsExists(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var references = item.GetReferences();
|
|
var result =
|
|
references.IsNull() &&
|
|
references.HasChild() &&
|
|
references.Any(r =>
|
|
r.ProvidedFor == providedFor &&
|
|
r.ReferencedTo == $"{forProvidedId}"
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Specified Reference to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddReference<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
Guid id,
|
|
int forIndex = 0,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!providedFor.IsNullOrEmpty() &&
|
|
!id.IsNull() &&
|
|
!id.IsDefaultGuid() &&
|
|
!providedFor.IsNull() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Has Reference or not ...
|
|
isValid = await IsProvidedFor(
|
|
id: id,
|
|
providedFor: providedFor,
|
|
forProvidedId: forProvidedId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Prevent Moving Forward Since Reference Exists ...
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check Permissions ...
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var reference = new XReference<string>
|
|
{
|
|
Index = forIndex,
|
|
ProvidedFor = providedFor,
|
|
ReferencedTo = $"{forProvidedId}"
|
|
};
|
|
var references = item.GetReferences();
|
|
references.Add(reference);
|
|
item = item.UpdateReferences(references);
|
|
item = await Update(
|
|
id: id,
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Reference from Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveReference<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
Guid id,
|
|
int forIndex = 0,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!id.IsDefaultGuid() &&
|
|
!forProvidedId.IsNull() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
!providedFor.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Has Reference or not ...
|
|
isValid = await IsProvidedFor(
|
|
id: id,
|
|
providedFor: providedFor,
|
|
forProvidedId: forProvidedId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
//
|
|
// Prevent Moving Forward Since Reference not Exists ...
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check Permissions ...
|
|
var item = await Get(
|
|
id: id,
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetIdentifier(
|
|
providedFor: providedFor,
|
|
forProvidedId: forProvidedId
|
|
);
|
|
var references = item.GetReferences();
|
|
references = references
|
|
.Where(r =>
|
|
r.Index != forIndex &&
|
|
r.ProvidedFor != providedFor &&
|
|
r.ReferencedTo != $"{forProvidedId}"
|
|
)
|
|
.ToList();
|
|
item = item.UpdateReferences(references);
|
|
|
|
//
|
|
item = await Update(
|
|
item: item,
|
|
id: item.Id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified References ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XReference<string>>> GetReferences(
|
|
string providedFor,
|
|
Guid id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
IList<XReference<string>> result = new List<XReference<string>>();
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var isValid = !item.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = item.GetReferences();
|
|
|
|
//
|
|
result = result.Where(r =>
|
|
r.ProvidedFor == providedFor
|
|
)
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileTagProvided.cs
|
|
|
|
using System;
|
|
using xCommons.Extensions;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Interfaces.Dtos;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xFileService.Providers.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Providers;
|
|
|
|
namespace xFileService.Providers
|
|
{
|
|
public class XFileTagProvided : XBaseTagProvided<XFile, XFileDto, Guid, XFileDtoHub>, IXFileTagProvided
|
|
{
|
|
public XFileTagProvided(
|
|
IXFileTagProvider tagProvider,
|
|
IXFileServiceProvider provider
|
|
) : base(
|
|
provider: provider,
|
|
tagProvider: tagProvider,
|
|
permittedRoles: new string[] { "admin" }
|
|
)
|
|
{ }
|
|
|
|
public override bool IsOwned(
|
|
XFileDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!item.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
item.OwnerId == userInfo.UserId;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XFile item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!item.IsNullOrDefault() &&
|
|
!userInfo.IsNullOrDefault() &&
|
|
item.OwnerId == userInfo.UserId;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileTagProvider.cs
|
|
|
|
using System;
|
|
using xFileService.Constants;
|
|
using xFileService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Providers;
|
|
|
|
namespace xFileService.Providers
|
|
{
|
|
public class XFileTagProvider : XBaseTagProvider<Guid>, IXFileTagProvider
|
|
{
|
|
public XFileTagProvider(
|
|
IXTagServiceProvider tagProvider
|
|
) : base(
|
|
tagProvider: tagProvider,
|
|
providedFor: XFileServiceConstants.XFileTagProvided
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Configurations\XHttpServiceConfiguration.cs
|
|
|
|
namespace xHttpService.Configurations {
|
|
public partial class XHttpServiceConfiguration {
|
|
/// <summary>
|
|
/// Determines Http Handler Check SSL or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool DisableSSLCheck { get; set; }
|
|
public int DefaultClientTimeout { get; set; } = 360;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xHttpService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string HTTP_SERVICE_NODE_NAME = "HttpServiceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Constants\XHttpMethod.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xHttpService.Constants {
|
|
public enum XHttpMethod {
|
|
[StringValue ("GET")]
|
|
GET,
|
|
|
|
[StringValue ("POST")]
|
|
POST,
|
|
|
|
[StringValue ("PUT")]
|
|
PUT,
|
|
|
|
[StringValue ("DELETE")]
|
|
DELETE
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xHttpService.Configurations;
|
|
using xHttpService.Constants;
|
|
using xHttpService.Interfaces;
|
|
using xHttpService.Providers;
|
|
|
|
namespace xHttpService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XHttpService Configuration from AppSettings
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XHttpServiceConfiguration GetXHttpServiceConfiguration (this IConfiguration configuration) {
|
|
//
|
|
var xHttpSection = configuration.GetSection (ConfigurationNodeNames.HTTP_SERVICE_NODE_NAME);
|
|
return xHttpSection.Get<XHttpServiceConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XHttpService Configuration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXHttpServiceConfiguration (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
var httpServiceConfiguration = configuration.GetXHttpServiceConfiguration ();
|
|
services.AddXHttpServiceConfiguration(httpServiceConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XHttpService Configuration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXHttpServiceConfiguration (
|
|
this IServiceCollection services,
|
|
XHttpServiceConfiguration configuration
|
|
) {
|
|
//
|
|
if (configuration.IsNull ()) {
|
|
Console.WriteLine($"xHttpService: there is no provided configurations, using default ...");
|
|
configuration = new XHttpServiceConfiguration ();
|
|
}
|
|
|
|
//
|
|
services.AddSingleton<XHttpServiceConfiguration> (configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XHttpService on DI ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXHttpService (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Register Service Configuration ...
|
|
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
|
|
services.AddXHttpServiceConfiguration (configuration);
|
|
}
|
|
|
|
//
|
|
// Register Service ...
|
|
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XHttpService on DI ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXHttpService (
|
|
this IServiceCollection services,
|
|
XHttpServiceConfiguration configuration
|
|
) {
|
|
//
|
|
// Register Service Configuration ...
|
|
if (services.GetRegisteredService<XHttpServiceConfiguration> ().IsNull ()) {
|
|
services.AddXHttpServiceConfiguration (configuration);
|
|
}
|
|
|
|
//
|
|
// Register Service ...
|
|
services.AddSingleton<IXHttpProvider, XHttpProvider> ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Extensions\RestSharpExtensions.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
using AutoMapper.Mappers;
|
|
using RestSharp;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xModels.Dtos;
|
|
|
|
namespace xHttpService.Extensions
|
|
{
|
|
public static partial class RestSharpExtensions
|
|
{
|
|
/// <summary>
|
|
/// Attach an instance of XQuery to a RestRequest object
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="query"></param>
|
|
/// <returns></returns>
|
|
public static RestRequest AttachXQuery(
|
|
this RestRequest source,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
if (query.IsNull())
|
|
{
|
|
return source;
|
|
}
|
|
|
|
//
|
|
// ContainsDetail ...
|
|
//
|
|
var containsDetailKey = System.Uri.EscapeDataString(nameof(query.ContainsDetail));
|
|
var containsDetailValue = query.ContainsDetail.AsHttpParamString();
|
|
source.AddQueryParameter(containsDetailKey, containsDetailValue);
|
|
|
|
//
|
|
// IsAscending ...
|
|
var isAscendingKey = System.Uri.EscapeDataString(nameof(query.IsAscending));
|
|
var isAscendingValue = query.IsAscending.AsHttpParamString();
|
|
source.AddQueryParameter(isAscendingKey, isAscendingValue);
|
|
|
|
//
|
|
// Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var key = System.Uri.EscapeDataString(nameof(query.Filter));
|
|
var value = query.Filter.AsHttpParamString();
|
|
source.AddQueryParameter(key, value);
|
|
}
|
|
|
|
//
|
|
// SortBy ...
|
|
if (!query.SortBy.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var key = System.Uri.EscapeDataString(nameof(query.SortBy));
|
|
var value = query.SortBy.AsHttpParamString();
|
|
source.AddQueryParameter(key, value);
|
|
}
|
|
|
|
//
|
|
// Page ...
|
|
if (query.Page > 0)
|
|
{
|
|
//
|
|
var key = System.Uri.EscapeDataString(nameof(query.Page));
|
|
var value = query.Page.AsHttpParamString();
|
|
source.AddQueryParameter(key, value);
|
|
}
|
|
|
|
//
|
|
// PageSize ...
|
|
if (query.PageSize > 0)
|
|
{
|
|
//
|
|
var key = System.Uri.EscapeDataString(nameof(query.PageSize));
|
|
var value = query.PageSize.AsHttpParamString();
|
|
source.AddQueryParameter(key, value);
|
|
}
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Dest User to Query Strings ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="destUser"></param>
|
|
/// <returns></returns>
|
|
public static RestRequest AttachDestUser(
|
|
this RestRequest source,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
if (destUser.IsNullOrEmpty())
|
|
{
|
|
return source;
|
|
}
|
|
|
|
//
|
|
var destUserKey = System.Uri.EscapeDataString(nameof(destUser));
|
|
var destUserValue = destUser.AsHttpParamString();
|
|
source.AddQueryParameter(destUserKey, destUserValue);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add XPoweredBy Header to specific RestRequest Headers ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="poweredByValue"></param>
|
|
/// <returns></returns>
|
|
public static RestRequest AddXPoweredBy(
|
|
this RestRequest source,
|
|
string poweredByValue
|
|
)
|
|
{
|
|
//
|
|
source.AddHeader(
|
|
XAuthorization.XPoweredBy,
|
|
poweredByValue
|
|
);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add XAccessToken Header to specific RestRequest Headers ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="poweredByValue"></param>
|
|
/// <returns></returns>
|
|
public static RestRequest AddXAccessToken(
|
|
this RestRequest source,
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
token = $"{XAuthentication.BEARER} {token}";
|
|
|
|
//
|
|
source.AddHeader(
|
|
XAuthorization.Header,
|
|
token
|
|
);
|
|
|
|
//
|
|
return source;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Interfaces\IXHttpProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using RestSharp;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xHttpService.Interfaces {
|
|
public partial interface IXHttpProvider {
|
|
HttpClient GetHttpClient ();
|
|
RestClient GetRestClient (
|
|
string baseUrl = null,
|
|
string poweredByValue = null,
|
|
XTokenResponse tokens = null
|
|
);
|
|
RestRequest GetRestRequet (
|
|
string endpoint,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
);
|
|
Task<T> RunRestRequest<T> (
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xHttpService\Providers\XHttpProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using RestSharp;
|
|
using RestSharp.Authenticators;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Configurations;
|
|
using xHttpService.Constants;
|
|
using xHttpService.Interfaces;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xHttpService.Providers {
|
|
public partial class XHttpProvider : XBaseClass, IXHttpProvider {
|
|
|
|
private readonly XHttpServiceConfiguration configuration;
|
|
|
|
public XHttpProvider (
|
|
ILoggerFactory loggerFactory,
|
|
XHttpServiceConfiguration configuration
|
|
) : base (loggerFactory) {
|
|
this.configuration = configuration;
|
|
}
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Get an Instance of Http Client
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public HttpClient GetHttpClient () {
|
|
//
|
|
HttpClient httpClient = null;
|
|
httpClient = new HttpClient ();
|
|
|
|
//
|
|
if (configuration.DisableSSLCheck) {
|
|
//
|
|
var httpHandler = new HttpClientHandler ();
|
|
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
|
|
|
//
|
|
httpClient = new HttpClient (httpHandler);
|
|
}
|
|
|
|
//
|
|
// Set Timeout ...
|
|
httpClient.Timeout = TimeSpan
|
|
.FromSeconds (configuration.DefaultClientTimeout);
|
|
|
|
//
|
|
return httpClient;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestClient
|
|
/// </summary>
|
|
/// <param name="baseUrl"></param>
|
|
/// <param name="poweredByValue"></param>
|
|
/// <param name="tokens"></param>
|
|
/// <returns></returns>
|
|
public RestClient GetRestClient (
|
|
string baseUrl = null,
|
|
string poweredByValue = null,
|
|
XTokenResponse tokens = null
|
|
) {
|
|
//
|
|
var client = new RestClient (baseUrl);
|
|
|
|
//
|
|
// Add XPowered By to Default Headers ...
|
|
if (!poweredByValue.IsNullOrEmpty ()) {
|
|
client.AddDefaultHeader (XAuthorization.XPoweredBy, poweredByValue);
|
|
}
|
|
|
|
//
|
|
// Set Authenticator ...
|
|
if (!tokens.IsNull () &&
|
|
!tokens.AccessToken.IsNullOrEmpty ()) {
|
|
client.Authenticator = new JwtAuthenticator (tokens.AccessToken);
|
|
}
|
|
|
|
//
|
|
// Refresh Token ...
|
|
if (!tokens.IsNull () &&
|
|
!tokens.RefreshToken.IsNullOrEmpty ()) {
|
|
client.AddDefaultHeader (XAuthorization.RefreshToken, tokens.RefreshToken);
|
|
}
|
|
|
|
//
|
|
// ExpiresAt ...
|
|
if (!tokens.IsNull () &&
|
|
tokens.ExpiresAt > 0) {
|
|
client.AddDefaultHeader (XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString ());
|
|
}
|
|
|
|
//
|
|
// Set Default Timeout ...
|
|
client.Timeout = configuration.DefaultClientTimeout;
|
|
|
|
//
|
|
// SSL Validation Handler ...
|
|
if (configuration.DisableSSLCheck) {
|
|
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
|
|
}
|
|
|
|
//
|
|
return client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestRequest
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="params"></param>
|
|
/// <param name="headers"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
public RestRequest GetRestRequet (
|
|
string endpoint,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
) {
|
|
//
|
|
var url = endpoint.ToString ();
|
|
|
|
//
|
|
// Add Route Payloads ...
|
|
if (!@params.IsNull () && @params.Count > 0) {
|
|
//
|
|
var enumerator = @params.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url = url.Replace (item.Key, item.Value.ToUrlEncoded ());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add Query Strings ...
|
|
if (!queryStrings.IsNull () && queryStrings.Count > 0) {
|
|
//
|
|
url = $"{url}?";
|
|
var enumerator = queryStrings.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url += $"{item.Key}={item.Value.ToUrlEncoded ()}&";
|
|
}
|
|
|
|
//
|
|
// remove lates & ...
|
|
if (url.EndsWith ("&")) {
|
|
url = url.Substring (0, url.Length - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create request ...
|
|
var request = new RestRequest (url, DataFormat.Json);
|
|
|
|
//
|
|
// Add Headers to request ...
|
|
if (!headers.IsNull () && headers.Count > 0) {
|
|
//
|
|
var enumerator = headers.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
request.AddHeader (item.Key, item.Value);
|
|
}
|
|
}
|
|
|
|
//
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Call Specific Request and retrieve Response
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public async Task<T> RunRestRequest<T> (
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method
|
|
) {
|
|
//
|
|
var response = await Task.Run (() => {
|
|
//
|
|
IRestResponse resp = null;
|
|
|
|
//
|
|
// Call Endpoint Service using Specified Method ...
|
|
switch (method) {
|
|
//
|
|
// Get ...
|
|
case XHttpMethod.GET:
|
|
resp = client.Get (request);
|
|
break;
|
|
|
|
//
|
|
// Put ...
|
|
case XHttpMethod.PUT:
|
|
resp = client.Put (request);
|
|
break;
|
|
|
|
//
|
|
// Post ...
|
|
case XHttpMethod.POST:
|
|
resp = client.Post (request);
|
|
break;
|
|
|
|
//
|
|
// Delete ...
|
|
case XHttpMethod.DELETE:
|
|
resp = client.Delete (request);
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (!resp.IsSuccessful) {
|
|
//
|
|
// UnAuthorized ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
|
XException.NotAuthorized.Throw ();
|
|
}
|
|
|
|
//
|
|
// NotFound ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
|
|
XException.NotFound.Throw ();
|
|
}
|
|
|
|
//
|
|
// Timeout ...
|
|
if (!resp.ErrorMessage.IsNullOrEmpty () &&
|
|
resp.ErrorMessage.Contains ("timed out")) {
|
|
XException.Timeout.Throw ();
|
|
}
|
|
|
|
//
|
|
// ErrorMessage ...
|
|
if (!resp.ErrorMessage.IsNullOrEmpty ()) {
|
|
throw new Exception (resp.ErrorMessage);
|
|
}
|
|
|
|
//
|
|
// Default Exception ...
|
|
XException.BadRequest.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = resp.Content.FromJSON<T> ();
|
|
return result;
|
|
});
|
|
|
|
//
|
|
return response;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\Extensions\XIdentityHelperExtensions.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityHelper.Extensions
|
|
{
|
|
public static class XIdentityHelperExtensions
|
|
{
|
|
/// <summary>
|
|
/// Check User Claims ia Admin Role or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsAdmin(this XUserClaimsInfoDto source)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
if (source.IsNull() ||
|
|
source.Roles.IsNull() ||
|
|
!source.Roles.HasChild())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = source.Roles.Contains(XUserRoles.ADMIN);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Actor is Valid for UserSelectByParam or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="userSelectByParam"></param>
|
|
/// <returns></returns>
|
|
public static bool IsValidActor(this XUserClaimsInfoDto source, string userSelectByParam)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
if (source.IsNull() ||
|
|
userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isAdmin = source.IsAdmin();
|
|
result = isAdmin ||
|
|
userSelectByParam == source.Email ||
|
|
userSelectByParam == source.UserId ||
|
|
userSelectByParam == source.UserName ||
|
|
userSelectByParam == source.PhoneNumber;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\Extensions\XUserRoleExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xIdentityHelper.Extensions
|
|
{
|
|
public static class XUserRoleExtensions
|
|
{
|
|
/// <summary>
|
|
/// Converts an String to XUserRole ...
|
|
/// </summary>
|
|
/// <param name="role"></param>
|
|
/// <returns></returns>
|
|
public static XUserRole ToXUserRole(this string role)
|
|
{
|
|
//
|
|
var result = XUserRole.User;
|
|
|
|
//
|
|
// Validate ...
|
|
if (role.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var roles = new List<string>
|
|
{
|
|
role
|
|
};
|
|
result = roles.GetTopRole();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve User Top Role based on Role Lists ...
|
|
/// </summary>
|
|
/// <param name="roles"></param>
|
|
/// <returns></returns>
|
|
public static XUserRole GetTopRole(this IEnumerable<string> roles)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (roles.IsNull() || !roles.HasChild())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize Roles ...
|
|
roles = roles.Select(r => r.ToNormalString());
|
|
|
|
//
|
|
var result = XUserRole.User;
|
|
|
|
//
|
|
// Admin ...
|
|
if (roles.Contains(XUserRole.Admin.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.Admin;
|
|
}
|
|
//
|
|
// ResponsibleManager ...
|
|
else if (roles.Contains(XUserRole.ResponsibleManager.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.ResponsibleManager;
|
|
}
|
|
//
|
|
// Journalist ...
|
|
else if (roles.Contains(XUserRole.Journalist.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.Journalist;
|
|
}
|
|
//
|
|
// ChiefClerk ...
|
|
else if (roles.Contains(XUserRole.ChiefClerk.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.ChiefClerk;
|
|
}
|
|
//
|
|
// ChiefClerkAssistant ...
|
|
else if (roles.Contains(XUserRole.ChiefClerkAssistant.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.ChiefClerkAssistant;
|
|
}
|
|
//
|
|
// Actuary ...
|
|
else if (roles.Contains(XUserRole.Actuary.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.Actuary;
|
|
}
|
|
//
|
|
// ActuaryAssistant ...
|
|
else if (roles.Contains(XUserRole.ActuaryAssistant.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.ActuaryAssistant;
|
|
}
|
|
//
|
|
// Reporter ...
|
|
else if (roles.Contains(XUserRole.Reporter.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.Reporter;
|
|
}
|
|
//
|
|
// ReporterAssistant ...
|
|
else if (roles.Contains(XUserRole.ReporterAssistant.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.ReporterAssistant;
|
|
}
|
|
//
|
|
// Agent ...
|
|
else if (roles.Contains(XUserRole.Agent.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.Agent;
|
|
}
|
|
//
|
|
// User ...
|
|
else if (roles.Contains(XUserRole.User.GetStringValue().ToNormalString()))
|
|
{
|
|
result = XUserRole.User;
|
|
}
|
|
else
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User Roles has Specified Permissions or not ...
|
|
/// </summary>
|
|
/// <param name="roles"></param>
|
|
/// <param name="role"></param>
|
|
/// <returns></returns>
|
|
public static bool HasRolePermissions(this IEnumerable<string> roles, XUserRole role)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!roles.IsNull() &&
|
|
roles.HasChild();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var topRole = roles.GetTopRole();
|
|
|
|
//
|
|
result = (int)topRole >= (int)role;
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
public static bool HasRolePermissions(this IEnumerable<string> roles, string role)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!roles.IsNull() &&
|
|
roles.HasChild() &&
|
|
!role.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var roleEnum = role.ToXUserRole();
|
|
result = roles.HasRolePermissions(roleEnum);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\XApiScopeHelper.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityHelper {
|
|
public static class XApiScopeHelper {
|
|
public partial struct XApiScopes {
|
|
public const string Read = "XAPI.read";
|
|
public const string Write = "XAPI.write";
|
|
public const string Admin = "XAPI.admin";
|
|
public const string Manage = "manage";
|
|
}
|
|
|
|
public enum XApiScope {
|
|
[StringValue ("XAPI.read")]
|
|
Read,
|
|
|
|
[StringValue ("XAPI.write")]
|
|
Write,
|
|
|
|
[StringValue ("XAPI.admin")]
|
|
Admin,
|
|
|
|
[StringValue ("manage")]
|
|
Manage,
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\XAuthorizationHelper.cs
|
|
|
|
using System.Collections.Generic;
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using xCommons.Authorization;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using static xIdentityHelper.XApiScopeHelper;
|
|
|
|
namespace xIdentityHelper
|
|
{
|
|
public class XAuthorizationHelper
|
|
{
|
|
public static IDictionary<string, AuthorizationPolicy> GetXAuthorizationPolicies()
|
|
{
|
|
//
|
|
var result = new Dictionary<string, AuthorizationPolicy>();
|
|
|
|
//
|
|
RequiredRolesRequirement roleRequirements = null;
|
|
|
|
//
|
|
#region Build Policies ...
|
|
//
|
|
// Scope Policies ...
|
|
#region Scope Policies ...
|
|
//
|
|
// Read Scope ...
|
|
result.Add(XPolicies.ReadAccess,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireClaim(JwtClaimTypes.Scope, XApiScopes.Read)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Write Scope ...
|
|
result.Add(XPolicies.WriteAccess,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireClaim(
|
|
JwtClaimTypes.Scope,
|
|
XApiScopes.Read,
|
|
XApiScopes.Write
|
|
)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Admin Scope ...
|
|
result.Add(XPolicies.AdminAccess,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireClaim(
|
|
JwtClaimTypes.Scope,
|
|
XApiScopes.Read,
|
|
XApiScopes.Write,
|
|
XApiScopes.Admin
|
|
)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Manage Scope ...
|
|
result.Add(XPolicies.ManageAccess,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireClaim(
|
|
JwtClaimTypes.Scope,
|
|
XApiScopes.Read,
|
|
XApiScopes.Write,
|
|
XApiScopes.Admin,
|
|
XApiScopes.Manage
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Roles Policies ...
|
|
#region Roles Policies ...
|
|
//
|
|
// User ...
|
|
#region User Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.USER,
|
|
XUserRoles.AGENT,
|
|
XUserRoles.REPORTER_ASSISTANT,
|
|
XUserRoles.REPORTER,
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// User Policy ...
|
|
result.Add(XPolicies.User,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled User Policy ...
|
|
result.Add(XPolicies.EnabledUser,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Agent ...
|
|
#region Agent Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.AGENT,
|
|
XUserRoles.REPORTER_ASSISTANT,
|
|
XUserRoles.REPORTER,
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// Agent Policy ...
|
|
result.Add(XPolicies.Agent,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Agent Policy ...
|
|
result.Add(XPolicies.EnabledAgent,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// ReporterAssistant ...
|
|
#region Reporter Assistant Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.REPORTER_ASSISTANT,
|
|
XUserRoles.REPORTER,
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// ReporterAssistant ...
|
|
result.Add(XPolicies.ReporterAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled ReporterAssistant ...
|
|
result.Add(XPolicies.EnabledReporterAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Reporter ...
|
|
#region Reporter Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.REPORTER,
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// Reporter ...
|
|
result.Add(XPolicies.Reporter,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Reporter ...
|
|
result.Add(XPolicies.EnabledReporter,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// ActuaryAssistant ...
|
|
#region Actuary Assistant Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// ActuaryAssistant ...
|
|
result.Add(XPolicies.ActuaryAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled ActuaryAssistant ...
|
|
result.Add(XPolicies.EnabledActuaryAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Actuary ...
|
|
#region Actuary Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// Actuary ...
|
|
result.Add(XPolicies.Actuary,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Actuary ...
|
|
result.Add(XPolicies.EnabledActuary,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// ChiefClerkAssistant ...
|
|
#region Chief Clerk Assistant Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// ChiefClerkAssistant ...
|
|
result.Add(XPolicies.ChiefClerkAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled ChiefClerkAssistant ...
|
|
result.Add(XPolicies.EnabledChiefClerkAssistant,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// ChiefClerk ...
|
|
#region Chief Clerk Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// ChiefClerk ...
|
|
result.Add(XPolicies.ChiefClerk,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled ChiefClerk ...
|
|
result.Add(XPolicies.EnabledChiefClerk,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Journalist ...
|
|
#region Journalist Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// Journalist ...
|
|
result.Add(XPolicies.Journalist,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Journalist ...
|
|
result.Add(XPolicies.EnabledJournalist,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// ResponsibleManager ...
|
|
#region Responsible Manager Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// ResponsibleManager ...
|
|
result.Add(XPolicies.ResponsibleManager,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled ResponsibleManager ...
|
|
result.Add(XPolicies.EnabledResponsibleManager,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
// Admin ...
|
|
#region Admin Related Policies ...
|
|
//
|
|
roleRequirements = new RequiredRolesRequirement(
|
|
XUserRoles.ADMIN
|
|
);
|
|
|
|
//
|
|
// Admin Policy ...
|
|
result.Add(XPolicies.Admin,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Admin Policy ...
|
|
result.Add(XPolicies.EnabledAdmin,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(roleRequirements)
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
// Complex Policies ...
|
|
#region AdminOrAgent Related Policies ...
|
|
//
|
|
// Admin Or Agent Policy ...
|
|
result.Add(XPolicies.AdminOrAgent,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(new RequiredRolesRequirement(
|
|
XUserRoles.ADMIN,
|
|
XUserRoles.AGENT
|
|
))
|
|
.Build()
|
|
);
|
|
|
|
//
|
|
// Enabled Admin Or Agent Policy ...
|
|
result.Add(XPolicies.EnabledAdminOrAgent,
|
|
new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(new RequiredRolesRequirement(
|
|
XUserRoles.ADMIN,
|
|
XUserRoles.AGENT
|
|
))
|
|
.RequireClaim(
|
|
XCustomClaims.IsBanned,
|
|
false.ToString(),
|
|
false.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.RequireClaim(
|
|
XCustomClaims.IsEnabled,
|
|
true.ToString(),
|
|
true.ToString()
|
|
.ToNormalString()
|
|
)
|
|
.Build()
|
|
);
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\XPolicies.cs
|
|
|
|
namespace xIdentityHelper
|
|
{
|
|
public partial struct XPolicies
|
|
{
|
|
//
|
|
// Scopes ...
|
|
public const string ReadAccess = "readScopePolicy";
|
|
public const string WriteAccess = "writeScopePolicy";
|
|
public const string AdminAccess = "adminScopePolicy";
|
|
public const string ManageAccess = "manageScopePolicy";
|
|
//
|
|
// Admin ...
|
|
public const string Admin = "adminPolicy";
|
|
public const string EnabledAdmin = "enabledAdminPolicy";
|
|
//
|
|
// Responsible Manager ...
|
|
public const string ResponsibleManager = "responsibleManagerPolicy";
|
|
public const string EnabledResponsibleManager = "enabledResponsibleManagerPolicy";
|
|
//
|
|
// Journalist ...
|
|
public const string Journalist = "journalistPolicy";
|
|
public const string EnabledJournalist = "enabledJournalistPolicy";
|
|
//
|
|
// Chief Clerk ...
|
|
public const string ChiefClerk = "chiefClerkPolicy";
|
|
public const string EnabledChiefClerk = "enabledChiefClerkPolicy";
|
|
//
|
|
// Chief Clerk Assistant ...
|
|
public const string ChiefClerkAssistant = "chiefClerkAssistantPolicy";
|
|
public const string EnabledChiefClerkAssistant = "enabledChiefClerkAssistantPolicy";
|
|
//
|
|
// Actuary ...
|
|
public const string Actuary = "actuaryPolicy";
|
|
public const string EnabledActuary = "enabledActuaryPolicy";
|
|
//
|
|
// Actuary Assistant ...
|
|
public const string ActuaryAssistant = "actuaryAssistantPolicy";
|
|
public const string EnabledActuaryAssistant = "enabledActuaryAssistantPolicy";
|
|
//
|
|
// Reporter ...
|
|
public const string Reporter = "reporterPolicy";
|
|
public const string EnabledReporter = "enabledReporterPolicy";
|
|
//
|
|
// Reporter Assistant ...
|
|
public const string ReporterAssistant = "reporterAssistantPolicy";
|
|
public const string EnabledReporterAssistant = "enabledReporterAssistantPolicy";
|
|
//
|
|
// Agent ...
|
|
public const string Agent = "agentPolicy";
|
|
public const string EnabledAgent = "enabledAgentPolicy";
|
|
//
|
|
// User ...
|
|
public const string User = "userPolicy";
|
|
public const string EnabledUser = "enabledUserPolicy";
|
|
//
|
|
// Complex Policies ...
|
|
public const string AdminOrAgent = "adminOrAgentPolicy";
|
|
public const string EnabledAdminOrAgent = "enabledAdminOrAgentPolicy";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityHelper\XUserRoles.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityHelper
|
|
{
|
|
public partial struct XUserRoles
|
|
{
|
|
/// <summary>
|
|
/// Must Top Role of System ...
|
|
/// </summary>
|
|
public const string ADMIN = "admin";
|
|
|
|
/// <summary>
|
|
/// مدیر مسئول
|
|
/// </summary>
|
|
public const string RESPONSIBLE_MANAGER = "responsible_manager";
|
|
|
|
/// <summary>
|
|
/// روزنامه نگار
|
|
/// </summary>
|
|
public const string JOURNALIST = "journalist";
|
|
|
|
/// <summary>
|
|
/// سر دبیر
|
|
/// </summary>
|
|
public const string CHIEF_CLERK = "chief_clerk";
|
|
|
|
/// <summary>
|
|
/// دستیار سرد بیر
|
|
/// </summary>
|
|
public const string CHIEF_CLERK_ASSISTANT = "chief_clerk_assistant";
|
|
|
|
/// <summary>
|
|
/// دبیر
|
|
/// </summary>
|
|
public const string ACTUARY = "actuary";
|
|
|
|
/// <summary>
|
|
/// دستیار دبیر
|
|
/// </summary>
|
|
public const string ACTUARY_ASSISTANT = "actuary_assistant";
|
|
|
|
/// <summary>
|
|
/// خبرنگار
|
|
/// </summary>
|
|
public const string REPORTER = "reporter";
|
|
|
|
/// <summary>
|
|
/// دستیار خبرنگار
|
|
/// </summary>
|
|
public const string REPORTER_ASSISTANT = "reporter_assistant";
|
|
|
|
/// <summary>
|
|
/// دستیار
|
|
/// </summary>
|
|
public const string AGENT = "agent";
|
|
|
|
/// <summary>
|
|
/// کاربر
|
|
/// </summary>
|
|
public const string USER = "user";
|
|
}
|
|
|
|
public enum XUserRole
|
|
{
|
|
/// <summary>
|
|
/// Must Top Role of System ...
|
|
/// </summary>
|
|
[StringValue("admin")]
|
|
Admin = 10,
|
|
|
|
/// <summary>
|
|
/// مدیر مسئول
|
|
/// </summary>
|
|
[StringValue("responsible_manager")]
|
|
ResponsibleManager = 9,
|
|
|
|
/// <summary>
|
|
/// روزنامه نگار
|
|
/// </summary>
|
|
[StringValue("journalist")]
|
|
Journalist = 8,
|
|
|
|
/// <summary>
|
|
/// سر دبیر
|
|
/// </summary>
|
|
[StringValue("chief_clerk")]
|
|
ChiefClerk = 7,
|
|
|
|
/// <summary>
|
|
/// دستیار سرد بیر
|
|
/// </summary>
|
|
[StringValue("chief_clerk_assistant")]
|
|
ChiefClerkAssistant = 6,
|
|
|
|
/// <summary>
|
|
/// دبیر
|
|
/// </summary>
|
|
[StringValue("actuary")]
|
|
Actuary = 5,
|
|
|
|
/// <summary>
|
|
/// دستیار دبیر
|
|
/// </summary>
|
|
[StringValue("actuary_assistant")]
|
|
ActuaryAssistant = 4,
|
|
|
|
/// <summary>
|
|
/// خبرنگار
|
|
/// </summary>
|
|
[StringValue("reporter")]
|
|
Reporter = 3,
|
|
|
|
/// <summary>
|
|
/// دستیار خبرنگار
|
|
/// </summary>
|
|
[StringValue("reporter_assistant")]
|
|
ReporterAssistant = 2,
|
|
|
|
/// <summary>
|
|
/// دستیار
|
|
/// </summary>
|
|
[StringValue("agent")]
|
|
Agent = 1,
|
|
|
|
/// <summary>
|
|
/// کاربر
|
|
/// </summary>
|
|
[StringValue("user")]
|
|
User = 0
|
|
}
|
|
|
|
public static class XUserRoleHelper
|
|
{
|
|
public static List<string> GetAllRoles()
|
|
{
|
|
//
|
|
var result = new List<string>
|
|
{
|
|
XUserRoles.ADMIN,
|
|
XUserRoles.RESPONSIBLE_MANAGER,
|
|
XUserRoles.JOURNALIST,
|
|
XUserRoles.CHIEF_CLERK,
|
|
XUserRoles.CHIEF_CLERK_ASSISTANT,
|
|
XUserRoles.ACTUARY,
|
|
XUserRoles.ACTUARY_ASSISTANT,
|
|
XUserRoles.REPORTER,
|
|
XUserRoles.REPORTER_ASSISTANT,
|
|
XUserRoles.AGENT,
|
|
XUserRoles.USER
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
public class XIdentityConfiguration {
|
|
//
|
|
// Define All Policies which can Apply to Identity Framework
|
|
// and also create a Default instance if it's not Exists
|
|
// in AppSetting JSON file ...
|
|
public XIdentityPolicy Policy { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Security Key which used to Signing JWT Tokens
|
|
/// in Authentication Provider
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IdentitySecretKey { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Issuer and Creator of Token
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IdentityIssuer { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Audience and Consumer of Token
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IdentityAudience { get; set; }
|
|
|
|
/// <summary>
|
|
/// the List of Users Roles which must Provides in Identity
|
|
/// </summary>
|
|
/// <value></value>
|
|
public HashSet<string> IdentityRoles { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines All new users must Assign to which role in Registration
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string NewUsersRole { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines New Registered Users Confirm Email or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool AutoConfirmNewUsersEmail { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines New Registered Users Confirm PhoneNumber or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool AutoConfirmNewUsersPhoneNumber { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines the Registration only Can be done with Invitation or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RegistrationJustWithInvite { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines the Registration required confirmation with email or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireRegistrationConfirm { get; set; }
|
|
|
|
//
|
|
public int MaxNumberOfVerificationCodeSend { get; set; }
|
|
|
|
//
|
|
public int DeleyBetweenTwoVerificationCode { get; set; }
|
|
|
|
public int BannedDeviceTimeout { get; set; }
|
|
|
|
/// <summary>
|
|
/// an string Which Provide how long a action token can be valid
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string ActionTokenExpirationDateProvider { get; set; }
|
|
|
|
public HashSet<XIdentityMessageDto> IdentityMessages { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicy.cs
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// Provide the Available Policies with their Default Values
|
|
/// </summary>
|
|
public class XIdentityPolicy {
|
|
/// <summary>
|
|
/// User Account Lock Policies
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XIdentityPolicyLockout Lockout { get; set; }
|
|
|
|
/// <summary>
|
|
/// User Password Policies
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XIdentityPolicyPassword Password { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Policies for User for Allowing to SignIn
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XIdentityPolicySignIn SignIn { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Policies for User
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XIdentityPolicyUser User { get; set; }
|
|
|
|
/// <summary>
|
|
/// the policies which determines how to
|
|
/// populate user profile
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XIdentityProfile Profile { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyLockout.cs
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// User Account Lock Policies
|
|
/// </summary>
|
|
public class XIdentityPolicyLockout {
|
|
/// <summary>
|
|
/// The String which Provide Time Span Delais
|
|
/// between Lockout and UnLock a User Account
|
|
/// this Provided String the Parsed before Use
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string LockoutTimeSpanProvider { get; set; }
|
|
|
|
/// <summary>
|
|
/// the Number of InvalidLoginAttemps which can
|
|
/// Happens to Lockout User Account
|
|
/// </summary>
|
|
/// <value></value>
|
|
public byte MaxFailedAccessAttempts { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines Lockout mechanism allowed for new Users or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool AllowedForNewUsers { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyPassword.cs
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// User Password Policies
|
|
/// </summary>
|
|
public class XIdentityPolicyPassword {
|
|
/// <summary>
|
|
/// determines Password must contains digits or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireDigit { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines the minimum allowed length for a password
|
|
/// </summary>
|
|
/// <value></value>
|
|
public byte RequiredLength { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines the number of Unique Chars must be included in a Password
|
|
/// </summary>
|
|
/// <value></value>
|
|
public byte RequiredUniqueChars { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines Password must contains LowerCase chars or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireLowercase { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines Password must contains Non-Alphabetical chars or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireNonAlphanumeric { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines Password must contains UpperCase chars or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireUppercase { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicySignIn.cs
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// the Policies for User for Allowing to SignIn
|
|
/// </summary>
|
|
public class XIdentityPolicySignIn {
|
|
/// <summary>
|
|
/// determines only enabled users can SignIn
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequiredEnabled { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines User must Confirm the given Email Address
|
|
/// before Login or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireConfirmedEmail { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines User must Confirm the given Phone Number
|
|
/// before Login or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireConfirmedPhoneNumber { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyUser.cs
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// the Policies for User
|
|
/// </summary>
|
|
public class XIdentityPolicyUser {
|
|
/// <summary>
|
|
/// determines Allowed characters which can used in UserName
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string AllowedUserNameCharacters { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines the Email Address of each User must be Unique or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool RequireUniqueEmail { get; set; }
|
|
|
|
/// <summary>
|
|
/// minimum length of User Name
|
|
/// </summary>
|
|
/// <value></value>
|
|
public byte MinLength { get; set; }
|
|
|
|
/// <summary>
|
|
/// maximum length of user name
|
|
/// </summary>
|
|
/// <value></value>
|
|
public byte MaxLength { get; set; }
|
|
|
|
/// <summary>
|
|
/// Minimum Age for Registration
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MinAgeForRegistration { get; set; }
|
|
|
|
/// <summary>
|
|
/// Maximum age for Registration
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MaxAgeForRegistration { get; set; }
|
|
|
|
/// <summary>
|
|
/// a collection of invalid usernames
|
|
/// </summary>
|
|
/// <value></value>
|
|
public ICollection<string> InvalidUserNames { get; set; } = new HashSet<string> ();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityProfile.cs
|
|
|
|
namespace xIdentityModels.Configurations {
|
|
/// <summary>
|
|
/// contains user profile configuration
|
|
/// </summary>
|
|
public class XIdentityProfile {
|
|
/// <summary>
|
|
/// determines user profile contain email or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool ContainsEmail { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines user profile contains phone number or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool ContainsPhoneNumber { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines user profile contains Roles collection or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool ContainsRoles { get; set; }
|
|
|
|
public bool ContainsDateOfBirth { get; set; }
|
|
|
|
public bool ContainsLastLogin { get; set; }
|
|
|
|
public bool ContainsCreationDate { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XAction.cs
|
|
|
|
namespace xIdentityModels.Constants {
|
|
public enum XAction {
|
|
Authentication,
|
|
Invite,
|
|
Registration,
|
|
RequestMobileVerificationCode,
|
|
ConfirmMobileNumber,
|
|
RequestEmailVerificationCode,
|
|
ConfirmEmailAddress,
|
|
AddAccountInfo,
|
|
AttachProfileImage,
|
|
RequestResetPassword,
|
|
ProfileAction,
|
|
Finish,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XFriendshipState.cs
|
|
|
|
namespace xIdentityModels.Constants {
|
|
/// <summary>
|
|
/// Represent State of Friendship between to Users
|
|
/// </summary>
|
|
public enum XFriendshipState {
|
|
None,
|
|
Pending,
|
|
Accepted,
|
|
Rejected,
|
|
Blocked,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XGender.cs
|
|
|
|
namespace xIdentityModels.Constants {
|
|
/// <summary>
|
|
/// Determines Available Genders
|
|
/// </summary>
|
|
public enum XGender {
|
|
Male,
|
|
Female
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\xIdentityModelsConstants.cs
|
|
|
|
namespace xIdentityModels.Constants {
|
|
public class xIdentityModelsConstants { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XUserSelectBy.cs
|
|
|
|
namespace xIdentityModels.Constants {
|
|
public enum XUserSelectBy {
|
|
NotSpecified,
|
|
ID,
|
|
Username,
|
|
Email,
|
|
MobileNumber
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Descriptors\XIdentityUserDescriptor.cs
|
|
|
|
namespace xIdentityModels.Descriptors {
|
|
/// <summary>
|
|
/// contains default users information
|
|
/// </summary>
|
|
public class XIdentityUserDescriptor {
|
|
public string Id { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public string UserName { get; set; }
|
|
public string Email { get; set; }
|
|
public bool EmailConfirmed { get; set; }
|
|
public string PhoneNumber { get; set; }
|
|
public bool PhoneNumberConfirmed { get; set; }
|
|
public string Password { get; set; }
|
|
public string Role { get; set; }
|
|
public bool IsEnable { get; set; }
|
|
public bool IsBanned { get; set; }
|
|
public string DateOfBirth { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\DI\XDIHelperExtension.cs
|
|
|
|
namespace xIdentityModels.DI {
|
|
public static partial class XDIHelperExtension { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XDiscoveryDocumentDto.cs
|
|
|
|
using System.Collections.Generic;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace xIdentityModels.Dtos
|
|
{
|
|
public class XDiscoveryDocumentDto
|
|
{
|
|
[JsonProperty ("issuer")]
|
|
public string Issuer { get; set; }
|
|
|
|
[JsonProperty ("jwks_uri")]
|
|
public string JwksUri { get; set; }
|
|
|
|
[JsonProperty ("authorization_endpoint")]
|
|
public string AuthorizationEndpoint { get; set; }
|
|
|
|
[JsonProperty ("token_endpoint")]
|
|
public string TokenEndpoint { get; set; }
|
|
|
|
[JsonProperty ("userinfo_endpoint")]
|
|
public string UserinfoEndpoint { get; set; }
|
|
|
|
[JsonProperty ("end_session_endpoint")]
|
|
public string EndSessionEndpoint { get; set; }
|
|
|
|
[JsonProperty ("check_session_iframe")]
|
|
public string CheckSessionIframe { get; set; }
|
|
|
|
[JsonProperty ("revocation_endpoint")]
|
|
public string RevocationEndpoint { get; set; }
|
|
|
|
[JsonProperty ("introspection_endpoint")]
|
|
public string IntrospectionEndpoint { get; set; }
|
|
|
|
[JsonProperty ("device_authorization_endpoint")]
|
|
public string DeviceAuthorizationEndpoint { get; set; }
|
|
|
|
[JsonProperty ("frontchannel_logout_supported")]
|
|
public bool FrontchannelLogoutSupported { get; set; }
|
|
|
|
[JsonProperty ("frontchannel_logout_session_supported")]
|
|
public bool FrontchannelLogoutSessionSupported { get; set; }
|
|
|
|
[JsonProperty ("backchannel_logout_supported")]
|
|
public bool BackchannelLogoutSupported { get; set; }
|
|
|
|
[JsonProperty ("backchannel_logout_session_supported")]
|
|
public bool BackchannelLogoutSessionSupported { get; set; }
|
|
|
|
[JsonProperty ("scopes_supported")]
|
|
public List<string> ScopesSupported { get; set; }
|
|
|
|
[JsonProperty ("claims_supported")]
|
|
public List<string> ClaimsSupported { get; set; }
|
|
|
|
[JsonProperty ("grant_types_supported")]
|
|
public List<string> GrantTypesSupported { get; set; }
|
|
|
|
[JsonProperty ("response_types_supported")]
|
|
public List<string> ResponseTypesSupported { get; set; }
|
|
|
|
[JsonProperty ("response_modes_supported")]
|
|
public List<string> ResponseModesSupported { get; set; }
|
|
|
|
[JsonProperty ("token_endpoint_auth_methods_supported")]
|
|
public List<string> TokenEndpointAuthMethodsSupported { get; set; }
|
|
|
|
[JsonProperty ("id_token_signing_alg_values_supported")]
|
|
public List<string> IdTokenSigningAlgValuesSupported { get; set; }
|
|
|
|
[JsonProperty ("subject_types_supported")]
|
|
public List<string> SubjectTypesSupported { get; set; }
|
|
|
|
[JsonProperty ("code_challenge_methods_supported")]
|
|
public List<string> CodeChallengeMethodsSupported { get; set; }
|
|
|
|
[JsonProperty ("request_parameter_supported")]
|
|
public bool RequestParameterSupported { get; set; }
|
|
|
|
[JsonProperty ("account_api")]
|
|
public string AccountApi { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XFriendDto.cs
|
|
|
|
using xIdentityModels.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos
|
|
{
|
|
/// <summary>
|
|
/// All Available Friendship Types ...
|
|
/// </summary>
|
|
public enum XFriendshipType
|
|
{
|
|
Follower = 0,
|
|
Following = 1,
|
|
}
|
|
|
|
/// <summary>
|
|
/// a DTO Class Which Represent a User Friends ...
|
|
/// </summary>
|
|
public class XFriendDto : XBaseDto
|
|
{
|
|
public string Avatar { get; set; }
|
|
public string UserId { get; set; }
|
|
public string Username { get; set; }
|
|
public string Lastname { get; set; }
|
|
public string Firstname { get; set; }
|
|
public XFriendshipType Type { get; set; }
|
|
public XFriendshipState State { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XFriendshipInfoDto.cs
|
|
|
|
using xModels.Base;
|
|
using xIdentityModels.Constants;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XFriendshipInfoDto : XBaseDto {
|
|
public string UserId { get; set; }
|
|
public bool IsFollower { get; set; }
|
|
public bool IsFollowing { get; set; }
|
|
public XFriendshipState FollowerState { get; set; }
|
|
public XFriendshipState FollowingState { get; set; }
|
|
public long Followers { get; set; }
|
|
public long Followings { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XIdentityMessageDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XIdentityMessageDto : XBaseDto {
|
|
public string Language { get; set; }
|
|
public string ResourceTitle { get; set; }
|
|
public string TranslatedValue { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XOpenActionDto.cs
|
|
|
|
using System;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityModels.Dtos
|
|
{
|
|
/// <summary>
|
|
/// a List of Available Open Actions ...
|
|
/// </summary>
|
|
public struct XOpenActions
|
|
{
|
|
public const string HandShake = "HandShake";
|
|
public const string GetUserInfo = "GetUserInfo";
|
|
public const string GetUserInfos = "GetUserInfos";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open Actions Request Model ...
|
|
/// </summary>
|
|
public class XOpenActionRequestDto : XBaseDto
|
|
{
|
|
//
|
|
public string Action { get; set; }
|
|
public string Payload { get; set; }
|
|
public string Checksum { get; set; }
|
|
public XDeviceDto Device { get; set; }
|
|
public string Timestamp { get; set; }
|
|
|
|
/// <summary>
|
|
/// Validate Model ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Validate()
|
|
{
|
|
//
|
|
var result =
|
|
!Device.IsNull() &&
|
|
!Timestamp.IsNull() &&
|
|
!Action.IsNullOrEmpty() &&
|
|
(Action == XOpenActions.HandShake ||
|
|
Action == XOpenActions.GetUserInfo ||
|
|
Action == XOpenActions.GetUserInfos) &&
|
|
!Int64.Parse(Timestamp).FromTimestamp().IsExPired();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checksum Digest Model ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string ToOpenActionToken()
|
|
{
|
|
//
|
|
var result = string.Empty;
|
|
if (!Validate())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var tmp = this;
|
|
tmp.Checksum = string.Empty;
|
|
|
|
//
|
|
result = $"{tmp.ToJSON()}"
|
|
.ToMd5String();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token is Correspond to Model or not ...
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public bool ValidateToken(string token)
|
|
{
|
|
//
|
|
var result =
|
|
Validate() &&
|
|
!token.IsNullOrEmpty() &&
|
|
token == ToOpenActionToken();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// aa Dto which used between Api's ...
|
|
/// </summary>
|
|
public class XOpenActionInnerDto : XBaseDto
|
|
{
|
|
public string Token { get; set; }
|
|
public string Payload { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// User Info Providing in Open Actions ...
|
|
/// </summary>
|
|
public class XOpenActionUserInfoDto : XBaseDto
|
|
{
|
|
public string Username { get; set; }
|
|
public string Firstname { get; set; }
|
|
public string Lastname { get; set; }
|
|
public string Avatar { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XProfileImageDto.cs
|
|
|
|
using System;
|
|
using Newtonsoft.Json;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XProfileImageDto : XBaseDto {
|
|
public int Id { get; set; }
|
|
|
|
[JsonProperty (
|
|
"name",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Name { get; set; }
|
|
|
|
[JsonProperty (
|
|
"thumb",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Thumb { get; set; }
|
|
|
|
[JsonProperty (
|
|
"path",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Path { get; set; }
|
|
|
|
[JsonProperty (
|
|
"thumbPath",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string ThumbPath { get; set; }
|
|
|
|
[JsonProperty (
|
|
"creationDate",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public DateTime CreationDate { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserNameIdRequest.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XUserNameIdRequest : XBaseDto {
|
|
public IEnumerable<string> Ids { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserNameIdResponse.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XUserNameIdResponse : XBaseDto {
|
|
public string Id { get; set; }
|
|
public string UserName { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserProfileDto.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Newtonsoft.Json;
|
|
using xIdentityModels.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Dtos {
|
|
public class XUserProfileDto : XBaseDto {
|
|
[JsonProperty (
|
|
"userId",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string UserId { get; set; }
|
|
|
|
[JsonProperty (
|
|
"userName",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string UserName { get; set; }
|
|
|
|
[JsonProperty (
|
|
"email",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Email { get; set; }
|
|
|
|
[JsonProperty (
|
|
"emailConfirmed",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public bool EmailConfirmed { get; set; }
|
|
|
|
[JsonProperty (
|
|
"phoneNumber",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string PhoneNumber { get; set; }
|
|
|
|
[JsonProperty (
|
|
"phoneNumberConfirmed",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public bool PhoneNumberConfirmed { get; set; }
|
|
|
|
[JsonProperty (
|
|
"firstName",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string FirstName { get; set; }
|
|
|
|
[JsonProperty (
|
|
"lastName",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string LastName { get; set; }
|
|
|
|
[JsonProperty (
|
|
"dateOfBirth",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public DateTime? DateOfBirth { get; set; }
|
|
|
|
[JsonProperty (
|
|
"creationDate",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public DateTime? CreationDate { get; set; }
|
|
|
|
[JsonProperty (
|
|
"lastLogin",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public DateTime? LastLogin { get; set; }
|
|
|
|
[JsonProperty (
|
|
"avatar",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Avatar { get; set; }
|
|
|
|
[JsonProperty (
|
|
"gender",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public XGender Gender { get; set; }
|
|
|
|
[JsonProperty (
|
|
"bio",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Bio { get; set; }
|
|
|
|
[JsonProperty (
|
|
"coverImage",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string CoverImage { get; set; }
|
|
|
|
[JsonProperty (
|
|
"openToSearch",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public bool OpenToSearch { get; set; }
|
|
|
|
[JsonProperty (
|
|
"friendshipInfo",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public XFriendshipInfoDto FriendshipInfo { get; set; }
|
|
|
|
[JsonProperty (
|
|
"roles",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public ICollection<string> Roles { get; set; } = new HashSet<string> ();
|
|
|
|
[JsonProperty (
|
|
"avatars",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public ICollection<XProfileImageDto> Avatars { get; set; } = new HashSet<XProfileImageDto> ();
|
|
|
|
[JsonProperty (
|
|
"isEnable",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public bool IsEnable { get; set; }
|
|
|
|
[JsonProperty (
|
|
"isBanned",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public bool IsBanned { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\DIExtensions.cs
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Interfaces;
|
|
using xIdentityModels.Providers;
|
|
|
|
namespace xIdentityModels.Extensions {
|
|
public static class DIExtensions {
|
|
/// <summary>
|
|
/// since registering IXUserRoleHelper need to add default instance if
|
|
/// user not provided we create this helper ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
public static void AddXUserRoleHandler (
|
|
this IServiceCollection services,
|
|
IXUserRoleHelper helper = null
|
|
) {
|
|
//
|
|
// Check if Provider is null ...
|
|
if (helper.IsNull ()) {
|
|
helper = services.GetRegisteredService<IXUserRoleHelper> ();
|
|
}
|
|
|
|
//
|
|
// check if Provider registered or not ...
|
|
if (helper.IsNull ()) {
|
|
//
|
|
// Create Default provider ...
|
|
services.AddSingleton<IXUserRoleHelper> (new XDefaultUserRoleHelper ());
|
|
} else {
|
|
//
|
|
// Register Given Helper ...
|
|
services.AddSingleton<IXUserRoleHelper> (helper);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XIdentityExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels.Extensions {
|
|
public static class XIdentityExtensions {
|
|
public static XUserSelectBy GetUserSelectByType (
|
|
this string source,
|
|
bool forceUserSelectByParamNotEmpty = true,
|
|
bool forceUserSelectByTypeMustSpecified = false
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNullOrEmpty () &&
|
|
forceUserSelectByParamNotEmpty) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = XUserSelectBy.NotSpecified;
|
|
var userSelectByParam = source.ToNormalString ();
|
|
if (userSelectByParam.IsValidEmail ()) {
|
|
//
|
|
// Find User by Email ...
|
|
result = XUserSelectBy.Email;
|
|
} else if (userSelectByParam.IsValidMobileNumber ()) {
|
|
//
|
|
// Find User by Mobile Number ...
|
|
result = XUserSelectBy.MobileNumber;
|
|
} else if (userSelectByParam.IsGuid ()) {
|
|
//
|
|
// Find User By it's ID ...
|
|
result = XUserSelectBy.ID;
|
|
} else {
|
|
//
|
|
// UserName ...
|
|
result = XUserSelectBy.Username;
|
|
}
|
|
|
|
//
|
|
// Validation Result ...
|
|
if (forceUserSelectByTypeMustSpecified &&
|
|
result == XUserSelectBy.NotSpecified) {
|
|
XException.InvalidData.Throw ();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static string GetUserSelectByParam (
|
|
this XActionRequest source,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var id = source.UserId;
|
|
var userName = source.UserName;
|
|
var email = source.Email;
|
|
var phoneNumber = source.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null) {
|
|
//
|
|
if (excludes.Contains (XUserSelectBy.ID)) {
|
|
id = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.Email)) {
|
|
email = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.MobileNumber)) {
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.Username)) {
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
//
|
|
var selectByParam =
|
|
id.IsNullOrEmpty () ?
|
|
userName.IsNullOrEmpty () ?
|
|
email.IsNullOrEmpty () ?
|
|
phoneNumber.IsNullOrEmpty () ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty ()) {
|
|
XException.InvalidData.Throw ();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\xIdentityModelsExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Configurations;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels.Extensions
|
|
{
|
|
public static class xIdentityModelsExtensions
|
|
{
|
|
/// <summary>
|
|
/// Converts a User Entity to Profile Dto ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="isAdmin"></param>
|
|
/// <param name="isSameUser"></param>
|
|
/// <param name="roles"></param>
|
|
/// <param name="friendship"></param>
|
|
/// <param name="profileConfig"></param>
|
|
/// <returns></returns>
|
|
public static XUserProfileDto ToXProfileDto(
|
|
this XUser source,
|
|
bool isAdmin = false,
|
|
bool isSameUser = false,
|
|
IEnumerable<string> roles = null,
|
|
XFriendshipInfoDto friendship = null,
|
|
XIdentityProfile profileConfig = null
|
|
)
|
|
{
|
|
//
|
|
XUserProfileDto result = null;
|
|
|
|
//
|
|
if (roles == null)
|
|
{
|
|
roles = new List<string>();
|
|
}
|
|
|
|
//
|
|
// Prepare Dto ...
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = new XUserProfileDto
|
|
{
|
|
Bio = source.Bio,
|
|
UserId = source.Id,
|
|
Email = source.Email,
|
|
Roles = roles.ToList(),
|
|
Avatar = source.Avatar,
|
|
IsEnable = source.IsEnable,
|
|
IsBanned = source.IsBanned,
|
|
UserName = source.UserName,
|
|
LastName = source.LastName,
|
|
FriendshipInfo = friendship,
|
|
FirstName = source.FirstName,
|
|
LastLogin = source.LastLogin,
|
|
CoverImage = source.CoverImage,
|
|
PhoneNumber = source.PhoneNumber,
|
|
DateOfBirth = source.DateOfBirth,
|
|
CreationDate = source.CreationDate,
|
|
OpenToSearch = source.OpenToSearch,
|
|
Gender = (XGender)(int)source.Gender,
|
|
EmailConfirmed = source.EmailConfirmed,
|
|
PhoneNumberConfirmed = source.PhoneNumberConfirmed,
|
|
Avatars = source.Avatars.Select(pfi =>
|
|
{
|
|
//
|
|
return new XProfileImageDto
|
|
{
|
|
Id = pfi.Id,
|
|
Name = pfi.Name,
|
|
Path = pfi.Path,
|
|
Thumb = pfi.Thumb,
|
|
ThumbPath = pfi.ThumbPath,
|
|
CreationDate = pfi.CreationDate
|
|
};
|
|
}).ToList(),
|
|
};
|
|
}
|
|
|
|
//
|
|
// Apply Profiling Configuration ...
|
|
|
|
//
|
|
bool isPassed = false;
|
|
|
|
//
|
|
// Handle Friendship ...
|
|
isPassed = !isSameUser;
|
|
if (!isPassed)
|
|
{
|
|
result.FriendshipInfo = null;
|
|
}
|
|
|
|
//
|
|
// Handle Email Info ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsEmail);
|
|
if (!isPassed)
|
|
{
|
|
result.Email = string.Empty;
|
|
result.EmailConfirmed = false;
|
|
}
|
|
|
|
//
|
|
// Handle PhoneNumber Info ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsPhoneNumber);
|
|
if (!isPassed)
|
|
{
|
|
source.PhoneNumber = string.Empty;
|
|
source.PhoneNumberConfirmed = false;
|
|
}
|
|
|
|
//
|
|
// Handle Last Login ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsLastLogin);
|
|
if (!isPassed)
|
|
{
|
|
result.LastLogin = null;
|
|
}
|
|
|
|
//
|
|
// Handle Date Of Birth ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsDateOfBirth);
|
|
if (!isPassed)
|
|
{
|
|
result.DateOfBirth = null;
|
|
}
|
|
|
|
//
|
|
// Handle Creation Date ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsCreationDate);
|
|
if (!isPassed)
|
|
{
|
|
result.CreationDate = null;
|
|
}
|
|
|
|
//
|
|
// Handle Roles ...
|
|
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsRoles);
|
|
if (!isPassed)
|
|
{
|
|
result.Roles = new List<string>();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified User Has Access to Provided Roles ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="roles"></param>
|
|
/// <returns></returns>
|
|
public static bool HasAccess(
|
|
this XUserClaimsInfoDto source,
|
|
string[] roles
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!source.IsNullOrDefault() &&
|
|
source.Roles
|
|
.Any(r => roles
|
|
.Any(ar => r.ToNormalString()
|
|
.Contains(ar.ToNormalString())));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified User Contains Specified UserSelectByParam or not ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="userSelectByParam"></param>
|
|
/// <returns></returns>
|
|
public static bool ContainsUserSelectByParam(
|
|
this XUser source,
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!source.IsNull() &&
|
|
!userSelectByParam.IsNullOrEmpty() &&
|
|
(source.Id == userSelectByParam ||
|
|
source.Email.ToNormalString() == userSelectByParam.ToNormalString() ||
|
|
source.UserName.ToNormalString() == userSelectByParam.ToNormalString() ||
|
|
source.PhoneNumber.ToNormalString() == userSelectByParam.ToNormalString());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XModelExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Descriptors;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIdentityModels.Extensions {
|
|
public static class XModelExtensions {
|
|
/// <summary>
|
|
/// /// Convert XIdentityUserDescriptor instance to XUser
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XUser ToXUser (this XIdentityUserDescriptor source) {
|
|
return new XUser {
|
|
Id = source.Id,
|
|
FirstName = source.FirstName,
|
|
LastName = source.LastName,
|
|
UserName = source.UserName,
|
|
Email = source.Email,
|
|
EmailConfirmed = source.EmailConfirmed,
|
|
PhoneNumber = source.PhoneNumber,
|
|
PhoneNumberConfirmed = source.PhoneNumberConfirmed,
|
|
IsEnable = true,
|
|
IsBanned = false,
|
|
CreationDate = DateTime.UtcNow,
|
|
DateOfBirth = DateTime.Parse (source.DateOfBirth)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is Same as Descriptor User
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <returns></returns>
|
|
public static bool IsSameAs (this XUser source, XIdentityUserDescriptor dest) {
|
|
//
|
|
if (source.IsNull () ||
|
|
dest.IsNull ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var isSame = source.IsSameContent (dest, propertyWhiteList : new [] {
|
|
nameof (XIdentityUserDescriptor.FirstName),
|
|
nameof (XIdentityUserDescriptor.LastName),
|
|
nameof (XIdentityUserDescriptor.UserName),
|
|
nameof (XIdentityUserDescriptor.Email),
|
|
nameof (XIdentityUserDescriptor.EmailConfirmed),
|
|
nameof (XIdentityUserDescriptor.PhoneNumber),
|
|
nameof (XIdentityUserDescriptor.PhoneNumberConfirmed),
|
|
nameof (XIdentityUserDescriptor.IsEnable),
|
|
nameof (XIdentityUserDescriptor.IsBanned),
|
|
nameof (XIdentityUserDescriptor.DateOfBirth)
|
|
},
|
|
propertyValueCheckers : new [] {
|
|
new KeyValuePair<string, Func<XUser, XIdentityUserDescriptor, bool>> (
|
|
nameof (XIdentityUserDescriptor.DateOfBirth),
|
|
(user, descriptorUser) => {
|
|
//
|
|
var descriptorUserDateOfBirth = DateTime.Parse (descriptorUser.DateOfBirth);
|
|
return DateTime.Equals (user.DateOfBirth, descriptorUserDateOfBirth);
|
|
})
|
|
}
|
|
);
|
|
|
|
//
|
|
return isSame;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check to XDevice instance to be same or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <returns></returns>
|
|
public static bool IsSameAs (this XDevice source, XDevice dest) {
|
|
//
|
|
if (source.IsNull () ||
|
|
dest.IsNull ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var isSame = source.Os.ToNormalString () == dest.Os.ToNormalString () &&
|
|
source.OsVersion.ToNormalString () == dest.OsVersion.ToNormalString () &&
|
|
source.Browser.ToNormalString () == dest.Browser.ToNormalString () &&
|
|
source.UserAgent.ToNormalString () == dest.UserAgent.ToNormalString () &&
|
|
source.DeviceType == dest.DeviceType;
|
|
|
|
//
|
|
return isSame;
|
|
}
|
|
|
|
/// <summary>
|
|
/// convert UserClaimsInfo to TokenResponse ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse ToXTokenResponse (this XUserClaimsInfoDto source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
(source.AccessToken.IsNullOrEmpty () && source.RefreshToken.IsNullOrEmpty ())) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XTokenExtensions.cs
|
|
|
|
using System;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels.Extensions {
|
|
public static class XTokenExtensions {
|
|
//
|
|
#region Identity Token Extensions ...
|
|
/// <summary>
|
|
/// Convert a SecurityToken to it's Token String
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <returns></returns>
|
|
public static string ToTokenString (
|
|
this SecurityToken source,
|
|
JwtSecurityTokenHandler tokenHandler
|
|
) {
|
|
return tokenHandler.WriteToken (source);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
SecurityToken tokenObj = null;
|
|
try {
|
|
tokenHandler.ValidateToken (token, tokenValidationParams, out tokenObj);
|
|
} catch {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return tokenObj != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a token string to Security Token
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static SecurityToken ToSecurityToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty () ||
|
|
!token.ValidateToken (tokenHandler, tokenValidationParams)) {
|
|
//
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// convert token from String to JWTSecurity Token ...
|
|
try {
|
|
return tokenHandler.ReadToken (token);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse Action Token and return Corresponding RegistrationRequestDto
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenValidationParams"></param>
|
|
/// <returns></returns>
|
|
public static XActionRequestToken ParseActionRequestToken (
|
|
this string token,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
TokenValidationParameters tokenValidationParams) {
|
|
//
|
|
if (token.IsNullOrEmpty () ||
|
|
!token.ValidateToken (tokenHandler, tokenValidationParams)) {
|
|
//
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// convert token from String to JWTSecurity Token ...
|
|
JwtSecurityToken tokenObj = null;
|
|
try {
|
|
tokenObj = tokenHandler.ReadToken (token) as JwtSecurityToken;
|
|
} catch {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
if (tokenObj == null) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Extract Registered Payload Claims ...
|
|
var mCurrentStepClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Action));
|
|
var mContextClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Context));
|
|
var mTokenClaim = tokenObj.Claims
|
|
.FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Token));
|
|
|
|
//
|
|
// Check All Claims to be NotNull ...
|
|
if (mCurrentStepClaim == null ||
|
|
mContextClaim == null ||
|
|
mTokenClaim == null) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Reading all Claims Values ...
|
|
var mCurrentStepStr = mCurrentStepClaim.Value;
|
|
var mCurrentStep = 0;
|
|
try {
|
|
int.TryParse (mCurrentStepStr, out mCurrentStep);
|
|
} catch { }
|
|
|
|
//
|
|
var mContext = mContextClaim.Value.IsNullOrEmpty () ?
|
|
null : mContextClaim.Value.FromJSON<XActionRequestContext> ();
|
|
var mToken = mTokenClaim.Value;
|
|
|
|
//
|
|
// Create Instance of UserInvite ...
|
|
var result = new XActionRequestToken {
|
|
Action = (XAction) mCurrentStep,
|
|
Context = mContext,
|
|
Token = mToken
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check to ActionRequestContext object is same or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <returns></returns>
|
|
public static bool IsSameAs (
|
|
this XActionRequestContext source,
|
|
XActionRequestContext dest
|
|
) {
|
|
//
|
|
if (source == null ||
|
|
dest == null) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = source.ToJSON () == dest.ToJSON ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a RegistrationRequestDto object to it's jwt token Claims
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Claim[] ToJwtClaims (this XActionRequestToken source) {
|
|
//
|
|
// Generate Required Fields ...
|
|
var action = source.Action;
|
|
var context = source.Context;
|
|
var token = source.Token;
|
|
|
|
//
|
|
// Generate Claims Array ...
|
|
var claims = new Claim[] {
|
|
new Claim (nameof (XActionRequestToken.Action), ((int) action).ToString (), ClaimValueTypes.Integer),
|
|
new Claim (nameof (XActionRequestToken.Context), context == null ? "" : context.ToJSON (), ClaimValueTypes.String),
|
|
new Claim (nameof (XActionRequestToken.Token), token.IsNullOrEmpty () ? "" : token, ClaimValueTypes.String)
|
|
};
|
|
|
|
//
|
|
// Return Result ...
|
|
return claims;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a SecurityToken based on RegistrationRequestDto object
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="tokenHandler"></param>
|
|
/// <param name="tokenDescriptor"></param>
|
|
/// <returns></returns>
|
|
public static SecurityToken ToJwtToken (
|
|
this XActionRequestToken source,
|
|
JwtSecurityTokenHandler tokenHandler,
|
|
SecurityTokenDescriptor tokenDescriptor) {
|
|
//
|
|
// Getting Claims ...
|
|
var claims = source.ToJwtClaims ();
|
|
tokenDescriptor.Subject = new ClaimsIdentity (claims);
|
|
|
|
//
|
|
// Generate Token Object ...
|
|
var tokenObject = tokenHandler.CreateToken (tokenDescriptor);
|
|
|
|
//
|
|
// Return Result ...
|
|
return tokenObject;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region IdentityServer Token Extensions ...
|
|
/// <summary>
|
|
/// Retrieve Tokens From Headers
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this HttpRequest source) {
|
|
//
|
|
var accessToken = source.Headers[XAuthorization.Header].ToString ();
|
|
var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();
|
|
|
|
//
|
|
var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
return new XTokenResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From HttpContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XTokenResponse> RetrieveTokens (this HttpContext source) {
|
|
//
|
|
var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
|
|
var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var headerRequestTokens = source.Request.RetrieveTokens ();
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = accessToken ?? headerRequestTokens.AccessToken,
|
|
RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
|
|
ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From ActionExecutingContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XTokenResponse> RetrieveTokens (this ActionExecutingContext source) {
|
|
//
|
|
var result = await source.HttpContext.RetrieveTokens ();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From XUserInfo instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From IHeader Dictionary
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this IHeaderDictionary source) {
|
|
//
|
|
var accessToken = source[XAuthorization.Header].ToString () ?? "";
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";
|
|
|
|
//
|
|
var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
|
|
var expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate XTokenResponse instance based on TokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
source.IsError) {
|
|
XException.InvalidToken.Throw ();
|
|
}
|
|
|
|
//
|
|
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds () +
|
|
source.ExpiresIn;
|
|
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate XTokenResponse instance based on TokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse CreateXTokenResponse (this TokenResponse source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
source.IsError) {
|
|
XException.InvalidToken.Throw ();
|
|
}
|
|
|
|
//
|
|
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds () +
|
|
source.ExpiresIn;
|
|
|
|
//
|
|
var result = new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert XLoginResponse to XTokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse ToXTokenResponse (this XLoginResponse source) {
|
|
//
|
|
if (source.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return new XTokenResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this IHeaderDictionary source,
|
|
XLoginResponse model,
|
|
string secret = null
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
|
|
//
|
|
if (!secret.IsNullOrEmpty ()) {
|
|
var revisionChecksum = model.GetRevisionChecksum (secret);
|
|
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this IHeaderDictionary source,
|
|
XTokenResponse model,
|
|
string secret = null
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
|
|
//
|
|
if (!secret.IsNullOrEmpty ()) {
|
|
var revisionChecksum = model.GetRevisionChecksum (secret);
|
|
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestHeaders source,
|
|
XLoginResponse model
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestHeaders source,
|
|
XTokenResponse model
|
|
) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequest source,
|
|
XLoginResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequest source,
|
|
XTokenResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestMessage source,
|
|
XLoginResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpRequestMessage source,
|
|
XTokenResponse model
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add ReNewed Authorization Tokens in Headers of
|
|
/// Specific Response.
|
|
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
|
|
/// header Value and Renew User Tokens based on it
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpResponse source,
|
|
XLoginResponse model,
|
|
string secret
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model, secret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add ReNewed Authorization Tokens in Headers of
|
|
/// Specific Response.
|
|
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
|
|
/// header Value and Renew User Tokens based on it
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (
|
|
this HttpResponse source,
|
|
XTokenResponse model,
|
|
string secret
|
|
) {
|
|
source.Headers.SetXAuthenticationTokens (model, secret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Token Can Refrsh or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsRefreshable (this XLoginResponse source) {
|
|
//
|
|
var containsTokenData = !source.IsNull () &&
|
|
!source.AccessToken.IsNullOrEmpty () &&
|
|
!source.RefreshToken.IsNullOrEmpty ();
|
|
if (!containsTokenData) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var current = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds ();
|
|
|
|
//
|
|
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Token Can Refrsh or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsRefreshable (this XTokenResponse source) {
|
|
//
|
|
var containsTokenData = !source.IsNull () &&
|
|
!source.AccessToken.IsNullOrEmpty () &&
|
|
!source.RefreshToken.IsNullOrEmpty ();
|
|
if (!containsTokenData) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var current = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds ();
|
|
|
|
//
|
|
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (
|
|
this XLoginResponse source,
|
|
string secret
|
|
) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (
|
|
this XTokenResponse source,
|
|
string secret
|
|
) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XLoginResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (
|
|
this XLoginResponse source,
|
|
string checksum,
|
|
string secret
|
|
) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XTokenResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (
|
|
this XTokenResponse source,
|
|
string checksum,
|
|
string secret
|
|
) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Interfaces\IXUserRoleHelper.cs
|
|
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels.Interfaces {
|
|
public interface IXUserRoleHelper {
|
|
bool canReadCriticalData (XUserClaimsInfoDto userInfo);
|
|
bool canDoDangerousAction (XUserClaimsInfoDto userInfo);
|
|
bool isInRole (XUserClaimsInfoDto userInfo, string role);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequest.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIdentityModels.Models {
|
|
/// <summary>
|
|
/// represent a system wide actions
|
|
/// </summary>
|
|
public class XActionRequest {
|
|
/// <summary>
|
|
/// Client Device Locale
|
|
/// </summary>
|
|
/// <value>user's client device local such as en-US</value>
|
|
public string Lang { get; set; } = null;
|
|
/// <summary>
|
|
/// Requested Action Token
|
|
/// </summary>
|
|
/// <value>a hashed content</value>
|
|
public string ActionToken { get; set; } = null;
|
|
/// <summary>
|
|
/// user's device
|
|
/// </summary>
|
|
/// <value>an instance of <see>XDevice</see> which represent user's device</value>
|
|
public XDevice Device { get; set; } = null;
|
|
/// <summary>
|
|
/// FirstName
|
|
/// </summary>
|
|
/// <value>users FirstName</value>
|
|
public string FirstName { get; set; } = null;
|
|
/// <summary>
|
|
/// LastName
|
|
/// </summary>
|
|
/// <value>user's LastName</value>
|
|
public string LastName { get; set; } = null;
|
|
/// <summary>
|
|
/// an Optional Value which represetns User's DateOfBirth
|
|
/// </summary>
|
|
/// <value>user's DateOfBirth</value>
|
|
public DateTime? DateOfBirth { get; set; } = DateTime.MinValue;
|
|
/// <summary>
|
|
/// User's Id
|
|
/// </summary>
|
|
/// <value>a GUID string which represent user's Id</value>
|
|
public string UserId { get; set; } = null;
|
|
/// <summary>
|
|
/// UserName
|
|
/// </summary>
|
|
/// <value>user's UserName</value>
|
|
public string UserName { get; set; } = null;
|
|
/// <summary>
|
|
/// Email
|
|
/// </summary>
|
|
/// <value>user's Email address</value>
|
|
public string Email { get; set; } = null;
|
|
/// <summary>
|
|
/// MobileNumber / PhoneNumber
|
|
/// </summary>
|
|
/// <value>user's PhoneNumber</value>
|
|
public string MobileNumber { get; set; } = null;
|
|
/// <summary>
|
|
/// Password
|
|
/// </summary>
|
|
/// <value>user's Password</value>
|
|
public string Password { get; set; } = null;
|
|
/// <summary>
|
|
/// NewPassword
|
|
/// </summary>
|
|
/// <value>a passwor string which used to Change/Reset password</value>
|
|
public string NewPassword { get; set; } = null;
|
|
/// <summary>
|
|
/// EmailVerificationCode
|
|
/// </summary>
|
|
/// <value>a Verification Code which assign to user's for confirm it's Email Address</value>
|
|
public string EmailVerificationCode { get; set; } = null;
|
|
/// <summary>
|
|
/// MobileVerificationCode
|
|
/// </summary>
|
|
/// <value>a Verification Code which assign to user's for confirm it's Phone Number</value>
|
|
public string MobileVerificationCode { get; set; } = null;
|
|
/// <summary>
|
|
/// Thumbnail
|
|
/// </summary>
|
|
/// <value>an instance of <see>IFormFile</see> which is used as user's avatar</value>
|
|
public IFormFile Thumbnail { get; set; }
|
|
/// <summary>
|
|
/// ReturnUrl
|
|
/// </summary>
|
|
/// <value>
|
|
/// a url string which used in many used cases for providing a way to lead users to right places.
|
|
/// </value>
|
|
public string ReturnUrl { get; set; } = null;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequestContext.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XActionRequestContext {
|
|
//
|
|
public string Lang { get; set; }
|
|
|
|
//
|
|
public string UserId { get; set; }
|
|
public string UserName { get; set; }
|
|
|
|
//
|
|
public string MobileNumber { get; set; }
|
|
public string MobileVerificationCode { get; set; }
|
|
public bool MobileVerified { get; set; }
|
|
|
|
//
|
|
public string Email { get; set; }
|
|
public string EmailVerificationCode { get; set; }
|
|
public bool EmailVerified { get; set; }
|
|
|
|
//
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public DateTime DateOfBirth { get; set; }
|
|
|
|
//
|
|
public XDevice Device { get; set; }
|
|
public IFormFile Thubmnail { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequestToken.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Constants;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XActionRequestToken {
|
|
public XAction Action { get; set; }
|
|
public XActionRequestContext Context { get; set; }
|
|
public string Token { get; set; }
|
|
|
|
public void Prepare (string secret) {
|
|
Token = (Action.ToString () +
|
|
secret +
|
|
Context.ToJSON ()).ToMd5String ();
|
|
}
|
|
|
|
public bool Validate (string secret) {
|
|
return (Action.ToString () +
|
|
secret +
|
|
Context.ToJSON ()).ToMd5String () == Token;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionResponse.cs
|
|
|
|
using System;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace xIdentityModels.Models {
|
|
/// <summary>
|
|
/// represent a system wide action result
|
|
/// </summary>
|
|
public class XActionResponse {
|
|
/// <summary>
|
|
/// ActionToken
|
|
/// </summary>
|
|
/// <value>a hashed string which carry required info for doing system actions.</value>
|
|
[JsonProperty (
|
|
"token",
|
|
Required = Required.Default,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Token { get; set; }
|
|
|
|
/// <summary>
|
|
/// ActionToken Lifetime
|
|
/// </summary>
|
|
/// <value>an instance of <see>DateTime</see> which represent token expiration time</value>
|
|
[JsonProperty (
|
|
"expiration",
|
|
Required = Required.DisallowNull,
|
|
NullValueHandling = NullValueHandling.Ignore)]
|
|
public DateTime Expiration { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XBannedDevice.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XBannedDevice : XBaseIntIDEntity {
|
|
public DateTime BannedOn { get; set; }
|
|
|
|
public string DeviceStr { get; set; }
|
|
|
|
[NotMapped]
|
|
public XDevice Device {
|
|
get {
|
|
return DeviceStr.FromJSON<XDevice> ();
|
|
}
|
|
set {
|
|
DeviceStr = value.ToJSON ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XLoginRequest.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIdentityModels.Models {
|
|
/// <summary>
|
|
/// Represent Requirements for Authenticationg a User
|
|
/// </summary>
|
|
public class XLoginRequest {
|
|
/// <summary>
|
|
/// how select an specific User
|
|
/// </summary>
|
|
/// <value>an string value which represent how system select user such as: UserName, Email Address or MobileNumber</value>
|
|
[Required]
|
|
public string UserSelectBy { get; set; }
|
|
|
|
/// <summary>
|
|
/// user's password
|
|
/// </summary>
|
|
/// <value>an string which represent user's pasword</value>
|
|
[Required]
|
|
public string Password { get; set; }
|
|
|
|
/// <summary>
|
|
/// user's device
|
|
/// </summary>
|
|
/// <value>an instance of <see>XDevice</see> which represent user's device</value>
|
|
public XDevice Device { get; set; }
|
|
|
|
/// <summary>
|
|
/// user's language
|
|
/// </summary>
|
|
/// <value>an string which represent user's language and locale, such as: en-US</value>
|
|
public string Language { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XLoginResponse.cs
|
|
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XLoginResponse : XTokenResponse {
|
|
public XUserProfileDto Profile { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XProfileUpdateRequest.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xIdentityModels.Constants;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XProfileUpdateRequest {
|
|
public string Email { get; set; }
|
|
public bool? EmailConfirmed { get; set; }
|
|
public string PhoneNumber { get; set; }
|
|
public bool? PhoneNumberConfirmed { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public string Avatar { get; set; }
|
|
public DateTime? DateOfBirth { get; set; }
|
|
public DateTime? CreationDate { get; set; }
|
|
public DateTime? LastLogin { get; set; }
|
|
public XGender? Gender { get; set; }
|
|
public ICollection<string> Roles { get; set; } = new HashSet<string> ();
|
|
public bool? IsEnable { get; set; }
|
|
public bool? IsBanned { get; set; }
|
|
public string Bio { get; set; }
|
|
public string CoverImage { get; set; }
|
|
public bool OpenToSearch { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XToken.cs
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XToken : XBaseIntIDEntity {
|
|
public string Token { get; set; }
|
|
public string Hash { get; set; }
|
|
public string UserSelectByParam { get; set; }
|
|
public string DeviceStr { get; set; }
|
|
public XAction Type { get; set; }
|
|
|
|
[NotMapped]
|
|
public XDevice Device {
|
|
get {
|
|
return DeviceStr.FromJSON<XDevice> ();
|
|
}
|
|
|
|
set {
|
|
DeviceStr = value.ToJSON ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XTokenResponse.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XTokenResponse {
|
|
[Required]
|
|
public string AccessToken { get; set; }
|
|
public string RefreshToken { get; set; }
|
|
public long ExpiresAt { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XUserClaimsInfoDto.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Claims;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Models
|
|
{
|
|
public class XUserClaimsInfoDto : XBaseDto
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public string AccessToken { get; }
|
|
public string RefreshToken { get; }
|
|
public long ExpiresAt { get; }
|
|
public string UserId { get; }
|
|
public string UserName { get; }
|
|
public string FirstName { get; }
|
|
public string LastName { get; }
|
|
public string Picture { get; }
|
|
public string Email { get; }
|
|
public string PhoneNumber { get; }
|
|
public XGender Gender { get; }
|
|
public bool IsBanned { get; }
|
|
public bool IsEnabled { get; }
|
|
public bool EmailConfirmed { get; }
|
|
public bool PhoneNumberConfirmed { get; }
|
|
public string Bio { get; set; }
|
|
public string CoverImage { get; set; }
|
|
public bool OpenToSearch { get; set; }
|
|
public long? ExpiredOn { get; }
|
|
public long? AuthenticatedOn { get; }
|
|
public DateTime? BrithDate { get; }
|
|
public IEnumerable<string> Issuers { get; } = new HashSet<string>();
|
|
public IEnumerable<string> Audiences { get; } = new HashSet<string>();
|
|
public IEnumerable<string> ClientIds { get; } = new HashSet<string>();
|
|
public IEnumerable<string> Scopes { get; } = new HashSet<string>();
|
|
public IEnumerable<string> Roles { get; } = new HashSet<string>();
|
|
#endregion
|
|
|
|
//
|
|
public XUserClaimsInfoDto() { }
|
|
|
|
public XUserClaimsInfoDto(
|
|
string accessToken,
|
|
string refreshToken,
|
|
long expiresAt,
|
|
IEnumerable<Claim> claims
|
|
)
|
|
{
|
|
//
|
|
// refreshToken.IsNullOrEmpty ()
|
|
if (claims.IsNull() ||
|
|
accessToken.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Attach XLogin Properties ...
|
|
AccessToken = accessToken;
|
|
RefreshToken = refreshToken;
|
|
ExpiresAt = expiresAt;
|
|
|
|
//
|
|
if (!claims.IsNull())
|
|
{
|
|
//
|
|
UserId = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "";
|
|
UserName = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "";
|
|
FirstName = claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "";
|
|
LastName = claims.FirstOrDefault(c => c.Type == XCustomClaims.LastName)?.Value ?? "";
|
|
Picture = claims.FirstOrDefault(c => c.Type == XCustomClaims.Picture)?.Value ?? "";
|
|
Email = claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null;
|
|
PhoneNumber = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null;
|
|
|
|
//
|
|
Bio = claims.FirstOrDefault(c => c.Type == XCustomClaims.Bio)?.Value ?? null;
|
|
CoverImage = claims.FirstOrDefault(c => c.Type == XCustomClaims.CoverImage)?.Value ?? null;
|
|
|
|
//
|
|
var openToSearchStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.OpenToSearch)?.Value ?? null;
|
|
if (openToSearchStr.IsNullOrEmpty())
|
|
{
|
|
OpenToSearch = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var openToSearch = false;
|
|
bool.TryParse(openToSearchStr, out openToSearch);
|
|
|
|
//
|
|
OpenToSearch = openToSearch;
|
|
}
|
|
|
|
//
|
|
// Handle Gender ...
|
|
var genders = ObjectHelper.ToEnumerableKeys<XGender>();
|
|
var genderStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null;
|
|
if (genderStr.IsNullOrEmpty())
|
|
{
|
|
Gender = XGender.Male;
|
|
}
|
|
else
|
|
{
|
|
Gender = genderStr.GetValue<XGender>();
|
|
}
|
|
|
|
//
|
|
// Handle IsBanned ...
|
|
var isBannedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null;
|
|
if (isBannedStr.IsNullOrEmpty())
|
|
{
|
|
IsBanned = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var isBanned = false;
|
|
Boolean.TryParse(isBannedStr, out isBanned);
|
|
|
|
//
|
|
IsBanned = isBanned;
|
|
}
|
|
|
|
//
|
|
// Handle IsEnabled ...
|
|
var isEnabledStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null;
|
|
if (isEnabledStr.IsNullOrEmpty())
|
|
{
|
|
IsEnabled = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var isEnabled = false;
|
|
Boolean.TryParse(isEnabledStr, out isEnabled);
|
|
|
|
//
|
|
IsEnabled = isEnabled;
|
|
}
|
|
|
|
//
|
|
// Handle Email Confirmed ...
|
|
var emailConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null;
|
|
if (emailConfirmedStr.IsNullOrEmpty())
|
|
{
|
|
EmailConfirmed = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var emailConfirmed = false;
|
|
Boolean.TryParse(emailConfirmedStr, out emailConfirmed);
|
|
|
|
//
|
|
EmailConfirmed = emailConfirmed;
|
|
}
|
|
|
|
//
|
|
// Handle PhoneNumber Confirmed ...
|
|
var phoneNumberConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null;
|
|
if (phoneNumberConfirmedStr.IsNullOrEmpty())
|
|
{
|
|
PhoneNumberConfirmed = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var phoneNumberConfirmed = false;
|
|
Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed);
|
|
|
|
//
|
|
PhoneNumberConfirmed = phoneNumberConfirmed;
|
|
}
|
|
|
|
//
|
|
// Handle ExpiredOn ...
|
|
var expiredOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null;
|
|
if (expiredOnStr.IsNullOrEmpty())
|
|
{
|
|
ExpiredOn = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
long expiredOn = 0;
|
|
long.TryParse(expiredOnStr, out expiredOn);
|
|
|
|
//
|
|
ExpiredOn = expiredOn;
|
|
}
|
|
|
|
//
|
|
// Handle AuthenticatedOn ...
|
|
var authenticatedOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null;
|
|
if (authenticatedOnStr.IsNullOrEmpty())
|
|
{
|
|
AuthenticatedOn = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
long authenticatedOn = 0;
|
|
long.TryParse(authenticatedOnStr, out authenticatedOn);
|
|
|
|
//
|
|
AuthenticatedOn = authenticatedOn;
|
|
}
|
|
|
|
//
|
|
// Handle BrithDate ...
|
|
var brithDateStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? "";
|
|
if (brithDateStr.IsNullOrEmpty())
|
|
{
|
|
// BrithDate = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
DateTime bDate;
|
|
DateTime.TryParse(brithDateStr, out bDate);
|
|
|
|
//
|
|
BrithDate = bDate;
|
|
}
|
|
|
|
//
|
|
// Collections ...
|
|
Issuers = claims.Where(c => c.Type == XCustomClaims.Issuer)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
Audiences = claims.Where(c => c.Type == XCustomClaims.Audience)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
ClientIds = claims.Where(c => c.Type == XCustomClaims.ClientId)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
Scopes = claims.Where(c => c.Type == XCustomClaims.Scope)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
Roles = claims.Where(c => c.Type == XCustomClaims.Role)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XVerificationRequest.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Models {
|
|
public class XVerificationRequest : XBaseIntIDEntity {
|
|
|
|
[Required]
|
|
public string VerificationCode { get; set; }
|
|
|
|
public int NumberOfTries { get; set; }
|
|
public DateTime LastTryOn { get; set; }
|
|
|
|
[NotMapped]
|
|
public XActionRequestToken Request {
|
|
get {
|
|
return RequestStr.FromJSON<XActionRequestToken> ();
|
|
}
|
|
set {
|
|
RequestStr = value.ToJSON ();
|
|
}
|
|
}
|
|
|
|
public string RequestStr { get; set; }
|
|
|
|
[NotMapped]
|
|
public XDevice Device {
|
|
get {
|
|
return DeviceStr.FromJSON<XDevice> ();
|
|
}
|
|
set {
|
|
DeviceStr = value.ToJSON ();
|
|
}
|
|
}
|
|
|
|
public string DeviceStr { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XDevice.cs
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xCommons.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Navigations {
|
|
/// <summary>
|
|
/// Represent a Client Device which used by User
|
|
/// </summary>
|
|
public class XDevice : XBaseIntIDEntity {
|
|
/// <summary>
|
|
/// Operating System
|
|
/// </summary>
|
|
/// <value>device operating system identifier</value>
|
|
public string Os { get; set; }
|
|
/// <summary>
|
|
/// Operating System Version
|
|
/// </summary>
|
|
/// <value>which version of operatin system is in use</value>
|
|
public string OsVersion { get; set; }
|
|
/// <summary>
|
|
/// Device Browser
|
|
/// </summary>
|
|
/// <value>the Browser identifier</value>
|
|
public string Browser { get; set; }
|
|
/// <summary>
|
|
/// Browser Engine Agent
|
|
/// </summary>
|
|
/// <value>browser engine Agent</value>
|
|
public string UserAgent { get; set; }
|
|
/// <summary>
|
|
/// Type of client Device
|
|
/// </summary>
|
|
/// <value>represent device type <see>XDeviceType</see></value>
|
|
public XDeviceType DeviceType { get; set; }
|
|
|
|
//
|
|
#region User ...
|
|
/// <summary>
|
|
/// UserId
|
|
/// </summary>
|
|
/// <value>Represent this Devie belong to which User Identifier</value>
|
|
public string UserId { get; set; }
|
|
/// <summary>
|
|
/// User
|
|
/// </summary>
|
|
/// <value>Represent Device User <see>XUser</see></value>
|
|
[ForeignKey (nameof (UserId))]
|
|
public virtual XUser User { get; set; }
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XFriendshipFollower.cs
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xIdentityModels.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Navigations {
|
|
/// <summary>
|
|
/// represent a Follower of specific User
|
|
/// </summary>
|
|
public class XFriendshipFollower : XBaseIntIDEntity {
|
|
/// <summary>
|
|
/// XFriendshipState
|
|
/// </summary>
|
|
/// <value>state of Friendship at current moment <see>XFriendshipState</see></value>
|
|
public XFriendshipState State { get; set; }
|
|
|
|
//
|
|
#region User ...
|
|
/// <summary>
|
|
/// UserId
|
|
/// </summary>
|
|
/// <value>source User's Id</value>
|
|
public string UserId { get; set; }
|
|
/// <summary>
|
|
/// User
|
|
/// </summary>
|
|
/// <value>source User <see>XUser</see></value>
|
|
[ForeignKey (nameof (UserId))]
|
|
public virtual XUser User { get; set; }
|
|
#endregion
|
|
|
|
//
|
|
#region Dest User ...
|
|
/// <summary>
|
|
/// DestId
|
|
/// </summary>
|
|
/// <value>destination User's Id</value>
|
|
public string DestId { get; set; }
|
|
/// <summary>
|
|
/// Dest
|
|
/// </summary>
|
|
/// <value>dest User <see>XUser</see></value>
|
|
[ForeignKey (nameof (DestId))]
|
|
public virtual XUser Dest { get; set; }
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XFriendshipFollowing.cs
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xIdentityModels.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Navigations {
|
|
/// <summary>
|
|
/// represent a Following of specific User
|
|
/// </summary>
|
|
public class XFriendshipFollowing : XBaseIntIDEntity {
|
|
/// <summary>
|
|
/// XFriendshipState
|
|
/// </summary>
|
|
/// <value>state of Friendship at current moment <see>XFriendshipState</see></value>
|
|
public XFriendshipState State { get; set; }
|
|
|
|
//
|
|
#region User ...
|
|
/// <summary>
|
|
/// UserId
|
|
/// </summary>
|
|
/// <value>source User's Id</value>
|
|
public string UserId { get; set; }
|
|
/// <summary>
|
|
/// User
|
|
/// </summary>
|
|
/// <value>source User <see>XUser</see></value>
|
|
[ForeignKey (nameof (UserId))]
|
|
public virtual XUser User { get; set; }
|
|
#endregion
|
|
|
|
//
|
|
#region Dest User ...
|
|
/// <summary>
|
|
/// DestId
|
|
/// </summary>
|
|
/// <value>destination User's Id</value>
|
|
public string DestId { get; set; }
|
|
/// <summary>
|
|
/// Dest
|
|
/// </summary>
|
|
/// <value>dest User <see>XUser</see></value>
|
|
[ForeignKey (nameof (DestId))]
|
|
public virtual XUser Dest { get; set; }
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XProfileImage.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityModels.Navigations {
|
|
/// <summary>
|
|
/// Represent a User's Avatar Entity
|
|
/// </summary>
|
|
public class XProfileImage : XBaseIntIDEntity {
|
|
/// <summary>
|
|
/// UserId
|
|
/// </summary>
|
|
/// <value>represent current Avatar belongs to which User</value>
|
|
public string UserId { get; set; }
|
|
/// <summary>
|
|
/// User
|
|
/// </summary>
|
|
/// <value>User instance <see>XUser</see></value>
|
|
[ForeignKey (nameof (UserId))]
|
|
public XUser User { get; set; }
|
|
/// <summary>
|
|
/// Name
|
|
/// </summary>
|
|
/// <value>Avatar's file name</value>
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string Name { get; set; }
|
|
/// <summary>
|
|
/// Thumb
|
|
/// </summary>
|
|
/// <value>Avatar's thumbnail file's name</value>
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string Thumb { get; set; }
|
|
/// <summary>
|
|
/// Path
|
|
/// </summary>
|
|
/// <value>Avatar's Image path on Profile Server</value>
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string Path { get; set; }
|
|
/// <summary>
|
|
/// ThumbPath
|
|
/// </summary>
|
|
/// <value>Avatar's Thumbnail Image path on Profile Service</value>
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string ThumbPath { get; set; }
|
|
/// <summary>
|
|
/// CreationDate
|
|
/// </summary>
|
|
/// <value>Upload Time</value>
|
|
public DateTime CreationDate { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Providers\XDefaultUserRoleHelper.cs
|
|
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Interfaces;
|
|
|
|
namespace xIdentityModels.Providers {
|
|
public class XDefaultUserRoleHelper : IXUserRoleHelper {
|
|
public bool canReadCriticalData (XUserClaimsInfoDto userInfo) {
|
|
return isInRole (userInfo, "admin");
|
|
}
|
|
|
|
public bool canDoDangerousAction (XUserClaimsInfoDto userInfo) {
|
|
return isInRole (userInfo, "admin");
|
|
}
|
|
|
|
public bool isInRole (XUserClaimsInfoDto userInfo, string role) {
|
|
return userInfo.Roles
|
|
.Any (r =>
|
|
r.ToNormalString () == role.ToNormalString ()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\XApiToken.cs
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityModels {
|
|
public class XApiToken : XBaseIntIDEntity {
|
|
public string Content { get; set; }
|
|
|
|
[NotMapped]
|
|
public XTokenResponse Tokens {
|
|
get { return Content.IsNullOrEmpty () ? null : Content.FromJSON<XTokenResponse> (); }
|
|
set { Content = value.ToJSON (); }
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\XUser.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIdentityModels
|
|
{
|
|
/// <summary>
|
|
/// represnt a User of System
|
|
/// </summary>
|
|
public partial class XUser : IdentityUser
|
|
{
|
|
//
|
|
#region Properties ...
|
|
/// <summary>
|
|
/// FirstName
|
|
/// </summary>
|
|
/// <value>user's FirstName</value>
|
|
[Required]
|
|
[StringLength(50)]
|
|
public string FirstName { get; set; }
|
|
/// <summary>
|
|
/// LastName
|
|
/// </summary>
|
|
/// <value>user's LastName</value>
|
|
[Required]
|
|
[StringLength(100)]
|
|
public string LastName { get; set; }
|
|
/// <summary>
|
|
/// User is Enabled or not
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// system was restrict Disabled Users access to Many Resources
|
|
/// </remarks>
|
|
/// <value>boolean value represent User is Enable or not</value>
|
|
public bool IsEnable { get; set; }
|
|
/// <summary>
|
|
/// User is Banned or not
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// system was reject Banned Users access to Almost all Resources
|
|
/// </remarks>
|
|
/// <value>boolean value represent User is Banned or not</value>
|
|
public bool IsBanned { get; set; }
|
|
/// <summary>
|
|
/// DateOfBirth
|
|
/// </summary>
|
|
/// <value>user's DateOfBirth</value>
|
|
[Required]
|
|
public DateTime DateOfBirth { get; set; }
|
|
/// <summary>
|
|
/// CreationDate
|
|
/// </summary>
|
|
/// <value>user's Creation/Registration Date</value>
|
|
[Required]
|
|
public DateTime CreationDate { get; set; }
|
|
/// <summary>
|
|
/// LastLogin
|
|
/// </summary>
|
|
/// <value>user's Last Successfull Login Date</value>
|
|
public DateTime? LastLogin { get; set; }
|
|
/// <summary>
|
|
/// ProfileImage/Avatar
|
|
/// </summary>
|
|
/// <value>user's current Avatar</value>
|
|
public string Avatar { get; set; }
|
|
/// <summary>
|
|
/// Gender
|
|
/// </summary>
|
|
/// <value>user's Gender</value>
|
|
[Required]
|
|
public XGender Gender { get; set; }
|
|
/// <summary>
|
|
/// User Biography ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Bio { get; set; }
|
|
/// <summary>
|
|
/// User Bio Cover Image ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string CoverImage { get; set; }
|
|
/// <summary>
|
|
/// Can Discover User ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool OpenToSearch { get; set; }
|
|
#endregion
|
|
|
|
//
|
|
#region Navigation Properties ...
|
|
/// <summary>
|
|
/// User's Devices
|
|
/// </summary>
|
|
/// <typeparam name="XDevice"><see>XDevice</see></typeparam>
|
|
/// <returns>a Collection of all assigned Devices to User</returns>
|
|
[InverseProperty("User")]
|
|
public virtual ICollection<XDevice> Devices { get; set; } = new HashSet<XDevice>();
|
|
/// <summary>
|
|
/// User's Avatars
|
|
/// </summary>
|
|
/// <typeparam name="XProfileImage"><see>XProfileImage</see></typeparam>
|
|
/// <returns>a Collection of all assigned Avatars to User</returns>
|
|
[InverseProperty("User")]
|
|
public virtual ICollection<XProfileImage> Avatars { get; set; } = new HashSet<XProfileImage>();
|
|
/// <summary>
|
|
/// User's Followers
|
|
/// </summary>
|
|
/// <typeparam name="XFriendshipFollower"><see>XFriendshipFollower</see></typeparam>
|
|
/// <returns>a Collection of all User's Followers</returns>
|
|
[InverseProperty("User")]
|
|
public virtual ICollection<XFriendshipFollower> Followers { get; set; } = new HashSet<XFriendshipFollower>();
|
|
/// <summary>
|
|
/// User's Followings
|
|
/// </summary>
|
|
/// <typeparam name="XFriendshipFollowing"><see>XFriendshipFollowing</see></typeparam>
|
|
/// <returns>a Collection of all User's Followings</returns>
|
|
[InverseProperty("User")]
|
|
public virtual ICollection<XFriendshipFollowing> Followings { get; set; } = new HashSet<XFriendshipFollowing>();
|
|
/// <summary>
|
|
/// User's Roles
|
|
/// </summary>
|
|
/// <returns>a Collection of all User's Roles in System</returns>
|
|
public virtual ICollection<IdentityUserRole<string>> Roles { get; set; } = new HashSet<IdentityUserRole<string>>();
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XIdentityServiceConfiguration.cs
|
|
|
|
using xIdentityService.Constants;
|
|
|
|
namespace xIdentityService.Configuration {
|
|
public partial class XIdentityServiceConfiguration {
|
|
public string Authority { get; set; }
|
|
public string ApiName { get; set; }
|
|
public string ApiSecret { get; set; }
|
|
public string ClientId { get; set; }
|
|
public string ClientSecret { get; set; }
|
|
public string XPoweredValue { get; set; }
|
|
public XTokenType TokenType { get; set; }
|
|
public string XRevisionSecretKey { get; set; }
|
|
public int DefaultClientTimeout { get; set; } = 360;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XProxyConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityService.Configuration {
|
|
/// <summary>
|
|
/// XProxy Middleware Configuration ...
|
|
/// </summary>
|
|
public class XProxyConfiguration {
|
|
/// <summary>
|
|
/// Proxy Host Address for Clients Which Use XProxy Server ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Host { get; set; }
|
|
|
|
/// <summary>
|
|
/// if EnableXPoweredByAthorization property setted to true, this property determines
|
|
/// the header must be this value ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string XPoweredValue { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Proxy Http Handler Check SSL or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool DisableSSLCheck { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Http Client Handler Allow Auto Redirect or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool AllowAutoRedirect { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Proxy Server Log Received Requests or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableLogging { get; set; }
|
|
|
|
/// <summary>
|
|
/// DefineRoutes for Handling ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public HashSet<XProxyRouteDescriptor> Routes { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Describe a Proxy Route ...
|
|
/// </summary>
|
|
public class XProxyRouteDescriptor : XBaseDescriptor {
|
|
/// <summary>
|
|
/// Determines which route can handled for Proxyfing ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Route { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Proxy Server Handle Athorization or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableAuthorization { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Which Scopes allowed to this route if authorizations enabled ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public HashSet<string> AllowedScopes { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines Which Roles allowed to this route if authorizations enabled ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public HashSet<string> AllowedRoles { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines XProxy Can Check XPowered By Authorization or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableXPoweredByAthorization { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xIdentityService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string XPROXY_CONFIGURATION_NODE_NAME = "ProxyConfiguration";
|
|
public const string IDENTITY_SERVICE_NODE_NAME = "IdentityServiceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XApiAccountEndpoint.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityService.Constants
|
|
{
|
|
public enum XApiAccountEndpoint
|
|
{
|
|
//
|
|
#region Authentication ...
|
|
[StringValue("Account/DiscoveryDocument")]
|
|
DiscoveryDocument,
|
|
|
|
[StringValue("Account/RequestScopeAccessToken")]
|
|
RequestScopeAccessToken,
|
|
|
|
[StringValue("Account/Authenticate")]
|
|
Authenticate,
|
|
|
|
[StringValue("Account/Login")]
|
|
Login,
|
|
|
|
[StringValue("Account/RefreshTokens")]
|
|
RefreshTokens,
|
|
|
|
[StringValue("Account/ChangePassword")]
|
|
ChangePassword,
|
|
|
|
[StringValue("Account/ResetPassword")]
|
|
ResetPassword,
|
|
#endregion
|
|
|
|
//
|
|
#region Proile ...
|
|
[StringValue("Account/Profile/{ids}/GetNames")]
|
|
GetNames,
|
|
|
|
[StringValue("Account/Profile/GetNameIds")]
|
|
GetNameIds,
|
|
|
|
[StringValue("Account/Profile/{userSelectByParam}")]
|
|
GetProfile,
|
|
|
|
[StringValue("Account/Profile/Query")]
|
|
QueryProfiles,
|
|
|
|
[StringValue("Account/Profile/Avatars/Query/{userSelectByParam}")]
|
|
QueryAvatars,
|
|
|
|
[StringValue("Account/Profile/Update/{userSelectByParam}")]
|
|
UpdateProfile,
|
|
|
|
[StringValue("Account/Profile/{userSelectByParam}")]
|
|
FullUpdateProfile,
|
|
|
|
[StringValue("Account/Profile/Avatar")]
|
|
AddAvatar,
|
|
|
|
[StringValue("Account/Profile/Avatars")]
|
|
AddAvatars,
|
|
|
|
[StringValue("Account/Profile/Avatars/{ids}")]
|
|
RemoveAvatars,
|
|
|
|
[StringValue("Account/Profile/Avatars/{id}/Set")]
|
|
SetAvatar,
|
|
#endregion
|
|
|
|
//
|
|
#region Search ...
|
|
[StringValue("Account/OpenToSearch/Query")]
|
|
QueryOpenToSearchProfiles,
|
|
#endregion
|
|
|
|
//
|
|
#region Registration ...
|
|
[StringValue("Account/CanRegisterUserName/{userName}")]
|
|
CanRegisterUserName,
|
|
|
|
[StringValue("Account/CanRegisterMobileNumber/{mobileNumber}")]
|
|
CanRegisterMobileNumber,
|
|
|
|
[StringValue("Account/CanRegisterEmail/{email}")]
|
|
CanRegisterEmail,
|
|
|
|
[StringValue("Account/IsConfirmedEmail")]
|
|
IsConfirmedEmail,
|
|
|
|
[StringValue("Account/IsConfirmedMobile")]
|
|
IsConfirmedMobile,
|
|
|
|
[StringValue("Account/ConfirmRegistration")]
|
|
ConfirmRegistration,
|
|
|
|
[StringValue("Account/ConfirmMobileNumber")]
|
|
ConfirmMobileNumber,
|
|
|
|
[StringValue("Account/ConfirmEmailAddress")]
|
|
ConfirmEmailAddress,
|
|
|
|
[StringValue("Account/RequestConfirmMobile")]
|
|
RequestConfirmMobile,
|
|
|
|
[StringValue("Account/RequestConfirmEmail")]
|
|
RequestConfirmEmail,
|
|
|
|
[StringValue("Account/RequestResetPassword")]
|
|
RequestResetPassword,
|
|
|
|
[StringValue("Account/RequestConfirmRegistration")]
|
|
RequestConfirmRegistration,
|
|
|
|
[StringValue("Account/InviteUser")]
|
|
InviteUser,
|
|
|
|
[StringValue("Account/RequestRegistration")]
|
|
RequestRegistration,
|
|
|
|
[StringValue("Account/AddAccountInfo")]
|
|
AddAccountInfo,
|
|
|
|
[StringValue("Account/AttachProfileImage")]
|
|
AttachProfileImage,
|
|
|
|
[StringValue("Account/FinishRegistration")]
|
|
FinishRegistration,
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship ...
|
|
[StringValue("Account/Friendship/{destUser}/Follow")]
|
|
Follow,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/Cancel")]
|
|
Cancel,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/UnFollowFollower")]
|
|
UnFollowFollower,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/UnFollowFollowing")]
|
|
UnFollowFollowing,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/Block")]
|
|
Block,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/UnBlock")]
|
|
UnBlock,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/AcceptRequest")]
|
|
AcceptRequest,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/RejectRequest")]
|
|
RejectRequest,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/FriendshipInfo")]
|
|
FriendshipInfo,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/IsFollower")]
|
|
IsFollower,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/FollowerState")]
|
|
FollowerState,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/Follower")]
|
|
Follower,
|
|
|
|
[StringValue("Account/Friendship/Followers")]
|
|
Followers,
|
|
|
|
[StringValue("Account/Friendship/AllFollowers")]
|
|
AllFollowers,
|
|
|
|
[StringValue("Account/Friendship/FollowersList")]
|
|
FollowersList,
|
|
|
|
[StringValue("Account/Friendship/QueryFollowers")]
|
|
QueryFollowers,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/IsFollowing")]
|
|
IsFollowing,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/FollowingState")]
|
|
FollowingState,
|
|
|
|
[StringValue("Account/Friendship/{destUser}/Following")]
|
|
Following,
|
|
|
|
[StringValue("Account/Friendship/Followings")]
|
|
Followings,
|
|
|
|
[StringValue("Account/Friendship/AllFollowings")]
|
|
AllFollowings,
|
|
|
|
[StringValue("Account/Friendship/FollowingsList")]
|
|
FollowingsList,
|
|
|
|
[StringValue("Account/Friendship/QueryFollowings")]
|
|
QueryFollowings,
|
|
#endregion
|
|
|
|
//
|
|
#region Admin ...
|
|
[StringValue("Account/Ban")]
|
|
Ban,
|
|
|
|
[StringValue("Account/UnBan")]
|
|
UnBan,
|
|
|
|
[StringValue("Account/IsBanned/{userSelectByParam}")]
|
|
IsBanned,
|
|
#endregion
|
|
|
|
//
|
|
#region Open Actions ...
|
|
[StringValue("Account/Open")]
|
|
Open,
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XAuthenticationScheme.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityService.Constants {
|
|
public enum XAuthenticationScheme {
|
|
[StringValue ("token")]
|
|
XToken,
|
|
[StringValue ("introspection")]
|
|
XIntrospection,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XHeader.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityService.Constants
|
|
{
|
|
/// <summary>
|
|
/// All Available Headers ...
|
|
/// </summary>
|
|
public enum XHeader
|
|
{
|
|
/// <summary>
|
|
/// Hub Connection ID Header Keys ...
|
|
/// </summary>
|
|
[StringValue("requestID")]
|
|
ConnectionId,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XParam.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xIdentityService.Constants {
|
|
public enum XParam {
|
|
[StringValue ("Content-Type")]
|
|
XContentType,
|
|
|
|
[StringValue ("{boundary}")]
|
|
XBoundary,
|
|
|
|
[StringValue ("{userSelectByParam}")]
|
|
XUserSelectByParam,
|
|
|
|
[StringValue ("{destUser}")]
|
|
XDestUser,
|
|
|
|
[StringValue ("{id}")]
|
|
XId,
|
|
|
|
[StringValue ("{ids}")]
|
|
XIds,
|
|
|
|
[StringValue ("Origin")]
|
|
XOrigin,
|
|
|
|
[StringValue ("{userName}")]
|
|
XUserName,
|
|
|
|
[StringValue ("{mobileNumber}")]
|
|
XMobileNumber,
|
|
|
|
[StringValue ("{email}")]
|
|
XEmail,
|
|
|
|
[StringValue ("role")]
|
|
XRole,
|
|
|
|
[StringValue ("forceRole")]
|
|
XForceRole,
|
|
|
|
[StringValue ("IsRefreshed")]
|
|
XIsRefreshed,
|
|
|
|
[StringValue ("file")]
|
|
XFile,
|
|
|
|
[StringValue ("files")]
|
|
XFiles,
|
|
|
|
[StringValue ("actionToken")]
|
|
XActionToken,
|
|
|
|
[StringValue ("request")]
|
|
XRequest,
|
|
|
|
[StringValue ("scope")]
|
|
XScope,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XProxyConstants.cs
|
|
|
|
namespace xIdentityService.Constants {
|
|
public struct XProxyConstants {
|
|
public const string XPROXY_HTTP_CLIENT = "XProxyHttpClient";
|
|
public const string XPROXY_FORWARD_HEADER = "xForwardHeader";
|
|
public const string XPROXY_ACCEPTED_HEADERS = "xAcceptedHeaders";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XResponseContentTypes.cs
|
|
|
|
namespace xIdentityService.Constants {
|
|
public struct XResponseContentTypes {
|
|
public const string HTML = "text/html";
|
|
public const string JSON = "application/json";
|
|
public const string JavaScript = "text/javascript";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XTokenType.cs
|
|
|
|
namespace xIdentityService.Constants {
|
|
public enum XTokenType {
|
|
//
|
|
// Summary:
|
|
// Self-contained Json Web Token
|
|
Jwt,
|
|
//
|
|
// Summary:
|
|
// Reference token
|
|
Reference
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiController.cs
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Base Identity Api Controller
|
|
/// </summary>
|
|
[ApiController]
|
|
[RequireXPowered(true)]
|
|
[Route("api/[controller]")]
|
|
[Produces("application/json")]
|
|
public abstract class XBaseIdentityApiController : XBaseIdentityController
|
|
{
|
|
protected XBaseIdentityApiController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiV1Controller.cs
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Base Identity Api V1 Controller
|
|
/// </summary>
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[RequireXPowered(true)]
|
|
[Route("api/v{version:apiVersion}/[controller]")]
|
|
public abstract class XBaseIdentityApiV1Controller : XBaseIdentityApiController
|
|
{
|
|
protected XBaseIdentityApiV1Controller(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Constants;
|
|
using xCommons.Controllers;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Controllers
|
|
{
|
|
public abstract class XBaseIdentityController : XBaseController
|
|
{
|
|
//
|
|
public IXIdentityProvider IdentityProvider { get; }
|
|
|
|
protected XBaseIdentityController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{
|
|
IdentityProvider = identityProvider;
|
|
}
|
|
|
|
//
|
|
#region NonActions ...
|
|
/// <summary>
|
|
/// Retrieve Connection ID for Hubs ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public string GetConnectionId()
|
|
{
|
|
//
|
|
var result = "";
|
|
|
|
//
|
|
var headerKey = XHeader.ConnectionId.GetStringValue();
|
|
|
|
//
|
|
// Check if Connection ID is Provided ...
|
|
if (Request.Headers.ContainsKey(headerKey))
|
|
{
|
|
result = Request.Headers[headerKey];
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve User Identifier Base on XActionRequest
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var result = IdentityProvider.GetUserSelectByParam(
|
|
model,
|
|
forceNotNull,
|
|
excludes
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<string> GetAccessToken()
|
|
{
|
|
//
|
|
var accessToken = Request.Headers[XAuthorization.Header].ToString();
|
|
if (accessToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
accessToken = await HttpContext
|
|
.GetTokenAsync(XAuthorization.AccessToken);
|
|
}
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString()
|
|
.Contains(XAuthorization.TokenIdentifier
|
|
.ToNormalString()))
|
|
{
|
|
//
|
|
accessToken = accessToken
|
|
.Remove(0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
return accessToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Refresh Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<string> GetRefreshToken()
|
|
{
|
|
//
|
|
var refreshToken = Request.Headers[XAuthorization.RefreshToken].ToString();
|
|
if (refreshToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
refreshToken = await HttpContext
|
|
.GetTokenAsync(XAuthorization.RefreshToken);
|
|
}
|
|
|
|
//
|
|
return refreshToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token Expiration Date
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<long> GetTokenExpiresAt()
|
|
{
|
|
//
|
|
var expiresAtStr = Request.Headers[XAuthorization.ExpiresAt].ToString();
|
|
if (expiresAtStr.IsNullOrEmpty())
|
|
{
|
|
//
|
|
expiresAtStr = await HttpContext
|
|
.GetTokenAsync(XAuthorization.ExpiresAt);
|
|
}
|
|
|
|
//
|
|
var expiresAt = expiresAtStr.ConvertTo<long>();
|
|
|
|
//
|
|
return expiresAt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Required Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XLoginResponse> RetrieveTokensAsXLoginResponse()
|
|
{
|
|
//
|
|
var accessToken = await GetAccessToken();
|
|
var refreshToken = await GetRefreshToken();
|
|
var expiresAt = await GetTokenExpiresAt();
|
|
|
|
//
|
|
return new XLoginResponse
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Required Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XTokenResponse> RetrieveTokensAsXTokenResponse()
|
|
{
|
|
//
|
|
var accessToken = await GetAccessToken();
|
|
var refreshToken = await GetRefreshToken();
|
|
var expiresAt = await GetTokenExpiresAt();
|
|
|
|
//
|
|
return new XTokenResponse
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrive UserInfo
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XUserClaimsInfoDto> GetUserInfo()
|
|
{
|
|
//
|
|
var claims = User.Claims ?? null;
|
|
if (!claims.HasChild())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var xTokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = new XUserClaimsInfoDto(
|
|
xTokens.AccessToken,
|
|
xTokens.RefreshToken,
|
|
xTokens.ExpiresAt,
|
|
User.Claims
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate User Authenticated and Retrieve User Info
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XUserClaimsInfoDto> ValidateAndGetUserInfo()
|
|
{
|
|
//
|
|
if (!User.Identity.IsAuthenticated)
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserInfo();
|
|
if (result.IsNull())
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using IdentityModel.AspNetCore.OAuth2Introspection;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Authorization;
|
|
using xCommons.Extensions;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Providers;
|
|
using xIdentityService.Security;
|
|
|
|
namespace xIdentityService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Extract Module Configuration Structure from IConfiguration interface
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <returns></returns>
|
|
public static XIdentityServiceConfiguration GetXIdentityServiceConfiguration (this IConfiguration config) {
|
|
//
|
|
var xIdentityServiceConfigSection = config.GetSection (ConfigurationNodeNames.IDENTITY_SERVICE_NODE_NAME);
|
|
return xIdentityServiceConfigSection.Get<XIdentityServiceConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service and All it's Requirements
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXIdentityService (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Singleton
|
|
) {
|
|
//
|
|
var identityConfiguration = configuration.GetXIdentityServiceConfiguration ();
|
|
AddIdentityService (
|
|
services,
|
|
identityConfiguration,
|
|
lifeTime
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service and All it's Requirements
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXIdentityService (
|
|
this IServiceCollection services,
|
|
XIdentityServiceConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Singleton
|
|
) {
|
|
AddIdentityService (services, configuration, lifeTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Custome Token Provider
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
public static void AddXTokenProvider<T> (
|
|
this IServiceCollection services,
|
|
ServiceLifetime lifetime = ServiceLifetime.Singleton)
|
|
where T : IXTokenProvider {
|
|
//
|
|
Console.WriteLine ("IdentityService: Add Custom Token Provider ...");
|
|
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (T), lifetime));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Authentication
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXIdentityService (this IApplicationBuilder app) {
|
|
app.UseAuthentication ();
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static void AddIdentityService (
|
|
this IServiceCollection services,
|
|
XIdentityServiceConfiguration config,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Singleton
|
|
) {
|
|
//
|
|
services.AddSingleton<XIdentityServiceConfiguration> (config);
|
|
|
|
//
|
|
var builder = services
|
|
.AddAuthentication (XAuthenticationScheme.XToken.GetStringValue ());
|
|
|
|
//
|
|
// Add JWT Handler ...
|
|
builder.AddJwtBearer (
|
|
XAuthenticationScheme.XToken.GetStringValue (), options => {
|
|
//
|
|
options.Authority = config.Authority;
|
|
options.TokenValidationParameters.ValidateAudience = false;
|
|
options.TokenValidationParameters.ValidTypes = new [] { "at+jwt" };
|
|
|
|
//
|
|
options.ForwardDefaultSelector = context => {
|
|
//
|
|
var path = context.Request.Path.Value;
|
|
|
|
//
|
|
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
|
|
var fromQuery = TokenRetrieval.FromQueryString ();
|
|
var bearerToken = fromHeader (context.Request) ?? fromQuery (context.Request);
|
|
|
|
//
|
|
var result = XAuthenticationScheme.XToken.GetStringValue ();
|
|
if (!bearerToken.IsNull () && !bearerToken.Contains (".")) {
|
|
result = XAuthenticationScheme.XIntrospection.GetStringValue ();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
};
|
|
});
|
|
|
|
//
|
|
// Add OAuthIntrospect ...
|
|
builder.AddOAuth2Introspection (
|
|
XAuthenticationScheme.XIntrospection.GetStringValue (), options => {
|
|
//
|
|
options.Authority = config.Authority;
|
|
options.ClientId = config.ApiName;
|
|
options.ClientSecret = config.ClientSecret;
|
|
|
|
//
|
|
options.TokenRetriever = new Func<HttpRequest, string> (req => {
|
|
//
|
|
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
|
|
var fromQuery = TokenRetrieval.FromQueryString ();
|
|
|
|
//
|
|
var bearerToken = fromHeader (req) ?? fromQuery (req);
|
|
|
|
//
|
|
return bearerToken;
|
|
});
|
|
});
|
|
|
|
//
|
|
// Register Authorization Handler ...
|
|
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler> ();
|
|
Console.WriteLine ("IdentityService: register Authorization Handlers ...");
|
|
|
|
//
|
|
// Register Identity Provider ...
|
|
services.Add (new ServiceDescriptor (typeof (IXIdentityProvider), typeof (XIdentityProvider), lifeTime));
|
|
Console.WriteLine ("IdentityService: Register IdentityProvider ...");
|
|
|
|
//
|
|
// Try To Register InMemoryTokenProvier if it's not Provided ...
|
|
IXTokenProvider xTokenProvider = null;
|
|
try {
|
|
xTokenProvider = services.GetRegisteredService<IXTokenProvider> ();
|
|
} catch { }
|
|
if (xTokenProvider.IsNull ()) {
|
|
//
|
|
Console.WriteLine ("IdentityService: there is no Custom Token Provider, Adding InMemoryTokenProvider instead ...");
|
|
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (XInMemoryTokenProvider), lifeTime));
|
|
}
|
|
|
|
//
|
|
// Adding Security Provider ...
|
|
services.Add (new ServiceDescriptor (typeof (IXSecurityProvider), typeof (XSecurityProvider), lifeTime));
|
|
Console.WriteLine ("IdentityService: Register Security Provider ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\AuthorizationPolicyBuilderExtensions.cs
|
|
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
namespace xIdentityService.Extensions {
|
|
public static class AuthorizationPolicyBuilderExtensions {
|
|
/// <summary>
|
|
/// Adds a policy to check for required scopes.
|
|
/// </summary>
|
|
/// <param name="builder"></param>
|
|
/// <param name="scope">List of any required scopes. The token must contain at least one of the listed scopes.</param>
|
|
/// <returns></returns>
|
|
public static AuthorizationPolicyBuilder RequireScope (this AuthorizationPolicyBuilder builder, params string[] scope) {
|
|
return builder.RequireClaim (JwtClaimTypes.Scope, scope);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper for creating scope-related policies
|
|
/// </summary>
|
|
public static class ScopePolicy {
|
|
/// <summary>
|
|
/// Creates a policy to check for required scopes.
|
|
/// </summary>
|
|
/// <param name="scopes">List of any required scopes. The token must contain at least one of the listed scopes.</param>
|
|
/// <returns></returns>
|
|
public static AuthorizationPolicy Create (params string[] scopes) {
|
|
return new AuthorizationPolicyBuilder ()
|
|
.RequireScope (scopes)
|
|
.Build ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\HttpContextExtensions.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
|
|
namespace xIdentityService.Extensions {
|
|
public static class HttpContextExtensions {
|
|
/// <summary>
|
|
/// Retrieve Authentication Service ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <returns></returns>
|
|
public static IAuthenticationService GetAuthenticationService (this HttpContext context) {
|
|
//
|
|
var result = context.RequestServices
|
|
.GetRequiredService<IAuthenticationService> ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specific Token from HttpContext ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="tokenName"></param>
|
|
/// <param name="scheme"></param>
|
|
/// <returns></returns>
|
|
public static async Task<string> GetXTokenAsync (
|
|
this HttpContext context,
|
|
string tokenName,
|
|
XAuthenticationScheme scheme = XAuthenticationScheme.XToken
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokenName.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var authService = context.GetAuthenticationService ();
|
|
if (authService.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var authResult = await authService
|
|
.AuthenticateAsync (
|
|
context,
|
|
scheme
|
|
.GetStringValue ()
|
|
);
|
|
|
|
//
|
|
var result = authResult?.Properties?
|
|
.GetTokenValue (tokenName);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static async Task<string> GetAccessToken (this HttpContext context) {
|
|
//
|
|
var accessToken = context.Request.Headers[XAuthorization.Header]
|
|
.ToString ();
|
|
if (accessToken.IsNullOrEmpty ()) {
|
|
accessToken = await context
|
|
.GetTokenAsync (XAuthorization.AccessToken);
|
|
}
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier
|
|
.ToNormalString ())) {
|
|
accessToken = accessToken
|
|
.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
return accessToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Refresh Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static async Task<string> GetRefreshToken (this HttpContext context) {
|
|
//
|
|
var refreshToken = context.Request.Headers[XAuthorization.RefreshToken]
|
|
.ToString ();
|
|
if (refreshToken.IsNullOrEmpty ()) {
|
|
refreshToken = await context
|
|
.GetTokenAsync (XAuthorization.RefreshToken);
|
|
}
|
|
|
|
//
|
|
return refreshToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token Expiration Date
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static async Task<long> GetTokenExpiresAt (this HttpContext context) {
|
|
//
|
|
var expiresAtStr = context.Request.Headers[XAuthorization.ExpiresAt]
|
|
.ToString ();
|
|
if (expiresAtStr.IsNullOrEmpty ()) {
|
|
expiresAtStr = await context
|
|
.GetTokenAsync (XAuthorization.ExpiresAt);
|
|
}
|
|
|
|
//
|
|
var expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
return expiresAt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Required Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static async Task<XTokenResponse> RetrieveTokensAsXTokenResponse (HttpContext context) {
|
|
//
|
|
var accessToken = await GetAccessToken (context);
|
|
var refreshToken = await GetRefreshToken (context);
|
|
var expiresAt = await GetTokenExpiresAt (context);
|
|
|
|
//
|
|
return new XTokenResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\StreamExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xIdentityService.Extensions
|
|
{
|
|
public static partial class StreamExtensions
|
|
{
|
|
/// <summary>
|
|
/// Converts an Stream to Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="stream"></param>
|
|
/// <param name="bufferSize"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async IAsyncEnumerable<byte[]> ToAsyncEnumerable(
|
|
this Stream stream,
|
|
int bufferSize = 8192,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var buffer = new byte[bufferSize];
|
|
while (true)
|
|
{
|
|
//
|
|
int read = await stream
|
|
.ReadAsync(
|
|
buffer,
|
|
0,
|
|
buffer.Length,
|
|
cancellationToken
|
|
);
|
|
|
|
//
|
|
if (read == 0)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
yield return buffer.Take(read).ToArray();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an Stream to Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="stream"></param>
|
|
/// <param name="bufferSize"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(
|
|
this Stream stream,
|
|
int bufferSize = 8192,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var buffer = new byte[bufferSize];
|
|
while (true)
|
|
{
|
|
//
|
|
int read = await stream
|
|
.ReadAsync(
|
|
buffer,
|
|
0,
|
|
buffer.Length,
|
|
cancellationToken
|
|
);
|
|
if (read == 0)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
T chunk = default(T);
|
|
var readedBuffer = buffer.Take(read).ToArray();
|
|
var str = readedBuffer.FromBytes();
|
|
if (str.IsNullOrEmpty())
|
|
{
|
|
yield return chunk;
|
|
}
|
|
try
|
|
{
|
|
chunk = str.FromJSON<T>();
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
//
|
|
yield return chunk;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XModelExtensions.cs
|
|
|
|
using xIdentityModels.Dtos;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
public static XPersonDto ToXPersonDto(this XOpenActionUserInfoDto source)
|
|
{
|
|
//
|
|
var result = new XPersonDto
|
|
{
|
|
Avatar = source.Avatar,
|
|
Lastname = source.Lastname,
|
|
Username = source.Username,
|
|
Firstname = source.Firstname,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XTokenExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xExceptions.Models;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Interfaces;
|
|
|
|
public static partial class XTokenExtensions {
|
|
/// <summary>
|
|
/// Retrieve Tokens From Headers
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLoginResponse RetrieveTokens (this HttpRequest source) {
|
|
//
|
|
var accessToken = source.Headers[XAuthorization.Header].ToString ();
|
|
var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();
|
|
|
|
//
|
|
var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
return new XLoginResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From HttpContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XLoginResponse> RetrieveTokens (this HttpContext source) {
|
|
//
|
|
var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
|
|
var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
|
|
long expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var headerRequestTokens = source.Request.RetrieveTokens ();
|
|
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = accessToken ?? headerRequestTokens.AccessToken,
|
|
RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
|
|
ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From ActionExecutingContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static async Task<XLoginResponse> RetrieveTokens (this ActionExecutingContext source) {
|
|
//
|
|
var result = await source.HttpContext.RetrieveTokens ();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From XUserInfo instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = source.ExpiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Tokens From IHeader Dictionary
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLoginResponse RetrieveTokens (this IHeaderDictionary source) {
|
|
//
|
|
var accessToken = source[XAuthorization.Header].ToString () ?? "";
|
|
if (accessToken
|
|
.ToNormalString ()
|
|
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
|
|
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";
|
|
|
|
//
|
|
var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
|
|
var expiresAt = expiresAtStr.ConvertTo<long> ();
|
|
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve IXIdentityProvider from HttpContext
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IXIdentityProvider GetXApiIdentityProvider (this FilterContext source) {
|
|
//
|
|
var services = source.HttpContext.RequestServices;
|
|
return (IXIdentityProvider) services
|
|
.GetService (typeof (IXIdentityProvider));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate XLoginResponse instance based on TokenResponse
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
|
|
//
|
|
if (source.IsNull () ||
|
|
source.IsError) {
|
|
XException.InvalidToken.Throw ();
|
|
}
|
|
|
|
//
|
|
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds () +
|
|
source.ExpiresIn;
|
|
|
|
//
|
|
var result = new XLoginResponse {
|
|
AccessToken = source.AccessToken,
|
|
RefreshToken = source.RefreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (this IHeaderDictionary source, XLoginResponse model, string secret = null) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
|
|
//
|
|
if (!secret.IsNullOrEmpty ()) {
|
|
var revisionChecksum = model.GetRevisionChecksum (secret);
|
|
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific IHeaderDictionary instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (this HttpRequestHeaders source, XLoginResponse model) {
|
|
//
|
|
source.Remove (XAuthorization.Header);
|
|
source.Remove (XAuthorization.RefreshToken);
|
|
source.Remove (XAuthorization.ExpiresAt);
|
|
source.Remove (XAuthorization.RevisionChecksum);
|
|
|
|
//
|
|
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
|
|
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
|
|
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (this HttpRequest source, XLoginResponse model) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Authorization Tokens in Headers of
|
|
/// Specific HttpRequest instance
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (this HttpRequestMessage source, XLoginResponse model) {
|
|
source.Headers.SetXAuthenticationTokens (model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add ReNewed Authorization Tokens in Headers of
|
|
/// Specific Response.
|
|
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
|
|
/// header Value and Renew User Tokens based on it
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="model"></param>
|
|
public static void SetXAuthenticationTokens (this HttpResponse source, XLoginResponse model, string secret) {
|
|
source.Headers.SetXAuthenticationTokens (model, secret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Token Can Refrsh or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static bool IsRefreshable (this XLoginResponse source) {
|
|
//
|
|
var containsTokenData = !source.IsNull () &&
|
|
!source.AccessToken.IsNullOrEmpty () &&
|
|
!source.RefreshToken.IsNullOrEmpty ();
|
|
if (!containsTokenData) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var current = new DateTimeOffset (DateTime.UtcNow)
|
|
.ToUnixTimeSeconds ();
|
|
|
|
//
|
|
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (this XLoginResponse source, string secret) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a Revision Checksum for new Tokens
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static string GetRevisionChecksum (this XTokenResponse source, string secret) {
|
|
return (source.AccessToken +
|
|
secret +
|
|
source.RefreshToken +
|
|
secret +
|
|
source.ExpiresAt.ToString ()
|
|
)
|
|
.ToMd5String ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XLoginResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (this XLoginResponse source, string checksum, string secret) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an XTokenResponse instance is Valid with it's revision
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="checksum"></param>
|
|
/// <param name="secret"></param>
|
|
/// <returns></returns>
|
|
public static bool ValidateRevisionChecksum (this XTokenResponse source, string checksum, string secret) {
|
|
//
|
|
var xChecksum = source.GetRevisionChecksum (secret);
|
|
return checksum == xChecksum;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Exception Details if Fails
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Exception GetException (this TokenResponse source) {
|
|
//
|
|
// Validate Args ...
|
|
if (source.IsNull () || !source.IsError) {
|
|
return XException.ActionFailed.ToException ();
|
|
}
|
|
|
|
//
|
|
XError error = source.ErrorDescription.FromJSON<XError> ();
|
|
return error.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert XTokenResponse to Header Dictionary
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IDictionary<string, string> ToHeaderDictionary (this XTokenResponse source) {
|
|
//
|
|
var result = new Dictionary<string, string> { { XAuthorization.RefreshToken, source.RefreshToken },
|
|
{ XAuthorization.ExpiresAt, source.ExpiresAt.ToString () }
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XUserClaimsInfoDtoExtensions.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityService.Extensions {
|
|
public static class XUserClaimsInfoDtoExtensions {
|
|
public static string GetUserSelectByParam (
|
|
this XUserClaimsInfoDto source,
|
|
XUserSelectBy userSelectBy = XUserSelectBy.Username
|
|
) {
|
|
//
|
|
var result = "";
|
|
|
|
//
|
|
switch (userSelectBy) {
|
|
//
|
|
case XUserSelectBy.ID:
|
|
result = source.UserId;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.Username:
|
|
result = source.UserName;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.Email:
|
|
result = source.Email;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.MobileNumber:
|
|
result = source.PhoneNumber;
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (result.IsNullOrEmpty ()) {
|
|
//
|
|
if (!source.UserId.IsNullOrEmpty ()) {
|
|
result = source.UserId;
|
|
} else if (!source.UserName.IsNullOrEmpty ()) {
|
|
result = source.UserName;
|
|
} else if (!source.Email.IsNullOrEmpty ()) {
|
|
result = source.Email;
|
|
} else if (!source.PhoneNumber.IsNullOrEmpty ()) {
|
|
result = source.PhoneNumber;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseIdentityHttpProvider.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using RestSharp;
|
|
using xCommons.Providers;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Models;
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an interface for Identity Provided Http Based Services ...
|
|
/// </summary>
|
|
public interface IXBaseIdentityHttpProvider
|
|
{
|
|
/// <summary>
|
|
/// Client Base Url ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
string BaseUrl { get; }
|
|
|
|
/// <summary>
|
|
/// Logger ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
ILogger Logger { get; }
|
|
|
|
/// <summary>
|
|
/// Powered Value ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
string XPoweredValue { get; }
|
|
|
|
/// <summary>
|
|
/// Default Client Timeout ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
int DefaultClientTimeout { get; }
|
|
|
|
/// <summary>
|
|
/// Default Buffering Chunk Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
int DefaultBufferingChunckSize { get; }
|
|
|
|
/// <summary>
|
|
/// Validation Provider ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
XValidationProvider ValidationProvider { get; }
|
|
|
|
/// <summary>
|
|
/// Get an Instance of Http Client
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
HttpClient GetHttpClient(XTokenResponse tokens = null);
|
|
HttpClient GetHttpClient(XUserClaimsInfoDto userInfo = null);
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestClient
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
RestClient GetRestClient(XTokenResponse tokens = null);
|
|
RestClient GetRestClient(XUserClaimsInfoDto userInfo = null);
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestRequest
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="addXPoweredValue"></param>
|
|
/// <param name=""></param>
|
|
/// <param name="headers"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
RestRequest GetRestRequet(
|
|
Enum endpoint,
|
|
bool addXPoweredValue = true,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Handle Call Specific Request and retrieve Response
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="supportRefreshingTokens"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
Task<T> RunRestRequest<T>(
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Access a Get Request Stream as AsyncEnumerable ...
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="bufferLength"></param>
|
|
/// <param name="addXPoweredValue"></param>
|
|
/// <param name="tokens"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="headers"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
Task<Stream> StreamData(
|
|
Enum endpoint,
|
|
int bufferLength = 8194,
|
|
bool addXPoweredValue = true,
|
|
XTokenResponse tokens = null,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Handle Call Specified Request and Retrieve XBaseRestResponse<T> ...
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="supportRefreshingTokens"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns>an instance of XBaseRestResponse<T></returns>
|
|
Task<XBaseRestResponse<T>> RunRestRequestByResponse<T>(
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get User SelectBy Param
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Converts UserInfo to TokenResponse model ...
|
|
/// </summary>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
XTokenResponse ToTokenResponse(XUserClaimsInfoDto userInfo = null);
|
|
|
|
/// <summary>
|
|
/// Prepare Url Address of Specified Enum by Filling Params
|
|
/// and Query Strings Attach ...
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="attachBaseUrl"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
string PrepareUrl(
|
|
Enum endpoint,
|
|
bool attachBaseUrl = false,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Prepare Url Address by Filling Params
|
|
/// and Query Strings Attach ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="attachBaseUrl"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
string PrepareUrl(
|
|
string url,
|
|
bool attachBaseUrl = false,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferenced.cs
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Models;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Referenced Service is a Service which can Referenced to other Items ...
|
|
/// </summary>
|
|
public interface IXBaseReferenced<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Get Reference Identifier for Specified Provider and Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <returns></returns>
|
|
string GetIdentifier<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Specified Item has Refernce to Provider ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsProvidedFor<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Specified Reference to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddReference<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
TKey id,
|
|
int forIndex = 0,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Reference from Specified Item ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveReference<TReferenceKey>(
|
|
string providedFor,
|
|
TReferenceKey forProvidedId,
|
|
TKey id,
|
|
int forIndex = 0,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get Specified References ...
|
|
/// </summary>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="TReferenceKey"></typeparam>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XReference<string>>> GetReferences(
|
|
string providedFor,
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferencedController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xDataService.Models;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
public interface IXBaseReferencedController<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Check an Item Has Reference to Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/Reference/IsProvidedFor")]
|
|
Task<ActionResult<bool>> IsProvidedFor(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add a Reference to Item for Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/Reference")]
|
|
Task<ActionResult> AddReference(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
[FromQuery] int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove a Reference from Item for Specified ProvideFor and Specified forProvidedId ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="forProvidedId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}/Reference")]
|
|
Task<ActionResult> RemoveReference(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] string providedFor,
|
|
[FromQuery] object forProvidedId,
|
|
[FromQuery] int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specified Itemfor providedFor ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="providedFor"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/References")]
|
|
Task<ActionResult<IEnumerable<XReference<string>>>> GetReferences(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] string providedFor,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityBaseReferencedProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Models;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// in Some Cases we have Entities Which Can Referenced for Specified
|
|
/// Provider and Types ...
|
|
/// this interface Globaly introduce all available Actions for those ...
|
|
///
|
|
/// TKey: type of Provider Models Keys ...
|
|
/// TModel: type of Dto which Referenced ...
|
|
/// </summary>
|
|
public interface IXIdentityBaseReferencedProvider<TModel, TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Provider Identifier ...
|
|
/// </summary>
|
|
string Provider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <returns></returns>
|
|
Task<TModel> GetReference(
|
|
TKey providedForId,
|
|
int forIndex = 0
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TModel>> GetAllReferences(TKey providedForId);
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XReference<TKey>>> GetAllReferencings(TKey providedForId);
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountReferences(TKey providedForId);
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TModel>> QueryReferences(
|
|
XQuery query,
|
|
TKey providedForId
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
TModel model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
TModel model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
TModel model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
TModel model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReferences(
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Http;
|
|
using RestSharp;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
public partial interface IXIdentityProvider
|
|
{
|
|
//
|
|
string BaseUrl { get; }
|
|
string RevisionSecretKey { get; }
|
|
IXSecurityProvider SecurityProvider { get; }
|
|
|
|
//
|
|
#region Tools ...
|
|
string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
Task<T> RunRestRequest<T>(
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = false
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Authentication ...
|
|
Task<DiscoveryDocumentResponse> RequestDiscoveryDocument();
|
|
Task<XTokenResponse> RequestScopeAccessToken(string scope);
|
|
Task<TokenIntrospectionResponse> Introspection(XTokenResponse model);
|
|
Task<XLoginResponse> Login(XLoginRequest model);
|
|
Task Logout(XTokenResponse model);
|
|
Task<XTokenResponse> Authenticate(XLoginRequest model);
|
|
Task<XTokenResponse> RefreshTokens(XTokenResponse model);
|
|
|
|
Task ChangePassword(
|
|
XTokenResponse tokens,
|
|
XActionRequest model
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Profile ...
|
|
Task<IEnumerable<string>> GetUserNames(
|
|
XTokenResponse tokens,
|
|
string userIds
|
|
);
|
|
|
|
Task<IEnumerable<XUserNameIdResponse>> GetUserNameIds(
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<XUserProfileDto> GetUserProfile(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
);
|
|
|
|
Task<XQueryResult<XUserProfileDto>> QueryUsers(
|
|
XTokenResponse tokens,
|
|
XQuery query
|
|
);
|
|
|
|
Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
|
|
XTokenResponse tokens,
|
|
string role,
|
|
XQuery query,
|
|
bool forceRole = false
|
|
);
|
|
|
|
Task<XQueryResult<XProfileImage>> QueryAvatars(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XQuery query
|
|
);
|
|
|
|
Task<XUserProfileDto> ProfileUpdateAsync(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XProfileUpdateRequest model
|
|
);
|
|
|
|
Task<XUserProfileDto> FullProfileUpdateAsync(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XProfileUpdateRequest request
|
|
);
|
|
|
|
Task<XUserProfileDto> AddAvatar(
|
|
XTokenResponse tokens,
|
|
IFormFile file
|
|
);
|
|
|
|
Task<XUserProfileDto> AddAvatars(
|
|
XTokenResponse tokens,
|
|
IFormFileCollection files
|
|
);
|
|
|
|
Task<XUserProfileDto> SetAvatar(
|
|
XTokenResponse tokens,
|
|
int avatarId
|
|
);
|
|
|
|
Task<XUserProfileDto> RemoveAvatars(
|
|
XTokenResponse tokens,
|
|
string avatarIds
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Search ...
|
|
/// <summary>
|
|
/// Query Open To Search User Profiles ...
|
|
/// </summary>
|
|
/// <param name="tokens">requested user's identifiers</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
|
|
XTokenResponse tokens,
|
|
XQuery query
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Registration ...
|
|
Task<bool> CanRegister(string userSelectByParam);
|
|
|
|
Task<XActionResponse> InviteUser(
|
|
XTokenResponse tokens,
|
|
XActionRequest model
|
|
);
|
|
|
|
Task<XActionResponse> RequestRegistration(
|
|
XActionRequest model
|
|
);
|
|
|
|
Task<XActionResponse> AddAccountInfo(
|
|
XActionRequest model
|
|
);
|
|
|
|
Task<XActionResponse> AttachProfileImage(
|
|
string actionToken,
|
|
IFormFile file
|
|
);
|
|
|
|
Task FinishRegistration(XActionRequest model);
|
|
|
|
Task<bool> IsConfirmedEmail(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
);
|
|
|
|
Task<bool> IsConfirmedMobile(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
);
|
|
|
|
Task RequestConfirmRegistration(XActionRequest model);
|
|
|
|
Task ConfirmRegistration(
|
|
XActionRequest model
|
|
);
|
|
|
|
Task<XActionResponse> RequestConfirmMobile(XActionRequest model);
|
|
|
|
Task<XActionResponse> ConfirmMobileNumber(XActionRequest model);
|
|
|
|
Task<XActionResponse> RequestConfirmEmail(XActionRequest model);
|
|
|
|
Task<XActionResponse> ConfirmEmailAddress(XActionRequest model);
|
|
|
|
Task<XActionResponse> RequestResetPassword(XActionRequest model);
|
|
|
|
Task ResetPassword(XActionRequest model);
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship ...
|
|
Task<XFriendshipFollowing> Follow(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<bool> Cancel(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task UnFollowFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task UnFollowFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollowing> Block(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollowing> UnBlock(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollower> AcceptRequest(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollower> RejectRequest(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipInfoDto> GetFriendshipInfo(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<bool> IsFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollower> GetFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipState> GetFollowerState(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<IEnumerable<XFriendshipFollower>> GetFollowers(XTokenResponse tokens);
|
|
|
|
Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(XTokenResponse tokens);
|
|
|
|
Task<IEnumerable<string>> GetFollowingList(XTokenResponse tokens);
|
|
|
|
Task<XQueryResult<XFriendDto>> QueryFollowers(
|
|
XQuery query,
|
|
string destUser,
|
|
XTokenResponse tokens
|
|
);
|
|
|
|
Task<bool> IsFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipFollowing> GetFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<XFriendshipState> GetFollowingState(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
);
|
|
|
|
Task<IEnumerable<XFriendshipFollowing>> GetFollowings(XTokenResponse tokens);
|
|
|
|
Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(XTokenResponse tokens);
|
|
|
|
Task<IEnumerable<string>> GetFollowersList(XTokenResponse tokens);
|
|
|
|
Task<XQueryResult<XFriendDto>> QueryFollowings(
|
|
XQuery query,
|
|
string destUser,
|
|
XTokenResponse tokens
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Admin ...
|
|
Task<IEnumerable<string>> Ban(
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<IEnumerable<string>> UnBan(
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<bool> IsBanned(
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Open Actions ...
|
|
//
|
|
XDeviceDto GetDevice();
|
|
|
|
//
|
|
Task<XOpenActionInnerDto> OpenGet(
|
|
XOpenActionInnerDto model
|
|
);
|
|
|
|
//
|
|
Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XDeviceDto device,
|
|
string userSelectByParam
|
|
);
|
|
Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XOpenActionInnerDto dto
|
|
);
|
|
Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
string token,
|
|
string request
|
|
);
|
|
|
|
//
|
|
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XDeviceDto device,
|
|
string ids
|
|
);
|
|
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XOpenActionInnerDto dto
|
|
);
|
|
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
string token,
|
|
string request
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXProxyHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using xIdentityService.Configuration;
|
|
|
|
namespace xIdentityService.Interfaces {
|
|
public interface IXProxyHelper {
|
|
/// <summary>
|
|
/// Proxy Configuration ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
XProxyConfiguration Configuration { get; }
|
|
|
|
/// <summary>
|
|
/// retrie Normalize Host ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
string NormalizeHost ();
|
|
|
|
/// <summary>
|
|
/// Validate XProxy Configuration for Client ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
bool ValidateConfiguration ();
|
|
|
|
/// <summary>
|
|
/// Retrieve all Prepared url of Routes ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
IEnumerable<string> GetRouteUrls ();
|
|
|
|
/// <summary>
|
|
/// retrieve all registred Routes ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
IEnumerable<XProxyRouteDescriptor> GetRoutes ();
|
|
|
|
/// <summary>
|
|
/// Prepare a request url for a Proxy Route ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="descriptor"></param>
|
|
/// <returns></returns>
|
|
string PrepareActionUrlForXProxyRoute (
|
|
string url,
|
|
XProxyRouteDescriptor descriptor
|
|
);
|
|
|
|
/// <summary>
|
|
/// Prepare a request url for a Selected Proxy Route ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="whereClause"></param>
|
|
/// <returns></returns>
|
|
string PrepareActionUrlForXProxyRoute (
|
|
string url,
|
|
Expression<Func<XProxyRouteDescriptor, bool>> whereClause
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find an Specific Route ...
|
|
/// </summary>
|
|
/// <param name="whereClause"></param>
|
|
/// <returns></returns>
|
|
XProxyRouteDescriptor FindRoute (Expression<Func<XProxyRouteDescriptor, bool>> whereClause);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXSecurityProvider.cs
|
|
|
|
namespace xIdentityService.Interfaces
|
|
{
|
|
public partial interface IXSecurityProvider
|
|
{
|
|
string Encrypt(string plainText);
|
|
string Decrypt(string cipherText);
|
|
string EncryptFromBytes(byte[] textBytes);
|
|
string DecryptFromBytes(byte[] cipherBytes);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXTokenProvider.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIdentityService.Interfaces {
|
|
public partial interface IXTokenProvider {
|
|
Task<bool> IsTokenExists (string accessToken);
|
|
Task<bool> IsTokenExists (XTokenResponse tokens);
|
|
Task<bool> RemoveToken (string accessToken);
|
|
Task<bool> RemoveToken (XTokenResponse tokens);
|
|
Task<XTokenResponse> RetrieveToken (string accessToken);
|
|
Task<bool> AddToken (XTokenResponse tokens);
|
|
Task<bool> UpdateToken (XTokenResponse tokens);
|
|
Task<bool> AddOrUpdateToken (XTokenResponse tokens);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XIdentityTokenRefresher.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Middlewares {
|
|
public partial class XIdentityTokenRefresherMiddleware {
|
|
//
|
|
#region Properties ...
|
|
private readonly ILogger logger;
|
|
private readonly RequestDelegate next;
|
|
private readonly IXTokenProvider tokenProvider;
|
|
private readonly IXIdentityProvider identityProvider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XIdentityTokenRefresherMiddleware (
|
|
RequestDelegate next,
|
|
ILoggerFactory loggerFactory,
|
|
IXTokenProvider tokenProvider,
|
|
IXIdentityProvider identityProvider
|
|
) {
|
|
//
|
|
this.next = next;
|
|
this.tokenProvider = tokenProvider;
|
|
this.identityProvider = identityProvider;
|
|
this.logger = loggerFactory
|
|
.CreateLogger<XIdentityTokenRefresherMiddleware> ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
public async Task Invoke (HttpContext context) {
|
|
//
|
|
// Handle Request ...
|
|
await HandleRequest (context);
|
|
|
|
//
|
|
// Do Main Task ...
|
|
try {
|
|
await next.Invoke (context);
|
|
} catch (Exception ex) {
|
|
logger.LogError ($"Error: {ex.Message}");
|
|
}
|
|
|
|
//
|
|
// Handle Response ...
|
|
await HandleResponse (context);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private async Task HandleRequest (HttpContext context) {
|
|
//
|
|
// Log ...
|
|
logger.LogInformation ($"Start Process Request ...");
|
|
|
|
//
|
|
// Check Access Token ...
|
|
var hasAccessToken = HasAccessToken (context);
|
|
if (!hasAccessToken) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check Access Token ...
|
|
var accessToken = GetAccessToken (context);
|
|
var isExists = await tokenProvider
|
|
.IsTokenExists (accessToken);
|
|
if (!isExists) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Try Check is Refreshable ...
|
|
var tokens = await tokenProvider
|
|
.RetrieveToken (accessToken);
|
|
if (tokens.IsNull ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check is Expired or Refreshable ...
|
|
var isRefreshable = tokens.IsRefreshable ();
|
|
if (!isRefreshable) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Refresh Token ...
|
|
var refreshedTokens = await identityProvider
|
|
.RefreshTokens (tokens);
|
|
if (refreshedTokens.IsNull ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Set Refreshed AccessToken to Request ...
|
|
context
|
|
.Request
|
|
.Headers[XAuthorization.Header] =
|
|
$"{XAuthorization.TokenIdentifier}{refreshedTokens.AccessToken}";
|
|
}
|
|
|
|
private async Task HandleResponse (HttpContext context) {
|
|
//
|
|
// Log ...
|
|
logger.LogInformation ($"Start Process Response ...");
|
|
|
|
//
|
|
await Task.Run (() => { });
|
|
}
|
|
|
|
private bool HasAccessToken (HttpContext context) {
|
|
//
|
|
// Check Headers ...
|
|
if (context.IsNull () ||
|
|
context.Request.IsNull () ||
|
|
context.Request.Headers.IsNull ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = context
|
|
.Request
|
|
.Headers
|
|
.ContainsKey (
|
|
XAuthorization.Header
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private string GetAccessToken (HttpContext context) {
|
|
//
|
|
var hasAccessToken = HasAccessToken (context);
|
|
if (!hasAccessToken) {
|
|
return string.Empty;
|
|
}
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = context
|
|
.Request
|
|
.Headers[
|
|
XAuthorization.Header
|
|
];
|
|
result = result
|
|
.ToString ()
|
|
.Replace (
|
|
XAuthorization.TokenIdentifier,
|
|
""
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provide all DI Requirements for XIdentityTokenRefresher Middleware
|
|
/// </summary>
|
|
public static class XIdentityTokenRefresherDIHelper {
|
|
/// <summary>
|
|
/// Use XTokenValidator Middleware
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXIdentityTokenRefresher (this IApplicationBuilder app) {
|
|
app.UseMiddleware<XIdentityTokenRefresherMiddleware> ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XProxyMiddleware.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.WebUtilities;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Providers;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityService.Middlewares {
|
|
/// <summary>
|
|
/// Proxy Server Middleware ...
|
|
/// </summary>
|
|
public class XProxyMiddleware : XBaseClass {
|
|
//
|
|
#region Pros ...
|
|
private readonly HttpClient HTTP_CLIENT;
|
|
private readonly RequestDelegate NEXT_MIDDLEWARE;
|
|
private readonly XProxyConfiguration CONFIGURATION;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XProxyMiddleware (
|
|
ILoggerFactory loggerFactory,
|
|
RequestDelegate nextMiddleware,
|
|
XProxyConfiguration configuration,
|
|
IHttpClientFactory httpClientFactory
|
|
) : base (loggerFactory) {
|
|
//
|
|
this.CONFIGURATION = configuration;
|
|
this.NEXT_MIDDLEWARE = nextMiddleware;
|
|
|
|
//
|
|
// Create Http Client ...
|
|
this.HTTP_CLIENT = httpClientFactory
|
|
.CreateClient (XProxyConstants.XPROXY_HTTP_CLIENT);
|
|
|
|
//
|
|
// Logging Server Configuration ...
|
|
LogXProxyServerConfig ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Public ...
|
|
public async Task InvokeAsync (HttpContext context) {
|
|
//
|
|
#region Bussiness Logic ...
|
|
//
|
|
var routeDescriptor = GetRouteDescriptor (context.Request);
|
|
if (!routeDescriptor.IsNull ()) {
|
|
//
|
|
#region Handle Authorization ...
|
|
//
|
|
try {
|
|
//
|
|
// Handle XPowered ...
|
|
if (routeDescriptor.EnableXPoweredByAthorization) {
|
|
//
|
|
var isPoweredByPass = context.Request.Headers
|
|
.Any (h => h.Key
|
|
.ToNormalString () == xCommons.Constants.XAuthorization.XPoweredBy
|
|
.ToNormalString () &&
|
|
h.Value
|
|
.ToString ()
|
|
.ToNormalString () == CONFIGURATION.XPoweredValue
|
|
.ToNormalString ()
|
|
);
|
|
|
|
//
|
|
if (!isPoweredByPass) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle EndableAuthorization ...
|
|
if (routeDescriptor.EnableAuthorization) {
|
|
//
|
|
// Retrieve User Info for Authentication ...
|
|
var userName = context.User.Identity.Name;
|
|
var isUserAuthenticated = !userName.IsNull () &&
|
|
context.User.Identity.IsAuthenticated;
|
|
if (!isUserAuthenticated &&
|
|
!routeDescriptor.AllowedScopes.HasChild ()
|
|
) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
|
|
//
|
|
// Check Allowed Scopes Authorization ...
|
|
if (routeDescriptor.AllowedScopes.HasChild ()) {
|
|
//
|
|
var scopeClaims = context.User.Claims
|
|
.Where (c => c.Type == JwtClaimTypes.Scope)
|
|
.Select (c => c.Value);
|
|
var isScopePassed = scopeClaims.HasChild () &&
|
|
scopeClaims.Any (c => routeDescriptor.AllowedScopes
|
|
.Any (allowedScope => allowedScope
|
|
.ToNormalString () == c
|
|
.ToNormalString ()
|
|
)
|
|
);
|
|
if (!isScopePassed) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Allowed Roles Authorization ...
|
|
if (
|
|
isUserAuthenticated &&
|
|
routeDescriptor.AllowedRoles.HasChild ()
|
|
) {
|
|
//
|
|
var roleClaim = context.User.Claims
|
|
.FirstOrDefault (c => c.Type == JwtClaimTypes.Role);
|
|
var isRolePassed = !roleClaim.IsNull () &&
|
|
routeDescriptor.AllowedRoles
|
|
.Any (role => role
|
|
.ToNormalString () == roleClaim.Value
|
|
.ToNormalString ());
|
|
if (!isRolePassed) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
|
|
return;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Extract Request Uri from Received Request ...
|
|
var requestUri = GetUri (context.Request);
|
|
if (!requestUri.IsNull ()) {
|
|
//
|
|
// Retrieve Request based on current ...
|
|
var request = GetRequestMessage (
|
|
uri: requestUri,
|
|
context: context
|
|
);
|
|
|
|
//
|
|
SendLog ($"Send Request to Recieve Response ...", LogLevel.Information);
|
|
|
|
//
|
|
// Send Request and Retrieve Response ...
|
|
try {
|
|
//
|
|
var response = await HTTP_CLIENT.SendAsync (
|
|
request,
|
|
HttpCompletionOption.ResponseContentRead
|
|
);
|
|
|
|
//
|
|
// Set Current Response Status Code ...
|
|
context.Response.StatusCode = (int) response.StatusCode;
|
|
|
|
//
|
|
// Retrieve Response Headers and Set To Current Response ...
|
|
HandleResponseHeaders (context, response);
|
|
|
|
//
|
|
// Processing Response Content ...
|
|
await ProcessResponseContent (context, response);
|
|
} catch (Exception ex) {
|
|
//
|
|
LogMessage ($"Exception: {ex.Message}", LogLevel.Error);
|
|
|
|
//
|
|
context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
|
|
}
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
await NEXT_MIDDLEWARE (context);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Throw Required Exception ...
|
|
/// </summary>
|
|
private void ThrowNotAuthorizedException () {
|
|
throw XException.NotAuthorized.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show propper logs if Enabled ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="logLevel"></param>
|
|
private void SendLog (string message, LogLevel logLevel = LogLevel.Information) {
|
|
//
|
|
if (!CONFIGURATION.EnableLogging) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
LogMessage (
|
|
message: message,
|
|
logLevel: logLevel
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Log Proxy Server Configuration ...
|
|
/// </summary>
|
|
private void LogXProxyServerConfig () {
|
|
//
|
|
// Retrieve XProxyConfiguration class from Configurations and Validate them ...
|
|
if (CONFIGURATION.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Try to Log Proxy Configuration ...
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ("= Proxy Server Configurations: ");
|
|
ConsoleMessage ("===============================");
|
|
|
|
//
|
|
ConsoleMessage ($"Host: {CONFIGURATION.Host}");
|
|
ConsoleMessage ($"XPoweredValue: {CONFIGURATION.XPoweredValue}");
|
|
ConsoleMessage ($"EnableLogging: {CONFIGURATION.EnableLogging}");
|
|
ConsoleMessage ($"DisableSSLCheck: {CONFIGURATION.DisableSSLCheck}");
|
|
ConsoleMessage ($"AllowAutoRedirect: {CONFIGURATION.AllowAutoRedirect}");
|
|
ConsoleMessage ($" ");
|
|
ConsoleMessage ($"Routes: ");
|
|
ConsoleMessage ($" ");
|
|
|
|
//
|
|
CONFIGURATION.Routes
|
|
.ToList ()
|
|
.ForEach (routeDescriptor => {
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ($"= Rote => {routeDescriptor.Route}");
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ($"AllowedRoles: {routeDescriptor.AllowedRoles.ToJSON()}");
|
|
ConsoleMessage ($"AllowedScopes: {routeDescriptor.AllowedScopes.ToJSON()}");
|
|
ConsoleMessage ($"EnableAuthorization: {routeDescriptor.EnableAuthorization}");
|
|
ConsoleMessage ($"EnableXPoweredByAthorization: {routeDescriptor.EnableXPoweredByAthorization}");
|
|
ConsoleMessage ($" ");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Destination Request Path based on Current Request ...
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
private Uri GetUri (HttpRequest request) {
|
|
//
|
|
// Create temp result ...
|
|
Uri result = null;
|
|
var requestPath = "";
|
|
|
|
//
|
|
SendLog ($"Receive Request: {request.Path} ...", LogLevel.Information);
|
|
|
|
//
|
|
// Try to Findout Route Descriptor ...
|
|
var routeDescriptor = GetRouteDescriptor (request);
|
|
|
|
//
|
|
// Route Descriptor Exists && Path for Delegating ...
|
|
if (!routeDescriptor.IsNull () &&
|
|
request.Path
|
|
.StartsWithSegments (routeDescriptor.Route)
|
|
) {
|
|
//
|
|
// Prepare Request Path by Cleaning Starter Path Segment ...
|
|
requestPath = request.Path
|
|
.ToString ()
|
|
.Replace (routeDescriptor.Route, "");
|
|
if (requestPath.StartsWith ("/")) {
|
|
requestPath = requestPath.Substring (1);
|
|
}
|
|
|
|
//
|
|
// Decoding URL ...
|
|
requestPath = HttpUtility.UrlDecode (requestPath);
|
|
|
|
//
|
|
var colonIndex = requestPath.IndexOf (":");
|
|
if (colonIndex > -1) {
|
|
//
|
|
var doubleSlash = requestPath.Substring (colonIndex + 1, 2);
|
|
var isDoubleSlash = doubleSlash == "//";
|
|
|
|
//
|
|
if (!isDoubleSlash) {
|
|
//
|
|
var protocol = requestPath
|
|
.Substring (0, colonIndex);
|
|
var section = requestPath
|
|
.Substring (colonIndex + 2, requestPath.Length - colonIndex - 2);
|
|
|
|
//
|
|
requestPath = $"{protocol}://{section}";
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Request Path ...
|
|
if (!requestPath.IsNullOrEmpty ()) {
|
|
//
|
|
result = new Uri (requestPath);
|
|
|
|
//
|
|
SendLog ($"Process Request: {requestPath} ...", LogLevel.Information);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Propper Request Message based on HttpContext and uri ...F
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="uri"></param>
|
|
/// <returns></returns>
|
|
private HttpRequestMessage GetRequestMessage (
|
|
HttpContext context,
|
|
Uri uri
|
|
) {
|
|
//
|
|
var result = new HttpRequestMessage ();
|
|
FillRequest (context, result);
|
|
|
|
//
|
|
// Handle Queries ...
|
|
SendLog ($"Start Processing Queries: ");
|
|
foreach (var query in context.Request.Query) {
|
|
//
|
|
var key = query.Key;
|
|
var value = HttpUtility.UrlDecode (query.Value);
|
|
|
|
//
|
|
uri = new Uri (
|
|
QueryHelpers.AddQueryString (
|
|
uri.OriginalString,
|
|
new Dictionary<string, string> {
|
|
[key] = value
|
|
}
|
|
)
|
|
);
|
|
|
|
//
|
|
SendLog ($"Query : {key}:{value} was Processed ...");
|
|
}
|
|
|
|
//
|
|
result.RequestUri = uri;
|
|
result.Headers.Host = uri.Host;
|
|
|
|
//
|
|
// Retrieve Request Method ...
|
|
result.Method = GetMethod (context.Request.Method);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fill Request Message by provide HttpContext ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="message"></param>
|
|
private void FillRequest (
|
|
HttpContext context,
|
|
HttpRequestMessage message
|
|
) {
|
|
//
|
|
var requestMethod = context.Request.Method;
|
|
|
|
//
|
|
if (!HttpMethods.IsGet (requestMethod) &&
|
|
!HttpMethods.IsHead (requestMethod) &&
|
|
!HttpMethods.IsTrace (requestMethod) &&
|
|
!HttpMethods.IsDelete (requestMethod)
|
|
) {
|
|
//
|
|
var streamContent = new StreamContent (context.Request.Body);
|
|
message.Content = streamContent;
|
|
}
|
|
|
|
//
|
|
// Handle Base Headers ...
|
|
var regularHeaders = context.Request.Headers
|
|
.Where (hr => hr.Key != XProxyConstants.XPROXY_ACCEPTED_HEADERS &&
|
|
!hr.Key
|
|
.Contains (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER
|
|
)
|
|
);
|
|
|
|
//
|
|
// Handle Aceepted Headers ...
|
|
IEnumerable<string> acceptedHeaders = null;
|
|
var acceptedHeadersKeyValue = context.Request.Headers
|
|
.FirstOrDefault (hr =>
|
|
hr.Key == XProxyConstants.XPROXY_ACCEPTED_HEADERS
|
|
);
|
|
if (!acceptedHeadersKeyValue.IsNull ()) {
|
|
//
|
|
acceptedHeaders = acceptedHeadersKeyValue.Value
|
|
.ToString ()
|
|
.ParseListString<string> ();
|
|
|
|
//
|
|
// Filter Regular Headers ...
|
|
if (
|
|
regularHeaders.HasChild () &&
|
|
acceptedHeaders.HasChild ()
|
|
) {
|
|
//
|
|
regularHeaders = regularHeaders
|
|
.Where (rhr => acceptedHeaders
|
|
.Contains (rhr.Key)
|
|
);
|
|
}
|
|
}
|
|
foreach (var header in regularHeaders) {
|
|
//
|
|
SendLog ($"Adding Header: {header.Key}:{header.Value} ...");
|
|
|
|
//
|
|
message.Headers.Add (
|
|
header.Key,
|
|
header.Value
|
|
.ToString ()
|
|
);
|
|
}
|
|
|
|
//
|
|
// Handle ForWarded Headers ...
|
|
// Since Forward Headers is Custom kind, this means user actually need this
|
|
// Header, so there is no need to put them on AcceptedHeaders ...
|
|
var forwardHeaders = context.Request.Headers
|
|
.Where (hr => hr.Key
|
|
.Contains (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER
|
|
)
|
|
);
|
|
foreach (var header in forwardHeaders) {
|
|
//
|
|
var key = header.Key
|
|
.Replace (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER,
|
|
string.Empty
|
|
);
|
|
|
|
//
|
|
SendLog ($"Forwarding Header: {header.Key} to {key} ...");
|
|
|
|
//
|
|
message.Headers
|
|
.Add (
|
|
key,
|
|
header.Value
|
|
.ToString ()
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retreive and Extract Method Type of HttpRequest ...
|
|
/// </summary>
|
|
/// <param name="method"></param>
|
|
/// <returns></returns>
|
|
private static HttpMethod GetMethod (string method) {
|
|
//
|
|
if (HttpMethods.IsDelete (method)) {
|
|
return HttpMethod.Delete;
|
|
} else if (HttpMethods.IsGet (method)) {
|
|
return HttpMethod.Get;
|
|
} else if (HttpMethods.IsHead (method)) {
|
|
return HttpMethod.Head;
|
|
} else if (HttpMethods.IsOptions (method)) {
|
|
return HttpMethod.Options;
|
|
} else if (HttpMethods.IsPost (method)) {
|
|
return HttpMethod.Post;
|
|
} else if (HttpMethods.IsPut (method)) {
|
|
return HttpMethod.Put;
|
|
} else if (HttpMethods.IsTrace (method)) {
|
|
return HttpMethod.Trace;
|
|
}
|
|
|
|
//
|
|
return new HttpMethod (method);
|
|
}
|
|
|
|
/// <summary>
|
|
/// add all headers exists in HttpResponse MEssage to Current Context Response Headers ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="message"></param>
|
|
private void HandleResponseHeaders (
|
|
HttpContext context,
|
|
HttpResponseMessage message
|
|
) {
|
|
//
|
|
// Handle Message Headers ...
|
|
foreach (var header in message.Headers) {
|
|
context.Response.Headers[header.Key] = header.Value
|
|
.ToArray ();
|
|
}
|
|
|
|
//
|
|
// Handle Message Content Headers ...
|
|
foreach (var header in message.Content.Headers) {
|
|
context.Response.Headers[header.Key] = header.Value
|
|
.ToArray ();
|
|
}
|
|
|
|
//
|
|
context.Response.Headers.Remove ("transfer-encoding");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing Response Content and Handle it on HttpContextResponse ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
private async Task ProcessResponseContent (
|
|
HttpContext context,
|
|
HttpResponseMessage message
|
|
) {
|
|
//
|
|
// Reading Content as Byte Array ...
|
|
var contentBytes = await message.Content
|
|
.ReadAsByteArrayAsync ();
|
|
|
|
//
|
|
// Check ContentType of Response ...
|
|
if (
|
|
IsContentOfType (message, XResponseContentTypes.HTML) ||
|
|
IsContentOfType (message, XResponseContentTypes.JSON) ||
|
|
IsContentOfType (message, XResponseContentTypes.JavaScript)
|
|
) {
|
|
//
|
|
// If their String Content ...
|
|
var stringContent = Encoding.UTF8.GetString (contentBytes);
|
|
|
|
//
|
|
// TODO: here we can change String Contents ...
|
|
|
|
//
|
|
// Writing new Content to Response ...
|
|
await context.Response
|
|
.WriteAsync (
|
|
stringContent,
|
|
Encoding.UTF8
|
|
);
|
|
} else {
|
|
//
|
|
// if they have non string content ...
|
|
await context.Response.Body
|
|
.WriteAsync (
|
|
buffer: contentBytes,
|
|
offset: 0,
|
|
count: contentBytes.Length
|
|
);
|
|
}
|
|
|
|
//
|
|
SendLog ($"Response Content Processed ...", LogLevel.Information);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Content Type of Specific Response ...
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
private bool IsContentOfType (
|
|
HttpResponseMessage response,
|
|
string type
|
|
) {
|
|
//
|
|
// Create EMpty Result ...
|
|
var result = false;
|
|
|
|
//
|
|
// Retrieve and Check Content Type of Response ...
|
|
if (response.Content?.Headers?.ContentType != null) {
|
|
result = response.Content.Headers.ContentType.MediaType == type;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve and Extract Route Descriptor ...
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
private XProxyRouteDescriptor GetRouteDescriptor (HttpRequest request) {
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
CONFIGURATION.IsNull () ||
|
|
!CONFIGURATION.Routes.HasChild ()
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = CONFIGURATION.Routes
|
|
.FirstOrDefault (rd => !rd.Route.IsNullOrEmpty () &&
|
|
request.Path
|
|
.StartsWithSegments (rd.Route
|
|
.ToNormalString ()
|
|
)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provide all requirements for Dependency Injection Handler ...
|
|
/// </summary>
|
|
public static class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XProxy Middelware Configuration from Configuration ...
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <returns></returns>
|
|
public static XProxyConfiguration GetXProxyConfiguration (this IConfiguration config) {
|
|
//
|
|
var xProxyConfiguration = config.GetSection (ConfigurationNodeNames.XPROXY_CONFIGURATION_NODE_NAME);
|
|
return xProxyConfiguration.Get<XProxyConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register HTTP Handler for XProxy Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyHttpHandler (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
if (proxyConfig.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
services.AddXProxyHttpHandler (
|
|
httpHandler: httpHandler,
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register HTTP Handler for XProxy Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyHttpHandler (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
if (httpHandler.IsNull ()) {
|
|
httpHandler = new HttpClientHandler ();
|
|
}
|
|
|
|
//
|
|
httpHandler.AllowAutoRedirect = configuration.AllowAutoRedirect;
|
|
|
|
//
|
|
if (configuration.DisableSSLCheck) {
|
|
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
|
}
|
|
|
|
//
|
|
services
|
|
.AddHttpClient (XProxyConstants.XPROXY_HTTP_CLIENT)
|
|
.ConfigurePrimaryHttpMessageHandler (() => {
|
|
return httpHandler;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyServer (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
|
|
//
|
|
services.AddXProxyServer (
|
|
httpHandler: httpHandler,
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyServer (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Register Proxy Configuration ...
|
|
services.AddSingleton<XProxyConfiguration> (configuration);
|
|
|
|
//
|
|
// Regiter Proxy Handler ...
|
|
services.AddXProxyHttpHandler (
|
|
httpHandler: httpHandler,
|
|
configuration: configuration
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXProxyClient (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
|
|
//
|
|
services.AddXProxyClient (
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Client ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXProxyClient (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Register Proxy Configuration ...
|
|
services.AddSingleton<XProxyConfiguration> (configuration);
|
|
|
|
//
|
|
// Register IXProxyHelper ...
|
|
services.AddSingleton<IXProxyHelper, XProxyHelper> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adding XProxy Middleware to Applications ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXProxy (this IApplicationBuilder app) {
|
|
app.UseMiddleware<XProxyMiddleware> ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Models\XBaseRestResponse.cs
|
|
|
|
using RestSharp;
|
|
|
|
namespace xIdentityService.Models
|
|
{
|
|
public class XBaseRestResponse<T>
|
|
{
|
|
public T Model { get; set; }
|
|
public IRestResponse Response { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Admin.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XIdentityProvider {
|
|
//
|
|
#region Admin ...
|
|
/// <summary>
|
|
/// Ban Specific Users
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of banned users identifiers</returns>
|
|
public async Task<IEnumerable<string>> Ban (
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
tokens,
|
|
model
|
|
)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.AddNotZeroChilds (model.Ids)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.Ban);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<string>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// UnBann Specific Users
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of unbanned users identifiers</returns>
|
|
public async Task<IEnumerable<string>> UnBan (
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
tokens,
|
|
model
|
|
)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.AddNotZeroChilds (model.Ids)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.UnBan);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<string>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specific User is Banned or not
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns>a boolean value which represent user banned or not</returns>
|
|
public async Task<bool> IsBanned (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (
|
|
userSelectByParam,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.IsBanned,
|
|
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam } }
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Authentication.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XIdentityProvider {
|
|
//
|
|
#region Authentication Handlers ...
|
|
/// <summary>
|
|
/// Request for Discovery Document
|
|
/// </summary>
|
|
/// <returns>an instance of DiscoveryDocumentResponse</returns>
|
|
public async Task<DiscoveryDocumentResponse> RequestDiscoveryDocument () {
|
|
//
|
|
var httpClient = GetHttpClient ();
|
|
|
|
//
|
|
try {
|
|
//
|
|
var result = httpClient
|
|
.GetDiscoveryDocumentAsync (identityConfiguration.Authority)
|
|
.ContinueWith (docTask => {
|
|
//
|
|
httpClient.Dispose ();
|
|
return docTask.Result;
|
|
});
|
|
|
|
//
|
|
return await result;
|
|
} catch {
|
|
throw XException.ActionFailed.ToException ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request AccessToken for Specific XApiScope
|
|
/// </summary>
|
|
/// <param name="scope">a member of <see>XApiScope</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
public async Task<XTokenResponse> RequestScopeAccessToken (string scope) {
|
|
//
|
|
// Validate Args ...
|
|
var scopeName = string.Empty;
|
|
try {
|
|
scopeName = scope; // scope.GetStringValue ();
|
|
} catch { }
|
|
if (scopeName.IsNullOrEmpty ()) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.RequestScopeAccessToken,
|
|
headers : new Dictionary<string, string> { { XParam.XScope.GetStringValue (), scope.ToString () } });
|
|
|
|
//
|
|
var response = await RunRestRequest<XTokenResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
|
|
//
|
|
// Save Token ...
|
|
if (!response.IsNull ()) {
|
|
await tokenProvider.AddOrUpdateToken (response);
|
|
}
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a token
|
|
/// </summary>
|
|
/// <param name="model">Authentication Tokens</param>
|
|
/// <returns>an instance of TokenIntrospectionResponse</returns>
|
|
public async Task<TokenIntrospectionResponse> Introspection (XTokenResponse model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (model.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var httpClient = GetHttpClient ();
|
|
|
|
//
|
|
try {
|
|
//
|
|
var discoDoc = await RequestDiscoveryDocument ();
|
|
if (discoDoc.IsError) {
|
|
XException.ActionFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
var response = await httpClient.IntrospectTokenAsync (new TokenIntrospectionRequest {
|
|
//
|
|
Address = discoDoc.IntrospectionEndpoint,
|
|
ClientId = identityConfiguration.ClientId,
|
|
ClientSecret = identityConfiguration.ClientSecret,
|
|
|
|
//
|
|
Token = model.AccessToken
|
|
});
|
|
if (response.IsError) {
|
|
throw new Exception (response.Error);
|
|
}
|
|
|
|
//
|
|
return response;
|
|
} catch {
|
|
throw XException.ActionFailed.ToException ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate a User
|
|
/// </summary>
|
|
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
public async Task<XTokenResponse> Authenticate (XLoginRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroup ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
var request = GetRestRequet (XApiAccountEndpoint.Authenticate);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XTokenResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
|
|
//
|
|
// Save Token ...
|
|
if (!response.IsNull ()) {
|
|
await tokenProvider.AddOrUpdateToken (response);
|
|
}
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Do Login based on XLoginRequest
|
|
/// </summary>
|
|
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
public async Task<XLoginResponse> Login (XLoginRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model, model.Device)
|
|
.AddNotEmpty (
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroup ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
var request = GetRestRequet (XApiAccountEndpoint.Login);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XLoginResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
|
|
//
|
|
if (!response.IsNull ()) {
|
|
//
|
|
var tokens = response.ToXTokenResponse ();
|
|
await tokenProvider.AddOrUpdateToken (tokens);
|
|
}
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logout from System
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <returns></returns>
|
|
public async Task Logout (XTokenResponse model) {
|
|
//
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (model.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var isExists = await tokenProvider
|
|
.IsTokenExists (model.AccessToken);
|
|
if (isExists) {
|
|
await tokenProvider
|
|
.RemoveToken (model.AccessToken);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Tokens
|
|
/// </summary>
|
|
/// <param name="model">Authentication Tokens</param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
public async Task<XTokenResponse> RefreshTokens (XTokenResponse model) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (
|
|
model.AccessToken,
|
|
model.RefreshToken
|
|
)
|
|
.ValidateGroup ();
|
|
|
|
//
|
|
var client = GetRestClient (model);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.RefreshTokens,
|
|
headers : model.ToHeaderDictionary ());
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XTokenResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
if (!response.IsNull ()) {
|
|
await tokenProvider.UpdateToken (response);
|
|
}
|
|
|
|
//
|
|
return response;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Password Actions Handlers ...
|
|
/// <summary>
|
|
/// Change Password
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
public async Task ChangePassword (
|
|
XTokenResponse tokens,
|
|
XActionRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, model)
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.NewPassword,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Validate User Select By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
forceNotNull : true,
|
|
excludes : null);
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.ChangePassword,
|
|
headers : tokens.ToHeaderDictionary ());
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<Object> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Friendship.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xHttpService.Constants;
|
|
using xHttpService.Extensions;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xIdentityService.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Providers
|
|
{
|
|
public partial class XIdentityProvider
|
|
{
|
|
//
|
|
#region Friendship ...
|
|
/// <summary>
|
|
/// Follow a User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> Follow(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Follow,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollowing>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cancel Following Request
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> Cancel(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Cancel,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow a Follower
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
public async Task UnFollowFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.UnFollowFollower,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<object>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow Following
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
public async Task UnFollowFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.UnFollowFollowing,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<object>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Block a Follower
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> Block(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Block,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollowing>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unblock a Blocked User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> UnBlock(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.UnBlock,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollowing>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accept a Following Request
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> AcceptRequest(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.AcceptRequest,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollower>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reject a Following Request
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> RejectRequest(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.RejectRequest,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollower>(
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Friendship Info Model between Specific User and Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
|
|
public async Task<XFriendshipInfoDto> GetFriendshipInfo(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.FriendshipInfo,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipInfoDto>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User IsFollower of Requested User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.IsFollower,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Follower
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> GetFollower(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Follower,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollower>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Follower State of a User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
public async Task<XFriendshipState> GetFollowerState(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.FollowerState,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipState>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followers List Of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
public async Task<IEnumerable<XFriendshipFollower>> GetFollowers(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.Followers);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<XFriendshipFollower>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followers List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
public async Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.AllFollowers);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<XFriendshipFollower>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Followers UserName's List of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of UserNames</returns>
|
|
public async Task<IEnumerable<string>> GetFollowersList(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.FollowersList);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<string>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All User's Followers based on Query Model ...
|
|
/// </summary>
|
|
/// <param name="query">Query Model Descriptor</param>
|
|
/// <param name="destUser">Dest User for Reading Followers</param>
|
|
/// <param name="tokens">Requester User's Descriptor</param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XFriendDto>> QueryFollowers(
|
|
XQuery query,
|
|
string destUser,
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(destUser)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.QueryFollowers);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery(query);
|
|
request = request.AttachDestUser(destUser);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XFriendDto>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is in Followings of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.IsFollowing,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Following Model
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> GetFollowing(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Following,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipFollowing>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Following State Relation between Specific User
|
|
/// and Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
public async Task<XFriendshipState> GetFollowingState(
|
|
XTokenResponse tokens,
|
|
string destUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(
|
|
destUser,
|
|
tokens.AccessToken
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.FollowingState,
|
|
@params: new Dictionary<string, string> { { XParam.XDestUser.GetStringValue (), destUser }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XFriendshipState>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followings of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<IEnumerable<XFriendshipFollowing>> GetFollowings(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.Followings);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<XFriendshipFollowing>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Following List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.AllFollowings);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<XFriendshipFollowing>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Following UserName's List of Current User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <returns>a collection of UserNames</returns>
|
|
public async Task<IEnumerable<string>> GetFollowingList(
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.FollowingsList);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<string>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All User's Followings based on Query Model ...
|
|
/// </summary>
|
|
/// <param name="query">Query Model Descriptor</param>
|
|
/// <param name="destUser">Dest User for Reading Followers</param>
|
|
/// <param name="tokens">Requester User's Descriptor</param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XFriendDto>> QueryFollowings(
|
|
XQuery query,
|
|
string destUser,
|
|
XTokenResponse tokens
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens)
|
|
.AddNotEmpty(destUser)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.QueryFollowings);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery(query);
|
|
request = request.AttachDestUser(destUser);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XFriendDto>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Open.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using MongoDB.Bson;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityService.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Providers
|
|
{
|
|
public partial class XIdentityProvider
|
|
{
|
|
/// <summary>
|
|
/// Prepare API Based Device to Open Actions ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public XDeviceDto GetDevice()
|
|
{
|
|
//
|
|
var os = "XSaherElmOS";
|
|
bool isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
|
bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
|
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
|
if (isOSX)
|
|
{
|
|
os = "MacOs";
|
|
}
|
|
else if (isLinux)
|
|
{
|
|
os = "Linux";
|
|
}
|
|
else if (isWindows)
|
|
{
|
|
os = "Windows";
|
|
}
|
|
var agent = RuntimeInformation.FrameworkDescription;
|
|
if (agent.IsNullOrEmpty())
|
|
{
|
|
agent = "XSaherElmOSAgent";
|
|
}
|
|
var version = RuntimeInformation.OSArchitecture + ", " + RuntimeInformation.OSDescription;
|
|
if (version.IsNullOrEmpty())
|
|
{
|
|
version = "XSaherElmOSVersion";
|
|
}
|
|
var browser = "XSaherElmBrowser_" + RevisionSecretKey.ToMd5String();
|
|
|
|
//
|
|
var result = new XDeviceDto
|
|
{
|
|
Os = os,
|
|
Browser = browser,
|
|
UserAgent = agent,
|
|
OsVersion = version,
|
|
DeviceType = XDeviceType.Desktop,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region OpenGet ...
|
|
public async Task<XOpenActionInnerDto> OpenGet(
|
|
XOpenActionInnerDto model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(model.Token)
|
|
.AddNotEmpty(model.Payload)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await OpenGet(
|
|
token: model.Token,
|
|
actionRequest: model.Payload
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
public async Task<XOpenActionInnerDto> OpenGet(
|
|
string token,
|
|
string actionRequest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(token)
|
|
.AddNotEmpty(actionRequest)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Retrieve Rest Client ...
|
|
var client = GetRestClient();
|
|
|
|
//
|
|
// Prepare Rest Request ...
|
|
var request = GetRestRequet(
|
|
XApiAccountEndpoint.Open,
|
|
headers: new Dictionary<string, string>
|
|
{
|
|
{ XAuthentication.TOKEN, token}
|
|
},
|
|
queryStrings: new Dictionary<string, string>
|
|
{
|
|
{ XParam.XRequest.GetStringValue(), actionRequest }
|
|
}
|
|
);
|
|
|
|
//
|
|
// Run Request and Retrieve Response ...
|
|
var response = await RunRestRequestByResponse<string>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
|
|
//
|
|
// Now we Have to Validate the recieved response ...
|
|
|
|
//
|
|
// Read token from Headers ...
|
|
var responseToken = response.Response.Headers
|
|
.First(h => h.Name == XAuthentication.TOKEN).Value.ToString();
|
|
if (responseToken.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Decript Recieve Response ...
|
|
var responseJson = response.Model; // SecurityProvider.Decrypt(response.Model);
|
|
if (responseJson.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new XOpenActionInnerDto
|
|
{
|
|
Token = responseToken,
|
|
Payload = responseJson
|
|
};
|
|
|
|
//
|
|
// Retrieve Model and Validate it ...
|
|
var responseModel = responseJson.FromJSON<XOpenActionRequestDto>();
|
|
if (responseModel.IsNull() ||
|
|
responseModel.Payload.IsNullOrEmpty() ||
|
|
responseToken != responseModel.Checksum ||
|
|
responseModel.Timestamp.FromTimestamp().IsExPired())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region GetUserInfo ...
|
|
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XDeviceDto device,
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(device);
|
|
validationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Prepare Open Action Model ...
|
|
var opaModel = new XOpenActionRequestDto
|
|
{
|
|
Device = device,
|
|
Payload = userSelectByParam,
|
|
Action = XOpenActions.GetUserInfo,
|
|
Timestamp = DateTime.UtcNow.AddMinutes(5).ToTimestamp().ToString()
|
|
};
|
|
if (!opaModel.Validate())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Fill Checksum Filed ...
|
|
var token = opaModel.ToOpenActionToken();
|
|
opaModel.Checksum = token;
|
|
|
|
//
|
|
// Prepare Request ...
|
|
var opaJson = opaModel.ToJson();
|
|
var requestString = SecurityProvider.Encrypt(opaJson);
|
|
|
|
//
|
|
return await GetUserInfo(
|
|
token: token,
|
|
request: requestString
|
|
);
|
|
}
|
|
|
|
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XOpenActionInnerDto dto
|
|
)
|
|
{
|
|
//
|
|
return await GetUserInfo(
|
|
token: dto.Token,
|
|
request: dto.Payload
|
|
);
|
|
}
|
|
|
|
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
string token,
|
|
string request
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotEmpty(token);
|
|
validationProvider.NotEmpty(request);
|
|
|
|
//
|
|
// Retrieve and Validate Response ...
|
|
var response = await OpenGet(
|
|
token: token,
|
|
actionRequest: request
|
|
);
|
|
if (response.IsNull() ||
|
|
response.Token.IsNullOrEmpty() ||
|
|
response.Payload.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Now we Have to Converts Repose Payload to Result Model ...
|
|
// Note that the respose Model's payload here is Decrypted and
|
|
// actually is Json Representation of Result Model ...
|
|
var requestModel = response.Payload.FromJSON<XOpenActionRequestDto>();
|
|
if (requestModel.IsNull())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var resultJson = SecurityProvider.Decrypt(requestModel.Payload);
|
|
var result = resultJson.FromJSON<XOpenActionUserInfoDto>();
|
|
if (result.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region GetUserInfos ...
|
|
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XDeviceDto device,
|
|
string ids
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(device);
|
|
validationProvider.NotEmpty(ids);
|
|
|
|
//
|
|
// Prepare Open Action Model ...
|
|
var opaModel = new XOpenActionRequestDto
|
|
{
|
|
Payload = ids,
|
|
Device = device,
|
|
Action = XOpenActions.GetUserInfos,
|
|
Timestamp = DateTime.UtcNow.AddMinutes(5).ToTimestamp().ToString()
|
|
};
|
|
if (!opaModel.Validate())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Fill Checksum Filed ...
|
|
var token = opaModel.ToOpenActionToken();
|
|
opaModel.Checksum = token;
|
|
|
|
//
|
|
// Prepare Request ...
|
|
var opaJson = opaModel.ToJson();
|
|
var requestString = SecurityProvider.Encrypt(opaJson);
|
|
|
|
//
|
|
return await GetUserInfos(
|
|
token: token,
|
|
request: requestString
|
|
);
|
|
}
|
|
|
|
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XOpenActionInnerDto dto
|
|
)
|
|
{
|
|
//
|
|
return await GetUserInfos(
|
|
token: dto.Token,
|
|
request: dto.Payload
|
|
);
|
|
}
|
|
|
|
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
string token,
|
|
string request
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotEmpty(token);
|
|
validationProvider.NotEmpty(request);
|
|
|
|
//
|
|
// Retrieve and Validate Response ...
|
|
var response = await OpenGet(
|
|
token: token,
|
|
actionRequest: request
|
|
);
|
|
if (response.IsNull() ||
|
|
response.Token.IsNullOrEmpty() ||
|
|
response.Payload.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Now we Have to Converts Repose Payload to Result Model ...
|
|
// Note that the respose Model's payload here is Decrypted and
|
|
// actually is Json Representation of Result Model ...
|
|
var requestModel = response.Payload.FromJSON<XOpenActionRequestDto>();
|
|
if (requestModel.IsNull())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var resultJson = SecurityProvider.Decrypt(requestModel.Payload);
|
|
var result = resultJson.FromJSON<IEnumerable<XOpenActionUserInfoDto>>();
|
|
if (result.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Profile.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xCommons.Extensions;
|
|
using xHttpService.Constants;
|
|
using xHttpService.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xIdentityService.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XIdentityProvider {
|
|
//
|
|
#region User Actions ...
|
|
/// <summary>
|
|
/// Retrieve User Names based on UserIds
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="ids">a comma seperated list of UserIds</param>
|
|
/// <returns>a collection of UserNames</returns>
|
|
public async Task<IEnumerable<string>> GetUserNames (
|
|
XTokenResponse tokens,
|
|
string ids
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (ids, tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.GetNames,
|
|
@params : new Dictionary<string, string> { { XParam.XIds.GetStringValue (), ids } }
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<string>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// get user ids and retrieve corresponding user names
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
|
|
/// <returns>a collection of <see>XUserNameIdResponse</see> instance</returns>
|
|
public async Task<IEnumerable<XUserNameIdResponse>> GetUserNameIds (
|
|
XTokenResponse tokens,
|
|
XUserNameIdRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model, tokens)
|
|
.AddNotZeroChilds (model.Ids)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
var request = GetRestRequet (XApiAccountEndpoint.GetNameIds);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<IEnumerable<XUserNameIdResponse>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Profile Actions ...
|
|
/// <summary>
|
|
/// Get Profile Object of Specific User
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> GetUserProfile (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (userSelectByParam, tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.GetProfile,
|
|
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam } }
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Users Based On Query
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryUsers (
|
|
XTokenResponse tokens,
|
|
XQuery query
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, query)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.QueryProfiles);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery (query);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XUserProfileDto>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Users Based On Query and Specified role
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers (
|
|
XTokenResponse tokens,
|
|
string role,
|
|
XQuery query,
|
|
bool forceRole = false
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, query)
|
|
.AddNotEmpty (tokens.AccessToken, role)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.QueryProfiles,
|
|
headers : new Dictionary<string, string> { { XParam.XRole.GetStringValue (), role },
|
|
{ XParam.XForceRole.GetStringValue (), forceRole.AsHttpParamString () }
|
|
}
|
|
);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery (query);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XUserProfileDto>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified User's Profile Images
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
|
|
public async Task<XQueryResult<XProfileImage>> QueryAvatars (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XQuery query
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, query)
|
|
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.QueryAvatars,
|
|
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
|
|
}
|
|
);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery (query);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XProfileImage>> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update User Profile based on <see>XProfileUpdateRequest</see> (FirstName/LastName/DateOfBirth)
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> ProfileUpdateAsync (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XProfileUpdateRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, model)
|
|
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.UpdateProfile,
|
|
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
|
|
}
|
|
);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a User Profile based on <see>XProfileUpdateRequest</see> Full
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> FullProfileUpdateAsync (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam,
|
|
XProfileUpdateRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, model)
|
|
.AddNotEmpty (tokens.AccessToken, userSelectByParam)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.FullUpdateProfile,
|
|
@params : new Dictionary<string, string> { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam }
|
|
}
|
|
);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a New Profile Image
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatar (
|
|
XTokenResponse tokens,
|
|
IFormFile file
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens, file)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.AddAvatar);
|
|
request.AlwaysMultipartFormData = true;
|
|
request.AddFileBytes (
|
|
XParam.XFile.GetStringValue (),
|
|
file.ToByteArray (),
|
|
file.FileName,
|
|
file.ContentType
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a New Collection of Profile Images
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatars (
|
|
XTokenResponse tokens,
|
|
IFormFileCollection files
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotZeroChilds (files)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.AddAvatars);
|
|
request.AlwaysMultipartFormData = true;
|
|
|
|
//
|
|
// Add Files ...
|
|
foreach (var file in files) {
|
|
//
|
|
// Add Single file ...
|
|
request.AddFileBytes (
|
|
XParam.XFiles.GetStringValue (),
|
|
file.ToByteArray (),
|
|
file.FileName,
|
|
file.ContentType
|
|
);
|
|
}
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// set Specified Profile Image as Avatar
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> SetAvatar (
|
|
XTokenResponse tokens,
|
|
int id
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
id.ValidateIntId ();
|
|
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.SetAvatar,
|
|
@params : new Dictionary<string, string> { { XParam.XId.GetStringValue (), id.ToString () }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Profile Images
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="avatarIds">a comma seperated list of avatarIds to remove</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> RemoveAvatars (
|
|
XTokenResponse tokens,
|
|
string avatarIds
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (avatarIds, tokens.AccessToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
XApiAccountEndpoint.RemoveAvatars,
|
|
@params : new Dictionary<string, string> { { XParam.XIds.GetStringValue (), avatarIds }
|
|
}
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XUserProfileDto> (
|
|
client,
|
|
request,
|
|
XHttpMethod.DELETE
|
|
);
|
|
return response;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Registration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XIdentityProvider {
|
|
//
|
|
#region Registration ...
|
|
/// <summary>
|
|
/// Check a User Selector is Available for Registration or Not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">an string value which reperesent a user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> CanRegister (string userSelectByParam) {
|
|
//
|
|
// Validate ARgs ...
|
|
validationProvider.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
// Check Endpoint ...
|
|
var endpoint = XApiAccountEndpoint.CanRegisterUserName;
|
|
var @params = new Dictionary<string, string> { { XParam.XUserName.GetStringValue (), userSelectByParam } };
|
|
|
|
//
|
|
// Check UserSelectByType ...
|
|
var type = userSelectByParam.GetUserSelectByType ();
|
|
switch (type) {
|
|
//
|
|
case XUserSelectBy.Username:
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.MobileNumber:
|
|
//
|
|
endpoint = XApiAccountEndpoint.CanRegisterMobileNumber;
|
|
@params = new Dictionary<string, string> { { XParam.XMobileNumber.GetStringValue (), userSelectByParam } };
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.Email:
|
|
//
|
|
endpoint = XApiAccountEndpoint.CanRegisterEmail;
|
|
@params = new Dictionary<string, string> { { XParam.XEmail.GetStringValue (), userSelectByParam } };
|
|
break;
|
|
|
|
//
|
|
default:
|
|
throw XException.InvalidData.ToException ();
|
|
}
|
|
|
|
//
|
|
var request = GetRestRequet (
|
|
endpoint,
|
|
@params: @params
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invite a User to Register on Dashboard
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> InviteUser (
|
|
XTokenResponse tokens,
|
|
XActionRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
tokens,
|
|
model,
|
|
model.Device)
|
|
.AddNotEmpty (
|
|
tokens.AccessToken,
|
|
model.Lang,
|
|
model.Email,
|
|
model.ReturnUrl)
|
|
.AddEmailAddress (model.Email)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.InviteUser);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recieve some Basic Informations and Start Registration Proccess
|
|
/// if they Valid
|
|
///
|
|
/// Registration Proccess Starts with Invoking this Action
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestRegistration (
|
|
XActionRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
model,
|
|
model.Device,
|
|
model.DateOfBirth)
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.FirstName,
|
|
model.LastName)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.RequestRegistration);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add User Account Informations
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> AddAccountInfo (
|
|
XActionRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
model,
|
|
model.Device)
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.UserName,
|
|
model.Password,
|
|
model.ActionToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.AddAccountInfo);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload and Attach a Profile Image for User. this is an Optional Step
|
|
/// </summary>
|
|
/// <param name="actionToken">user's requested action token</param>
|
|
/// <param name="file">an instance of <see>IFormFile</see> for user's Avatar</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> AttachProfileImage (
|
|
string actionToken,
|
|
IFormFile file
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (file)
|
|
.AddNotEmpty (actionToken)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.AttachProfileImage);
|
|
|
|
//
|
|
// Prepare Request Data ...
|
|
request.AddParameter (XParam.XActionToken.GetStringValue (), actionToken);
|
|
request.AddFileBytes (
|
|
XParam.XFile.GetStringValue (),
|
|
file.ToByteArray (),
|
|
file.FileName,
|
|
file.ContentType
|
|
);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finish Registrationn Proccess
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
public async Task FinishRegistration (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Create Http Client ...
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
// Create Request ...
|
|
var request = GetRestRequet (XApiAccountEndpoint.FinishRegistration);
|
|
|
|
//
|
|
// Prepare Request Data ...
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<object> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User is Confirmed Email or not
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">an string value which reperesent a user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedEmail (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (
|
|
tokens.AccessToken,
|
|
userSelectByParam)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.IsConfirmedEmail);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User is Confirmed Mobile or not
|
|
/// </summary>
|
|
/// <param name="tokens">Authentication Tokens</param>
|
|
/// <param name="userSelectByParam">an string value which reperesent a user</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedMobile (
|
|
XTokenResponse tokens,
|
|
string userSelectByParam
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (tokens)
|
|
.AddNotEmpty (
|
|
tokens.AccessToken,
|
|
userSelectByParam)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient (tokens);
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.IsConfirmedMobile);
|
|
|
|
//
|
|
var response = await RunRestRequest<bool> (
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Registration Confirm
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
public async Task RequestConfirmRegistration (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = model.GetUserSelectByParam ();
|
|
validationProvider.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmRegistration);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<object> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Registration
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
public async Task ConfirmRegistration (
|
|
XActionRequest model
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.ReturnUrl
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.ConfirmRegistration);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<object> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request For Mobile Number Change/Confirm
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmMobile (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.MobileNumber
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.AddMobileNumber (model.MobileNumber)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmMobile);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Mobile Number
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmMobileNumber (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.MobileVerificationCode
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.ConfirmMobileNumber);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request For Email Address Change/Confirm
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmEmail (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Email,
|
|
model.Password)
|
|
.AddNotNull (model.Device)
|
|
.AddEmailAddress (model.Email)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.RequestConfirmEmail);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Email Address
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmEmailAddress (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.EmailVerificationCode
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.ConfirmEmailAddress);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Reset Password Action
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestResetPassword (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.RequestResetPassword);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<XActionResponse> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset a User's Password
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
public async Task ResetPassword (XActionRequest model) {
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.NewPassword,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var client = GetRestClient ();
|
|
|
|
//
|
|
var request = GetRestRequet (XApiAccountEndpoint.ResetPassword);
|
|
request.AddJsonBody (model);
|
|
|
|
//
|
|
var response = await RunRestRequest<object> (
|
|
client,
|
|
request,
|
|
XHttpMethod.POST
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Search.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xHttpService.Constants;
|
|
using xHttpService.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIdentityService.Providers
|
|
{
|
|
public partial class XIdentityProvider
|
|
{
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Query Open To Search User Profiles ...
|
|
/// </summary>
|
|
/// <param name="tokens">requested user's identifiers</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
|
|
XTokenResponse tokens,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await validationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(tokens, query)
|
|
.AddNotEmpty(tokens.AccessToken)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var client = GetRestClient(tokens);
|
|
|
|
//
|
|
var request = GetRestRequet(XApiAccountEndpoint.QueryOpenToSearchProfiles);
|
|
|
|
//
|
|
// Attach XQuery to Request ...
|
|
request = request.AttachXQuery(query);
|
|
|
|
//
|
|
var response = await RunRestRequest<XQueryResult<XUserProfileDto>>(
|
|
client,
|
|
request,
|
|
XHttpMethod.GET
|
|
);
|
|
return response;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XBaseIdentityHttpProvider.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using RestSharp;
|
|
using RestSharp.Authenticators;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Models;
|
|
using xIdentityService.Extensions;
|
|
using System.Diagnostics.Tracing;
|
|
using MySqlX.XDevAPI.Common;
|
|
|
|
namespace xIdentityService.Providers
|
|
{
|
|
/// <summary>
|
|
/// an abstraction Implementation for Identity Provided Http Based Services ...
|
|
/// </summary>
|
|
public abstract class XBaseIdentityHttpProvider : IXBaseIdentityHttpProvider
|
|
{
|
|
/// <summary>
|
|
/// Client Base Url ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string BaseUrl { get; }
|
|
|
|
/// <summary>
|
|
/// Logger ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public ILogger Logger { get; }
|
|
|
|
/// <summary>
|
|
/// Powered Value ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string XPoweredValue { get; }
|
|
|
|
/// <summary>
|
|
/// Default Client Timeout ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int DefaultClientTimeout { get; }
|
|
|
|
/// <summary>
|
|
/// Default Buffering Chunk Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int DefaultBufferingChunckSize { get; }
|
|
|
|
/// <summary>
|
|
/// Validation Provider ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public XValidationProvider ValidationProvider { get; }
|
|
|
|
/// <summary>
|
|
/// Token Provider ...
|
|
/// </summary>
|
|
private readonly IXTokenProvider tokenProvider;
|
|
|
|
/// <summary>
|
|
/// Identity Provider ...
|
|
/// </summary>
|
|
private readonly IXIdentityProvider identityProvider;
|
|
|
|
public XBaseIdentityHttpProvider(
|
|
string baseUrl,
|
|
ILogger logger,
|
|
string poweredValue,
|
|
int defaultClientTimeout,
|
|
IXTokenProvider tokenProvider,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
int defaultBufferingChunckSize = 8192
|
|
)
|
|
{
|
|
//
|
|
Logger = logger;
|
|
BaseUrl = baseUrl;
|
|
XPoweredValue = poweredValue;
|
|
this.tokenProvider = tokenProvider;
|
|
ValidationProvider = validationProvider;
|
|
this.identityProvider = identityProvider;
|
|
DefaultClientTimeout = defaultClientTimeout;
|
|
DefaultBufferingChunckSize = defaultBufferingChunckSize;
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Get an Instance of Http Client
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public HttpClient GetHttpClient(XTokenResponse tokens = null)
|
|
{
|
|
//
|
|
HttpClient httpClient = null;
|
|
|
|
//
|
|
// httpClient = new HttpClient ();
|
|
var httpClientHandler = new HttpClientHandler()
|
|
{
|
|
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
|
|
{
|
|
//
|
|
Logger.LogInformation(
|
|
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
|
|
);
|
|
|
|
//
|
|
return true;
|
|
},
|
|
ClientCertificateOptions = ClientCertificateOption.Manual,
|
|
};
|
|
httpClient = new HttpClient(httpClientHandler);
|
|
|
|
//
|
|
// Set Authenticator ...
|
|
if (!tokens.IsNull() &&
|
|
!tokens.AccessToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
httpClient.DefaultRequestHeaders
|
|
.Add(
|
|
XAuthorization.Header,
|
|
$"{XAuthentication.BEARER} {tokens.AccessToken}");
|
|
}
|
|
|
|
//
|
|
// Refresh Token ...
|
|
if (!tokens.IsNull() &&
|
|
!tokens.RefreshToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
httpClient.DefaultRequestHeaders
|
|
.Add(
|
|
XAuthorization.RefreshToken,
|
|
tokens.RefreshToken);
|
|
}
|
|
|
|
//
|
|
// ExpiresAt ...
|
|
if (!tokens.IsNull() &&
|
|
tokens.ExpiresAt > 0)
|
|
{
|
|
//
|
|
httpClient.DefaultRequestHeaders
|
|
.Add(
|
|
XAuthorization.ExpiresAt,
|
|
tokens.ExpiresAt.AsHttpParamString());
|
|
}
|
|
|
|
//
|
|
// Set Default Timeout ...
|
|
httpClient.Timeout = TimeSpan.FromSeconds(DefaultClientTimeout == -1 ? 10000 : DefaultClientTimeout);
|
|
|
|
//
|
|
return httpClient;
|
|
}
|
|
public HttpClient GetHttpClient(XUserClaimsInfoDto userInfo = null)
|
|
{
|
|
//
|
|
XTokenResponse tokens = ToTokenResponse(userInfo);
|
|
|
|
//
|
|
return GetHttpClient(tokens);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestClient
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public RestClient GetRestClient(XTokenResponse tokens = null)
|
|
{
|
|
//
|
|
var client = new RestClient(BaseUrl);
|
|
|
|
//
|
|
// Set Authenticator ...
|
|
if (!tokens.IsNull() &&
|
|
!tokens.AccessToken.IsNullOrEmpty())
|
|
{
|
|
client.Authenticator = new JwtAuthenticator(tokens.AccessToken);
|
|
}
|
|
|
|
//
|
|
// Refresh Token ...
|
|
if (!tokens.IsNull() &&
|
|
!tokens.RefreshToken.IsNullOrEmpty())
|
|
{
|
|
client.AddDefaultHeader(XAuthorization.RefreshToken, tokens.RefreshToken);
|
|
}
|
|
|
|
//
|
|
// ExpiresAt ...
|
|
if (!tokens.IsNull() &&
|
|
tokens.ExpiresAt > 0)
|
|
{
|
|
client.AddDefaultHeader(XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString());
|
|
}
|
|
|
|
//
|
|
// Set Default Timeout ...
|
|
client.Timeout = DefaultClientTimeout;
|
|
|
|
//
|
|
// SSL Validation Handler ...
|
|
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
|
|
{
|
|
//
|
|
Logger.LogInformation(
|
|
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
|
|
);
|
|
|
|
//
|
|
return true;
|
|
};
|
|
|
|
//
|
|
return client;
|
|
}
|
|
public RestClient GetRestClient(XUserClaimsInfoDto userInfo = null)
|
|
{
|
|
//
|
|
XTokenResponse tokens = ToTokenResponse(userInfo);
|
|
|
|
//
|
|
return GetRestClient(tokens);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestRequest
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="addXPoweredValue"></param>
|
|
/// <param name=""></param>
|
|
/// <param name="headers"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
public RestRequest GetRestRequet(
|
|
Enum endpoint,
|
|
bool addXPoweredValue = true,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
)
|
|
{
|
|
//
|
|
var url = PrepareUrl(
|
|
@params: @params,
|
|
endpoint: endpoint,
|
|
queryStrings: queryStrings
|
|
);
|
|
|
|
//
|
|
// Create request ...
|
|
var request = new RestRequest(url, DataFormat.Json);
|
|
|
|
//
|
|
if (addXPoweredValue)
|
|
{
|
|
request.AddHeader(XAuthorization.XPoweredBy, XPoweredValue);
|
|
}
|
|
|
|
//
|
|
// Add Headers to request ...
|
|
if (!headers.IsNull() && headers.Count > 0)
|
|
{
|
|
//
|
|
var enumerator = headers.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
//
|
|
var item = enumerator.Current;
|
|
request.AddHeader(item.Key, item.Value);
|
|
}
|
|
}
|
|
|
|
//
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Call Specific Request and retrieve Response
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="supportRefreshingTokens"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public async Task<T> RunRestRequest<T>(
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var response = await Task.Run(async () =>
|
|
{
|
|
//
|
|
IRestResponse resp = null;
|
|
|
|
//
|
|
// Call Endpoint Service using Specified Method ...
|
|
switch (method)
|
|
{
|
|
//
|
|
// Get ...
|
|
case XHttpMethod.GET:
|
|
resp = client.Get(request);
|
|
break;
|
|
|
|
//
|
|
// Put ...
|
|
case XHttpMethod.PUT:
|
|
resp = client.Put(request);
|
|
break;
|
|
|
|
//
|
|
// Post ...
|
|
case XHttpMethod.POST:
|
|
resp = client.Post(request);
|
|
break;
|
|
|
|
//
|
|
// Delete ...
|
|
case XHttpMethod.DELETE:
|
|
resp = client.Delete(request);
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (!resp.IsSuccessful)
|
|
{
|
|
//
|
|
// Log Exception ...
|
|
Logger.LogError($"Error: {resp.ErrorMessage}");
|
|
Logger.LogError($"Exception: {resp.ErrorException.ToJSON()}");
|
|
if (!resp.ErrorMessage.IsNullOrEmpty() &&
|
|
resp.ErrorMessage.Contains("timed out"))
|
|
{
|
|
XException.Timeout.Throw();
|
|
}
|
|
|
|
//
|
|
// TODO: Check UnAuthorized Status here for
|
|
// Refresh Tokens or Issue Correct Exception ...
|
|
if (supportRefreshingTokens &&
|
|
resp.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
|
{
|
|
//
|
|
var isRefreshed = request.Parameters.Any(rp =>
|
|
rp.Name == XParam.XIsRefreshed.GetStringValue() &&
|
|
rp.Value.ToString().ToNormalString() == true.ToJSON());
|
|
|
|
//
|
|
Logger.LogInformation($"isRefreshed: {isRefreshed}");
|
|
|
|
//
|
|
// Get Access Token ...
|
|
XTokenResponse tokens = null;
|
|
var accessToken = request.Parameters.FirstOrDefault(rp =>
|
|
rp.Name.ToNormalString() == XAuthorization.Header.ToNormalString()).Value.ToString();
|
|
if (!accessToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
accessToken = accessToken.Replace(XAuthorization.TokenIdentifier, "");
|
|
|
|
//
|
|
if (!accessToken.IsNullOrEmpty())
|
|
{
|
|
tokens = await tokenProvider.RetrieveToken(accessToken);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Refresh Token and then re do request ...
|
|
if (!isRefreshed &&
|
|
!accessToken.IsNullOrEmpty() &&
|
|
!tokens.IsNull() &&
|
|
tokens.IsRefreshable())
|
|
{
|
|
//
|
|
request.AddHeader(XParam.XIsRefreshed.GetStringValue(), true.ToJSON());
|
|
|
|
//
|
|
// Refreshe Tokens ...
|
|
var refreshedTokens = await identityProvider
|
|
.RefreshTokens(tokens);
|
|
|
|
//
|
|
// Renew Rest Client with Refreshed Tokens ...
|
|
var timeout = client.Timeout;
|
|
client = GetRestClient(refreshedTokens);
|
|
client.Timeout = Timeout.Infinite;
|
|
|
|
//
|
|
// Do Request Again using renew Client ...
|
|
return await RunRestRequest<T>(
|
|
client: client,
|
|
request: request,
|
|
method: method);
|
|
}
|
|
}
|
|
|
|
//
|
|
var ex = resp.Content.ToXError();
|
|
if (!ex.IsNull())
|
|
{
|
|
throw ex.ToException();
|
|
}
|
|
|
|
//
|
|
// UnAuthorized ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
// NotFound ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = resp.Content.FromJSON<T>();
|
|
return result;
|
|
},
|
|
cancellationToken: cancellationToken);
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Access a Get Request Stream as AsyncEnumerable ...
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="bufferLength"></param>
|
|
/// <param name="addXPoweredValue"></param>
|
|
/// <param name="tokens"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="headers"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public async Task<Stream> StreamData(
|
|
Enum endpoint,
|
|
int bufferLength = 8194,
|
|
bool addXPoweredValue = true,
|
|
XTokenResponse tokens = null,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null,
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation]
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var url = PrepareUrl(
|
|
@params: @params,
|
|
endpoint: endpoint,
|
|
attachBaseUrl: true,
|
|
queryStrings: queryStrings
|
|
);
|
|
var client = GetHttpClient(tokens);
|
|
if (addXPoweredValue)
|
|
{
|
|
//
|
|
client.DefaultRequestHeaders
|
|
.Add(
|
|
XAuthorization.XPoweredBy,
|
|
XPoweredValue
|
|
);
|
|
}
|
|
|
|
//
|
|
// For SSE, you might want to set the Accept header, though not strictly necessary for just streaming
|
|
client.DefaultRequestHeaders.Accept.Clear();
|
|
client.DefaultRequestHeaders.Accept
|
|
.Add(
|
|
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
|
|
|
|
//
|
|
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
//
|
|
var stream = await response.Content.ReadAsStreamAsync();
|
|
|
|
//
|
|
return stream;
|
|
|
|
// using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
|
|
// {
|
|
// //
|
|
// int readedBuffers = 0;
|
|
// response.EnsureSuccessStatusCode();
|
|
// var buffer = new byte[bufferLength];
|
|
// var stream = await response.Content.ReadAsStreamAsync();
|
|
|
|
// //
|
|
// while ((readedBuffers = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
|
// {
|
|
// //
|
|
// var content = buffer.FromBytes();
|
|
// Console.WriteLine(content);
|
|
// }
|
|
|
|
// // await foreach (var message in stream) {
|
|
// // Console.WriteLine(message);
|
|
// // }
|
|
|
|
// // await foreach (var item in stream.ToAsyncEnumerable<byte[]>(cancellationToken: cancellationToken))
|
|
// // {
|
|
// // //
|
|
// // Console.WriteLine(item);
|
|
|
|
// // // T value = item.IsNull()
|
|
// // // ? default(T)
|
|
// // // : item.FromBytes().FromJSON<T>();
|
|
|
|
// // // //
|
|
// // // yield return value;
|
|
// // }
|
|
// }
|
|
|
|
///
|
|
///
|
|
///
|
|
///
|
|
|
|
//
|
|
// var eventSource = new EventSource(url);
|
|
// // eventSource.
|
|
|
|
// // var client = GetHttpClient(tokens);
|
|
// // if (addXPoweredValue)
|
|
// // {
|
|
// // //
|
|
// // client.DefaultRequestHeaders
|
|
// // .Add(
|
|
// // XAuthorization.XPoweredBy,
|
|
// // XPoweredValue);
|
|
// // }
|
|
|
|
// // //
|
|
// // // For SSE, you might want to set the Accept header, though not strictly necessary for just streaming
|
|
// // client.DefaultRequestHeaders.Accept.Clear();
|
|
// // client.DefaultRequestHeaders.Accept
|
|
// // .Add(
|
|
// // new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/event-stream"));
|
|
|
|
// // //
|
|
// // using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
|
|
// // {
|
|
// // //
|
|
// // response.EnsureSuccessStatusCode();
|
|
// // var stream = await response.Content.ReadAsStreamAsync();
|
|
// // await foreach (var item in stream.ToAsyncEnumerable<byte[]>(cancellationToken: cancellationToken))
|
|
// // {
|
|
// // //
|
|
// // T value = item.IsNull()
|
|
// // ? default(T)
|
|
// // : item.FromBytes().FromJSON<T>();
|
|
|
|
// // //
|
|
// // yield return value;
|
|
// // }
|
|
// // }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Call Specified Request and Retrieve XBaseRestResponse<T> ...
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="supportRefreshingTokens"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns>an instance of XBaseRestResponse<T></returns>
|
|
public async Task<XBaseRestResponse<T>> RunRestRequestByResponse<T>(
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var response = await Task.Run(async () =>
|
|
{
|
|
//
|
|
IRestResponse resp = null;
|
|
|
|
//
|
|
// Call Endpoint Service using Specified Method ...
|
|
switch (method)
|
|
{
|
|
//
|
|
// Get ...
|
|
case XHttpMethod.GET:
|
|
resp = client.Get(request);
|
|
break;
|
|
|
|
//
|
|
// Put ...
|
|
case XHttpMethod.PUT:
|
|
resp = client.Put(request);
|
|
break;
|
|
|
|
//
|
|
// Post ...
|
|
case XHttpMethod.POST:
|
|
resp = client.Post(request);
|
|
break;
|
|
|
|
//
|
|
// Delete ...
|
|
case XHttpMethod.DELETE:
|
|
resp = client.Delete(request);
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (!resp.IsSuccessful)
|
|
{
|
|
//
|
|
// Log Exception ...
|
|
Logger.LogError($"Error: {resp.ErrorMessage}");
|
|
Logger.LogError($"Exception: {resp.ErrorException.ToJSON()}");
|
|
if (!resp.ErrorMessage.IsNullOrEmpty() &&
|
|
resp.ErrorMessage.Contains("timed out"))
|
|
{
|
|
XException.Timeout.Throw();
|
|
}
|
|
|
|
//
|
|
// TODO: Check UnAuthorized Status here for
|
|
// Refresh Tokens or Issue Correct Exception ...
|
|
if (supportRefreshingTokens &&
|
|
resp.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
|
{
|
|
//
|
|
var isRefreshed = request.Parameters.Any(rp =>
|
|
rp.Name == XParam.XIsRefreshed.GetStringValue() &&
|
|
rp.Value.ToString().ToNormalString() == true.ToJSON());
|
|
|
|
//
|
|
Logger.LogInformation($"isRefreshed: {isRefreshed}");
|
|
|
|
//
|
|
// Get Access Token ...
|
|
XTokenResponse tokens = null;
|
|
var accessToken = request.Parameters.FirstOrDefault(rp =>
|
|
rp.Name.ToNormalString() == XAuthorization.Header.ToNormalString()).Value.ToString();
|
|
if (!accessToken.IsNullOrEmpty())
|
|
{
|
|
//
|
|
accessToken = accessToken.Replace(XAuthorization.TokenIdentifier, "");
|
|
|
|
//
|
|
if (!accessToken.IsNullOrEmpty())
|
|
{
|
|
tokens = await tokenProvider.RetrieveToken(accessToken);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Refresh Token and then re do request ...
|
|
if (!isRefreshed &&
|
|
!accessToken.IsNullOrEmpty() &&
|
|
!tokens.IsNull() &&
|
|
tokens.IsRefreshable())
|
|
{
|
|
//
|
|
request.AddHeader(XParam.XIsRefreshed.GetStringValue(), true.ToJSON());
|
|
|
|
//
|
|
// Refreshe Tokens ...
|
|
var refreshedTokens = await identityProvider
|
|
.RefreshTokens(tokens);
|
|
|
|
//
|
|
// Renew Rest Client with Refreshed Tokens ...
|
|
var timeout = client.Timeout;
|
|
client = GetRestClient(refreshedTokens);
|
|
client.Timeout = Timeout.Infinite;
|
|
|
|
//
|
|
// Do Request Again using renew Client ...
|
|
return await RunRestRequestByResponse<T>(
|
|
client: client,
|
|
request: request,
|
|
method: method
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
var ex = resp.Content.ToXError();
|
|
if (!ex.IsNull())
|
|
{
|
|
throw ex.ToException();
|
|
}
|
|
|
|
//
|
|
// UnAuthorized ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
// NotFound ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new XBaseRestResponse<T>
|
|
{
|
|
Response = resp,
|
|
Model = resp.Content.FromJSON<T>()
|
|
};
|
|
|
|
//
|
|
return result;
|
|
},
|
|
cancellationToken: cancellationToken);
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get User SelectBy Param
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
public string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var id = model.UserId;
|
|
var userName = model.UserName;
|
|
var email = model.Email;
|
|
var phoneNumber = model.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
//
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Url Address of Specified Enum by Filling Params
|
|
/// and Query Strings Attach ...
|
|
/// </summary>
|
|
/// <param name="endpoint"></param>
|
|
/// <param name="attachBaseUrl"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
public string PrepareUrl(
|
|
Enum endpoint,
|
|
bool attachBaseUrl = false,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
)
|
|
{
|
|
//
|
|
// Retrieving Url Template ...
|
|
var url = endpoint.GetStringValue();
|
|
|
|
//
|
|
// Filling Parmas and Query Strings of Url ...
|
|
url = PrepareUrl(
|
|
url: url,
|
|
@params: @params,
|
|
queryStrings: queryStrings,
|
|
attachBaseUrl: attachBaseUrl
|
|
);
|
|
|
|
//
|
|
return url;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Url Address by Filling Params
|
|
/// and Query Strings Attach ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="attachBaseUrl"></param>
|
|
/// <param name="@params"></param>
|
|
/// <param name="queryStrings"></param>
|
|
/// <returns></returns>
|
|
public string PrepareUrl(
|
|
string url,
|
|
bool attachBaseUrl = false,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
)
|
|
{
|
|
//
|
|
if (attachBaseUrl)
|
|
{
|
|
//
|
|
var baseUrl = BaseUrl;
|
|
if (!baseUrl.EndsWith("/"))
|
|
{
|
|
baseUrl = $"{baseUrl}/";
|
|
}
|
|
|
|
//
|
|
url = $"{baseUrl}{url}";
|
|
}
|
|
|
|
//
|
|
// Add Route Payloads ...
|
|
if (!@params.IsNull() && @params.Count > 0)
|
|
{
|
|
//
|
|
var enumerator = @params.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url = url.Replace(item.Key, item.Value.ToUrlEncoded());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add Query Strings ...
|
|
if (!queryStrings.IsNull() && queryStrings.Count > 0)
|
|
{
|
|
//
|
|
url = $"{url}?";
|
|
var enumerator = queryStrings.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url += $"{item.Key}={item.Value.ToUrlEncoded()}&";
|
|
}
|
|
|
|
//
|
|
// remove lates & ...
|
|
if (url.EndsWith("&"))
|
|
{
|
|
url = url.Substring(0, url.Length - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
return url;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts UserInfo to TokenResponse model ...
|
|
/// </summary>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public XTokenResponse ToTokenResponse(XUserClaimsInfoDto userInfo = null)
|
|
{
|
|
//
|
|
XTokenResponse result = null;
|
|
|
|
//
|
|
if (!userInfo.IsNull())
|
|
{
|
|
//
|
|
result = new XTokenResponse
|
|
{
|
|
AccessToken = userInfo.AccessToken.IsNullOrEmpty()
|
|
? ""
|
|
: userInfo.AccessToken,
|
|
RefreshToken = userInfo.RefreshToken.IsNullOrEmpty()
|
|
? ""
|
|
: userInfo.RefreshToken,
|
|
ExpiresAt = userInfo.ExpiresAt,
|
|
};
|
|
|
|
//
|
|
if (userInfo.AccessToken.IsNullOrEmpty())
|
|
{
|
|
result = null;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XIdentityProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Serialization;
|
|
using RestSharp;
|
|
using RestSharp.Authenticators;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xHttpService.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Models;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XIdentityProvider : IXIdentityProvider {
|
|
private readonly IXTokenProvider tokenProvider;
|
|
private readonly IHostingEnvironment environment;
|
|
private JsonSerializerSettings jsonSerializerSettings;
|
|
private readonly XValidationProvider validationProvider;
|
|
private readonly XIdentityServiceConfiguration identityConfiguration;
|
|
|
|
public ILogger<XIdentityProvider> Logger { get; }
|
|
public IXSecurityProvider SecurityProvider { get; }
|
|
|
|
public string BaseUrl { get; }
|
|
public string RevisionSecretKey { get; }
|
|
public bool ReadResponseAsString { get; set; }
|
|
|
|
public XIdentityProvider (
|
|
IXTokenProvider tokenProvider,
|
|
IHostingEnvironment environment,
|
|
ILogger<XIdentityProvider> logger,
|
|
IXSecurityProvider securityProvider,
|
|
XIdentityServiceConfiguration identityConfiguration,
|
|
XValidationProvider validationProvider
|
|
) {
|
|
//
|
|
BaseUrl = identityConfiguration.Authority;
|
|
RevisionSecretKey = identityConfiguration.XRevisionSecretKey;
|
|
|
|
//
|
|
this.environment = environment;
|
|
Logger = logger;
|
|
SecurityProvider = securityProvider;
|
|
|
|
//
|
|
this.identityConfiguration = identityConfiguration;
|
|
this.validationProvider = validationProvider;
|
|
this.jsonSerializerSettings = new JsonSerializerSettings {
|
|
ContractResolver = new CamelCasePropertyNamesContractResolver ()
|
|
};
|
|
|
|
//
|
|
this.tokenProvider = tokenProvider;
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Get an Instance of Http Client
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public HttpClient GetHttpClient () {
|
|
//
|
|
HttpClient httpClient = null;
|
|
|
|
//
|
|
// httpClient = new HttpClient ();
|
|
var httpClientHandler = new HttpClientHandler () {
|
|
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
|
|
//
|
|
Logger.LogInformation (
|
|
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
|
|
);
|
|
|
|
//
|
|
return true;
|
|
},
|
|
ClientCertificateOptions = ClientCertificateOption.Manual,
|
|
};
|
|
httpClient = new HttpClient (httpClientHandler);
|
|
|
|
//
|
|
// Set Timeout ...
|
|
// TODO: Fix this ...
|
|
// httpClient.Timeout = TimeSpan
|
|
// .FromSeconds (identityConfiguration.DefaultClientTimeout);
|
|
|
|
//
|
|
return httpClient;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestClient
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public RestClient GetRestClient (XTokenResponse tokens = null) {
|
|
//
|
|
var client = new RestClient (BaseUrl);
|
|
|
|
//
|
|
// Set Authenticator ...
|
|
if (!tokens.IsNull () &&
|
|
!tokens.AccessToken.IsNullOrEmpty ()) {
|
|
client.Authenticator = new JwtAuthenticator (tokens.AccessToken);
|
|
}
|
|
|
|
//
|
|
// Refresh Token ...
|
|
if (!tokens.IsNull () &&
|
|
!tokens.RefreshToken.IsNullOrEmpty ()) {
|
|
client.AddDefaultHeader (XAuthorization.RefreshToken, tokens.RefreshToken);
|
|
}
|
|
|
|
//
|
|
// ExpiresAt ...
|
|
if (!tokens.IsNull () &&
|
|
tokens.ExpiresAt > 0) {
|
|
client.AddDefaultHeader (XAuthorization.ExpiresAt, tokens.ExpiresAt.AsHttpParamString ());
|
|
}
|
|
|
|
//
|
|
// Set Default Timeout ...
|
|
client.Timeout = identityConfiguration.DefaultClientTimeout;
|
|
|
|
//
|
|
// SSL Validation Handler ...
|
|
client.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => {
|
|
//
|
|
Logger.LogInformation (
|
|
$"XSSL Handler: {Environment.NewLine}, sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
|
|
);
|
|
|
|
//
|
|
return true;
|
|
};
|
|
|
|
//
|
|
return client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get an Instance of RestRequest
|
|
/// </summary>
|
|
public RestRequest GetRestRequet (
|
|
XApiAccountEndpoint endpoint,
|
|
bool addXPoweredValue = true,
|
|
IDictionary<string, string> @params = null,
|
|
IDictionary<string, string> headers = null,
|
|
IDictionary<string, string> queryStrings = null
|
|
) {
|
|
//
|
|
var url = endpoint.GetStringValue ();
|
|
|
|
//
|
|
// Add Route Payloads ...
|
|
if (!@params.IsNull () && @params.Count > 0) {
|
|
//
|
|
var enumerator = @params.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url = url.Replace (item.Key, item.Value.ToUrlEncoded ());
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add Query Strings ...
|
|
if (!queryStrings.IsNull () && queryStrings.Count > 0) {
|
|
//
|
|
url = $"{url}?";
|
|
var enumerator = queryStrings.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
|
|
//
|
|
url += $"{item.Key}={item.Value.ToUrlEncoded ()}&";
|
|
}
|
|
|
|
//
|
|
// remove lates & ...
|
|
if (url.EndsWith ("&")) {
|
|
url = url.Substring (0, url.Length - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create request ...
|
|
var request = new RestRequest (url, DataFormat.Json);
|
|
|
|
//
|
|
if (addXPoweredValue) {
|
|
request.AddHeader (XAuthorization.XPoweredBy, identityConfiguration.XPoweredValue);
|
|
}
|
|
|
|
//
|
|
// Add Headers to request ...
|
|
if (!headers.IsNull () && headers.Count > 0) {
|
|
//
|
|
var enumerator = headers.GetEnumerator ();
|
|
while (enumerator.MoveNext ()) {
|
|
//
|
|
var item = enumerator.Current;
|
|
request.AddHeader (item.Key, item.Value);
|
|
}
|
|
}
|
|
|
|
//
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Call Specific Request and retrieve Response
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="request"></param>
|
|
/// <param name="method"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public async Task<T> RunRestRequest<T> (
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true
|
|
) {
|
|
//
|
|
var response = await Task.Run (async () => {
|
|
//
|
|
IRestResponse resp = null;
|
|
|
|
//
|
|
// Call Endpoint Service using Specified Method ...
|
|
switch (method) {
|
|
//
|
|
// Get ...
|
|
case XHttpMethod.GET:
|
|
resp = client.Get (request);
|
|
break;
|
|
|
|
//
|
|
// Put ...
|
|
case XHttpMethod.PUT:
|
|
resp = client.Put (request);
|
|
break;
|
|
|
|
//
|
|
// Post ...
|
|
case XHttpMethod.POST:
|
|
resp = client.Post (request);
|
|
break;
|
|
|
|
//
|
|
// Delete ...
|
|
case XHttpMethod.DELETE:
|
|
resp = client.Delete (request);
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (!resp.IsSuccessful) {
|
|
//
|
|
// Log Exception ...
|
|
Logger.LogError ($"Error: {resp.ErrorMessage}");
|
|
Logger.LogError ($"Exception: {resp.ErrorException.ToJSON()}");
|
|
if (!resp.ErrorMessage.IsNullOrEmpty () &&
|
|
resp.ErrorMessage.Contains ("timed out")) {
|
|
XException.Timeout.Throw ();
|
|
}
|
|
|
|
//
|
|
// TODO: Check UnAuthorized Status here for
|
|
// Refresh Tokens or Issue Correct Exception ...
|
|
if (supportRefreshingTokens &&
|
|
resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
|
//
|
|
var isRefreshed = request.Parameters.Any (rp =>
|
|
rp.Name == XParam.XIsRefreshed.GetStringValue () &&
|
|
rp.Value.ToString ().ToNormalString () == true.ToJSON ());
|
|
|
|
//
|
|
Logger.LogInformation ($"isRefreshed: {isRefreshed}");
|
|
|
|
//
|
|
// Get Access Token ...
|
|
XTokenResponse tokens = null;
|
|
var accessToken = request.Parameters.FirstOrDefault (rp =>
|
|
rp.Name.ToNormalString () == XAuthorization.Header.ToNormalString ()).Value.ToString ();
|
|
if (!accessToken.IsNullOrEmpty ()) {
|
|
//
|
|
accessToken = accessToken.Replace (XAuthorization.TokenIdentifier, "");
|
|
|
|
//
|
|
if (!accessToken.IsNullOrEmpty ()) {
|
|
tokens = await tokenProvider.RetrieveToken (accessToken);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Refresh Token and then re do request ...
|
|
if (!isRefreshed &&
|
|
!accessToken.IsNullOrEmpty () &&
|
|
!tokens.IsNull () &&
|
|
tokens.IsRefreshable ()) {
|
|
//
|
|
request.AddHeader (XParam.XIsRefreshed.GetStringValue (), true.ToJSON ());
|
|
|
|
//
|
|
// Refreshe Tokens ...
|
|
var refreshedTokens = await RefreshTokens (tokens);
|
|
|
|
//
|
|
// Renew Rest Client with Refreshed Tokens ...
|
|
var timeout = client.Timeout;
|
|
client = GetRestClient (refreshedTokens);
|
|
client.Timeout = Timeout.Infinite;
|
|
|
|
//
|
|
// Do Request Again using renew Client ...
|
|
return await RunRestRequest<T> (
|
|
client: client,
|
|
request: request,
|
|
method: method);
|
|
}
|
|
}
|
|
|
|
//
|
|
var ex = resp.Content.ToXError ();
|
|
if (!ex.IsNull ()) {
|
|
throw ex.ToException ();
|
|
}
|
|
|
|
//
|
|
// UnAuthorized ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
|
XException.NotAuthorized.Throw ();
|
|
}
|
|
|
|
//
|
|
// NotFound ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
|
|
XException.NotFound.Throw ();
|
|
}
|
|
|
|
//
|
|
XException.ActionFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = resp.Content.FromJSON<T> ();
|
|
return result;
|
|
});
|
|
|
|
//
|
|
return response;
|
|
}
|
|
public async Task<XBaseRestResponse<T>> RunRestRequestByResponse<T> (
|
|
RestClient client,
|
|
RestRequest request,
|
|
XHttpMethod method,
|
|
bool supportRefreshingTokens = true
|
|
) {
|
|
//
|
|
var response = await Task.Run (async () => {
|
|
//
|
|
IRestResponse resp = null;
|
|
|
|
//
|
|
// Call Endpoint Service using Specified Method ...
|
|
switch (method) {
|
|
//
|
|
// Get ...
|
|
case XHttpMethod.GET:
|
|
resp = client.Get (request);
|
|
break;
|
|
|
|
//
|
|
// Put ...
|
|
case XHttpMethod.PUT:
|
|
resp = client.Put (request);
|
|
break;
|
|
|
|
//
|
|
// Post ...
|
|
case XHttpMethod.POST:
|
|
resp = client.Post (request);
|
|
break;
|
|
|
|
//
|
|
// Delete ...
|
|
case XHttpMethod.DELETE:
|
|
resp = client.Delete (request);
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (!resp.IsSuccessful) {
|
|
//
|
|
// Log Exception ...
|
|
Logger.LogError ($"Error: {resp.ErrorMessage}");
|
|
Logger.LogError ($"Exception: {resp.ErrorException.ToJSON()}");
|
|
if (!resp.ErrorMessage.IsNullOrEmpty () &&
|
|
resp.ErrorMessage.Contains ("timed out")) {
|
|
XException.Timeout.Throw ();
|
|
}
|
|
|
|
//
|
|
// TODO: Check UnAuthorized Status here for
|
|
// Refresh Tokens or Issue Correct Exception ...
|
|
if (supportRefreshingTokens &&
|
|
resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
|
//
|
|
var isRefreshed = request.Parameters.Any (rp =>
|
|
rp.Name == XParam.XIsRefreshed.GetStringValue () &&
|
|
rp.Value.ToString ().ToNormalString () == true.ToJSON ());
|
|
|
|
//
|
|
Logger.LogInformation ($"isRefreshed: {isRefreshed}");
|
|
|
|
//
|
|
// Get Access Token ...
|
|
XTokenResponse tokens = null;
|
|
var accessToken = request.Parameters.FirstOrDefault (rp =>
|
|
rp.Name.ToNormalString () == XAuthorization.Header.ToNormalString ()).Value.ToString ();
|
|
if (!accessToken.IsNullOrEmpty ()) {
|
|
//
|
|
accessToken = accessToken.Replace (XAuthorization.TokenIdentifier, "");
|
|
|
|
//
|
|
if (!accessToken.IsNullOrEmpty ()) {
|
|
tokens = await tokenProvider.RetrieveToken (accessToken);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Refresh Token and then re do request ...
|
|
if (!isRefreshed &&
|
|
!accessToken.IsNullOrEmpty () &&
|
|
!tokens.IsNull () &&
|
|
tokens.IsRefreshable ()) {
|
|
//
|
|
request.AddHeader (XParam.XIsRefreshed.GetStringValue (), true.ToJSON ());
|
|
|
|
//
|
|
// Refreshe Tokens ...
|
|
var refreshedTokens = await RefreshTokens (tokens);
|
|
|
|
//
|
|
// Renew Rest Client with Refreshed Tokens ...
|
|
var timeout = client.Timeout;
|
|
client = GetRestClient (refreshedTokens);
|
|
client.Timeout = Timeout.Infinite;
|
|
|
|
//
|
|
// Do Request Again using renew Client ...
|
|
return await RunRestRequestByResponse<T> (
|
|
client: client,
|
|
request: request,
|
|
method: method
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
var ex = resp.Content.ToXError ();
|
|
if (!ex.IsNull ()) {
|
|
throw ex.ToException ();
|
|
}
|
|
|
|
//
|
|
// UnAuthorized ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) {
|
|
XException.NotAuthorized.Throw ();
|
|
}
|
|
|
|
//
|
|
// NotFound ...
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) {
|
|
XException.NotFound.Throw ();
|
|
}
|
|
|
|
//
|
|
XException.ActionFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = new XBaseRestResponse<T>
|
|
{
|
|
Response = resp,
|
|
Model = resp.Content.FromJSON<T> ()
|
|
};
|
|
|
|
//
|
|
return result;
|
|
});
|
|
|
|
//
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get User SelectBy Param
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
public string GetUserSelectByParam (
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull (model);
|
|
|
|
//
|
|
var id = model.UserId;
|
|
var userName = model.UserName;
|
|
var email = model.Email;
|
|
var phoneNumber = model.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null) {
|
|
//
|
|
if (excludes.Contains (XUserSelectBy.ID)) {
|
|
id = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.Email)) {
|
|
email = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.MobileNumber)) {
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains (XUserSelectBy.Username)) {
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty () ?
|
|
userName.IsNullOrEmpty () ?
|
|
email.IsNullOrEmpty () ?
|
|
phoneNumber.IsNullOrEmpty () ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty ()) {
|
|
XException.InvalidData.Throw ();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XInMemoryTokenProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public partial class XInMemoryTokenProvider : IXTokenProvider {
|
|
private IDictionary<string, XTokenResponse> DbContext;
|
|
|
|
public XInMemoryTokenProvider () {
|
|
//
|
|
this.DbContext = new Dictionary<string, XTokenResponse> ();
|
|
}
|
|
|
|
public async Task<bool> IsTokenExists (string accessToken) {
|
|
//
|
|
// Validate Args ...
|
|
if (accessToken.IsNullOrEmpty ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Process Result ...
|
|
var result = DbContext.Keys.Any (k => k == accessToken);
|
|
return await Task.FromResult (result);
|
|
}
|
|
|
|
public async Task<bool> IsTokenExists (XTokenResponse tokens) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokens.IsNull () ||
|
|
tokens.AccessToken.IsNullOrEmpty () ||
|
|
!await IsTokenExists (tokens.AccessToken)) {
|
|
return false;
|
|
};
|
|
|
|
//
|
|
// Process Result ...
|
|
var result = await IsTokenExists (tokens.AccessToken);
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> RemoveToken (string accessToken) {
|
|
//
|
|
// Validate Args ...
|
|
if (accessToken.IsNullOrEmpty ()) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Process Result ...
|
|
var result = DbContext.Remove (accessToken);
|
|
return await Task.FromResult (result);
|
|
}
|
|
|
|
public async Task<bool> RemoveToken (XTokenResponse tokens) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokens.IsNull () ||
|
|
tokens.AccessToken.IsNullOrEmpty () ||
|
|
!await IsTokenExists (tokens.AccessToken)) {
|
|
return false;
|
|
};
|
|
|
|
//
|
|
// Process Result ...
|
|
var result = await RemoveToken (tokens.AccessToken);
|
|
return result;
|
|
}
|
|
|
|
public async Task<XTokenResponse> RetrieveToken (string accessToken) {
|
|
//
|
|
// Validate Args ...
|
|
if (accessToken.IsNullOrEmpty () ||
|
|
!await IsTokenExists (accessToken)) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
// Process Result ...
|
|
var result = DbContext[accessToken];
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> AddToken (XTokenResponse tokens) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokens.IsNull () ||
|
|
tokens.AccessToken.IsNullOrEmpty () ||
|
|
await IsTokenExists (tokens.AccessToken)) {
|
|
return false;
|
|
};
|
|
|
|
//
|
|
// Process Result ...
|
|
try {
|
|
//
|
|
DbContext.Add (tokens.AccessToken, tokens);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> UpdateToken (XTokenResponse tokens) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokens.IsNull () ||
|
|
tokens.AccessToken.IsNullOrEmpty () ||
|
|
!await IsTokenExists (tokens.AccessToken)) {
|
|
return false;
|
|
};
|
|
|
|
//
|
|
// Process Result ...
|
|
try {
|
|
//
|
|
DbContext[tokens.AccessToken] = tokens;
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> AddOrUpdateToken (XTokenResponse tokens) {
|
|
//
|
|
// Validate Args ...
|
|
if (tokens.IsNull () ||
|
|
tokens.AccessToken.IsNullOrEmpty ()
|
|
) {
|
|
return false;
|
|
};
|
|
|
|
//
|
|
// Process Result ...
|
|
try {
|
|
//
|
|
var isExists = await IsTokenExists (tokens);
|
|
if (isExists) {
|
|
return await UpdateToken (tokens);
|
|
} else {
|
|
return await AddToken (tokens);
|
|
}
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Providers\XProxyHelper.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Web;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Providers {
|
|
public class XProxyHelper : IXProxyHelper {
|
|
//
|
|
#region Props ...
|
|
public XProxyConfiguration Configuration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XProxyHelper (XProxyConfiguration configuration) {
|
|
this.Configuration = configuration;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Validate XProxy Configuration for Client ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ValidateConfiguration () {
|
|
//
|
|
var result = !Configuration.IsNull () &&
|
|
!Configuration.Host.IsNullOrEmpty () &&
|
|
Configuration.Host.IsValidUrl () &&
|
|
Configuration.Routes.HasChild ();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrie Normalize Host ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string NormalizeHost () {
|
|
//
|
|
var result = string.Empty;
|
|
|
|
//
|
|
if (!Configuration.IsNull () &&
|
|
!Configuration.Host.IsNullOrEmpty () &&
|
|
Configuration.Host.IsValidUrl ()
|
|
) {
|
|
//
|
|
result = Configuration.Host
|
|
.ToNormalString ();
|
|
|
|
//
|
|
if (result.EndsWith ("/")) {
|
|
result = result.Substring (0, result.Length - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all registred Routes ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<XProxyRouteDescriptor> GetRoutes () {
|
|
//
|
|
// Validate Args ...
|
|
if (Configuration.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return Configuration.Routes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Prepared url of Routes ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<string> GetRouteUrls () {
|
|
//
|
|
var normalHost = NormalizeHost ();
|
|
if (normalHost.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = GetRoutes ()
|
|
.Select (r => $"{normalHost}{r.Route}");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find an Specific Route ...
|
|
/// </summary>
|
|
/// <param name="whereClause"></param>
|
|
/// <returns></returns>
|
|
public XProxyRouteDescriptor FindRoute (Expression<Func<XProxyRouteDescriptor, bool>> whereClause) {
|
|
//
|
|
// Validate Arg ...
|
|
if (whereClause.IsNull ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var whereFunc = whereClause
|
|
.Compile ();
|
|
|
|
//
|
|
var result = GetRoutes ()
|
|
.FirstOrDefault (whereFunc);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare a request url for a Proxy Route ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="descriptor"></param>
|
|
/// <returns></returns>
|
|
public string PrepareActionUrlForXProxyRoute (
|
|
string url,
|
|
XProxyRouteDescriptor descriptor
|
|
) {
|
|
//
|
|
if (!url.IsValidUrl () ||
|
|
url.IsNullOrEmpty () ||
|
|
!ValidateConfiguration ()
|
|
) {
|
|
throw XException.InvalidArgs.ToException ();
|
|
}
|
|
|
|
//
|
|
// find Route ...
|
|
var routeDescriptor = GetRoutes ()
|
|
.FirstOrDefault (r => r
|
|
.IsSameContent (descriptor)
|
|
);
|
|
|
|
//
|
|
// Validate Route Descriptor ...
|
|
if (
|
|
routeDescriptor.IsNull () ||
|
|
routeDescriptor.Route.IsNullOrEmpty ()
|
|
) {
|
|
throw XException.InvalidArgs.ToException ();
|
|
}
|
|
|
|
//
|
|
// Retrieve and Validate Host Address ...
|
|
var host = NormalizeHost ();
|
|
if (!host.IsValidUrl () ||
|
|
host.IsNullOrEmpty ()
|
|
) {
|
|
throw XException.InvalidArgs.ToException ();
|
|
}
|
|
|
|
//
|
|
url = $"{host}{routeDescriptor.Route}/{HttpUtility.UrlEncode(url)}";
|
|
|
|
//
|
|
return url;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare a request url for a Selected Proxy Route ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <param name="whereClause"></param>
|
|
/// <returns></returns>
|
|
public string PrepareActionUrlForXProxyRoute (
|
|
string url,
|
|
Expression<Func<XProxyRouteDescriptor, bool>> whereClause
|
|
) {
|
|
//
|
|
if (!url.IsValidUrl () ||
|
|
url.IsNullOrEmpty () ||
|
|
whereClause.IsNull () ||
|
|
!ValidateConfiguration ()
|
|
) {
|
|
throw XException.InvalidArgs.ToException ();
|
|
}
|
|
|
|
//
|
|
var descriptor = FindRoute (whereClause);
|
|
|
|
//
|
|
// find Route ...
|
|
var result = PrepareActionUrlForXProxyRoute (
|
|
url: url,
|
|
descriptor: descriptor
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Security\XSecurityProvider.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xIdentityService.Security {
|
|
public partial class XSecurityProvider : IXSecurityProvider {
|
|
private readonly string secretKey;
|
|
private readonly byte[] iv;
|
|
private readonly byte[] key;
|
|
private readonly XValidationProvider validationProvider;
|
|
|
|
public XSecurityProvider (
|
|
XIdentityServiceConfiguration identityConfiguration,
|
|
XValidationProvider validationProvider
|
|
) {
|
|
//
|
|
this.secretKey = identityConfiguration.XRevisionSecretKey.ToMd5String ();
|
|
this.validationProvider = validationProvider;
|
|
|
|
//
|
|
var ivBytes = new byte[16];
|
|
var keyBytes = new byte[32];
|
|
var secretBytes = Encoding.UTF8.GetBytes (this.secretKey);
|
|
|
|
//
|
|
Array.Copy (
|
|
secretBytes,
|
|
ivBytes,
|
|
secretBytes.Length < ivBytes.Length ?
|
|
secretBytes.Length :
|
|
ivBytes.Length
|
|
);
|
|
this.iv = ivBytes;
|
|
|
|
//
|
|
Array.Copy (
|
|
secretBytes,
|
|
keyBytes,
|
|
secretBytes.Length < keyBytes.Length ?
|
|
secretBytes.Length :
|
|
keyBytes.Length
|
|
);
|
|
this.key = keyBytes;
|
|
|
|
// Encoding.UTF8.GetBytes (this.secretKey);
|
|
}
|
|
|
|
public string Encrypt (string plainText) {
|
|
//
|
|
validationProvider.NotEmpty (plainText);
|
|
|
|
//
|
|
var textBytes = Encoding.UTF8.GetBytes (plainText);
|
|
var result = EncryptFromBytes (textBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string Decrypt (string cipherText) {
|
|
//
|
|
validationProvider.NotEmpty (cipherText);
|
|
|
|
//
|
|
var cipherBytes = Convert.FromBase64String (cipherText);
|
|
var result = DecryptFromBytes (cipherBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string EncryptFromBytes (byte[] textBytes) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull (textBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
byte[] encryptedBytes = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged ()) {
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
//
|
|
using (var encryptor = rijAlg.CreateEncryptor (rijAlg.Key, rijAlg.IV)) {
|
|
encryptedBytes = encryptor.TransformFinalBlock (textBytes, 0, textBytes.Length);
|
|
}
|
|
}
|
|
|
|
//
|
|
return Convert.ToBase64String (encryptedBytes);
|
|
}
|
|
|
|
public string DecryptFromBytes (byte[] cipherBytes) {
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull (cipherBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
string plaintext = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged ()) {
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
// Create a decrytor to perform the stream transform.
|
|
var decryptor = rijAlg.CreateDecryptor (rijAlg.Key, rijAlg.IV);
|
|
|
|
// Create the streams used for decryption.
|
|
using (var msDecrypt = new MemoryStream (cipherBytes)) {
|
|
using (var csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read)) {
|
|
using (var srDecrypt = new StreamReader (csDecrypt)) {
|
|
// Read the decrypted bytes from the decrypting stream
|
|
// and place them in a string.
|
|
plaintext = srDecrypt.ReadToEnd ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return plaintext;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xMessageService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string MESSAGE_NODE_NAME = "MessageConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Constants\xMessageServiceConstants.cs
|
|
|
|
namespace xMessageService.Constants {
|
|
public struct xMessageServiceConstants {
|
|
public const string DEFAULT_EMPTY_PROVIDER = "EMPTY";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xMessageService.Constants;
|
|
using xMessageService.Interfaces;
|
|
using xMessageService.Models;
|
|
using xMessageService.Providers;
|
|
|
|
namespace xMessageService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XMessage Configuration from App Settings
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <returns></returns>
|
|
public static XMessageConfiguration GetXMessageConfiguration (this IConfiguration config) {
|
|
//
|
|
var xMessageConfigSection = config.GetSection (ConfigurationNodeNames.MESSAGE_NODE_NAME);
|
|
var xMessageConfiguration = xMessageConfigSection.Get<XMessageConfiguration> ();
|
|
|
|
//
|
|
var defaultMailConfiguration = new Dictionary<string, XMailConfiguration> {
|
|
["EMPTY"] =
|
|
new XMailConfiguration {
|
|
Title = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
|
Host = "",
|
|
Port = 25,
|
|
EnableSsl = false,
|
|
Username = "",
|
|
Password = ""
|
|
}
|
|
};
|
|
|
|
//
|
|
var defaultSmsConfiguration = new Dictionary<string, XSmsConfiguration> {
|
|
["EMPTY"] =
|
|
new XSmsConfiguration {
|
|
ServiceUrl = "",
|
|
Username = "",
|
|
Password = "",
|
|
LineNumber = "",
|
|
UserApiKey = "",
|
|
SecretKey = "",
|
|
}
|
|
};
|
|
|
|
//
|
|
if (xMessageConfiguration.IsNull ()) {
|
|
//
|
|
xMessageConfiguration = new XMessageConfiguration {
|
|
DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
|
DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
|
|
MailConfigurations = defaultMailConfiguration,
|
|
SmsConfigurations = defaultSmsConfiguration
|
|
};
|
|
|
|
//
|
|
// Warn Message is Default Configuration ...
|
|
Console.WriteLine ($"IMPORTANT: xMessageService Configuration is Default, so the Service can't works properly ...");
|
|
}
|
|
|
|
//
|
|
// Handle Default Mail Provider ...
|
|
if (xMessageConfiguration.DefaultMailProvider.IsNullOrEmpty ()) {
|
|
//
|
|
if (xMessageConfiguration.IsNull () ||
|
|
//
|
|
xMessageConfiguration.MailConfigurations.IsNull () ||
|
|
xMessageConfiguration.MailConfigurations.Count == 0) {
|
|
//
|
|
Console.WriteLine ("There is no defined Mail Provider Configurations ...");
|
|
xMessageConfiguration.DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
|
|
}
|
|
|
|
//
|
|
if (xMessageConfiguration.DefaultMailProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
|
|
xMessageConfiguration.MailConfigurations = defaultMailConfiguration;
|
|
} else {
|
|
xMessageConfiguration.DefaultMailProvider = xMessageConfiguration.MailConfigurations.Keys.First ();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle Default SMS Provider ...
|
|
if (xMessageConfiguration.DefaultSMSProvider.IsNullOrEmpty ()) {
|
|
//
|
|
if (xMessageConfiguration.IsNull () ||
|
|
xMessageConfiguration.SmsConfigurations.IsNull () ||
|
|
xMessageConfiguration.SmsConfigurations.Count == 0) {
|
|
//
|
|
Console.WriteLine ("There is no defined SMS Provider Configurations ...");
|
|
xMessageConfiguration.DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
|
|
}
|
|
|
|
//
|
|
if (xMessageConfiguration.DefaultSMSProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
|
|
xMessageConfiguration.SmsConfigurations = defaultSmsConfiguration;
|
|
} else {
|
|
xMessageConfiguration.DefaultSMSProvider = xMessageConfiguration.SmsConfigurations.Keys.First ();
|
|
}
|
|
}
|
|
|
|
//
|
|
return xMessageConfiguration;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XMessage Service
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
public static void AddXMessageService (this IServiceCollection services, IConfiguration config) {
|
|
//
|
|
var xMessageConfiguration = config.GetXMessageConfiguration ();
|
|
services.AddSingleton<XMessageConfiguration> (xMessageConfiguration);
|
|
|
|
//
|
|
// Register SMS Service ...
|
|
var xSmsService = new XSmsService (
|
|
xMessageConfiguration.DefaultSMSProvider,
|
|
xMessageConfiguration.SmsConfigurations
|
|
);
|
|
services.AddSingleton<IXSmsService> (xSmsService);
|
|
|
|
//
|
|
// Register Mail Service ...
|
|
var xMailService = new XMailService (
|
|
xMessageConfiguration.DefaultMailProvider,
|
|
xMessageConfiguration.MailConfigurations
|
|
);
|
|
services.AddSingleton<IXMailService> (xMailService);
|
|
|
|
//
|
|
// Register MEssage Provider ...
|
|
services.AddSingleton<IXMessageProvider, XMessageProvider> ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMailService.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Interfaces {
|
|
public partial interface IXMailService {
|
|
Task SendMailAsync (
|
|
XMessage message,
|
|
string provider = null
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXMessageProvider.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Interfaces {
|
|
public partial interface IXMessageProvider {
|
|
bool IsReady (
|
|
bool? checkMailService = false,
|
|
bool? checkSmsService = false
|
|
);
|
|
|
|
Task SendMailAsync (
|
|
XMessage message,
|
|
string provider = null,
|
|
bool throwException = true,
|
|
Exception exception = null
|
|
);
|
|
|
|
Task SendSmsAsync (
|
|
XMessage message,
|
|
string provider = null,
|
|
bool throwException = true,
|
|
Exception exception = null
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Interfaces\IXSmsService.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Interfaces {
|
|
public partial interface IXSmsService {
|
|
Task SendSmsAsync (
|
|
XMessage message,
|
|
string provider = null
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Models\XMailConfiguration.cs
|
|
|
|
namespace xMessageService.Models {
|
|
public partial class XMailConfiguration {
|
|
public string Title { get; set; }
|
|
public string Host { get; set; }
|
|
public int Port { get; set; }
|
|
public bool EnableSsl { get; set; }
|
|
public string Username { get; set; }
|
|
public string Password { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessage.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xMessageService.Models {
|
|
public partial class XMessage : XBaseDto {
|
|
public HashSet<string> Recievers { get; set; } = new HashSet<string> ();
|
|
public string Message { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Models\XMessageConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace xMessageService.Models {
|
|
public partial class XMessageConfiguration {
|
|
public string DefaultSMSProvider { get; set; }
|
|
public string DefaultMailProvider { get; set; }
|
|
public IDictionary<string, XMailConfiguration> MailConfigurations { get; set; }
|
|
public IDictionary<string, XSmsConfiguration> SmsConfigurations { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Models\XSmsConfiguration.cs
|
|
|
|
namespace xMessageService.Models {
|
|
public partial class XSmsConfiguration {
|
|
public string ServiceUrl { get; set; }
|
|
public string Username { get; set; }
|
|
public string Password { get; set; }
|
|
public string LineNumber { get; set; }
|
|
public string UserApiKey { get; set; }
|
|
public string SecretKey { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMailService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Mail;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xMessageService.Interfaces;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Providers {
|
|
public partial class XMailService : IXMailService {
|
|
private SmtpClient smtpClient;
|
|
private readonly string defaultProvider;
|
|
private readonly IDictionary<string, XMailConfiguration> configurations;
|
|
|
|
public XMailService (
|
|
string defaultProvider,
|
|
IDictionary<string, XMailConfiguration> configurations
|
|
) {
|
|
this.defaultProvider = defaultProvider;
|
|
this.configurations = configurations;
|
|
|
|
//
|
|
// Get instance of SMTP Client ...
|
|
PrepareSmtpClient ();
|
|
}
|
|
|
|
public Task SendMailAsync (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
// Run Send Mail Asynchronous ...
|
|
return Task.Run (() => {
|
|
SendMail (message, provider);
|
|
});
|
|
}
|
|
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Validate and Retrieve Provider Configuration for Service
|
|
/// </summary>
|
|
/// <param name="provider"></param>
|
|
/// <returns></returns>
|
|
private XMailConfiguration GetConfiguration (string provider = null) {
|
|
//
|
|
if (provider.IsNullOrEmpty ()) {
|
|
provider = defaultProvider;
|
|
}
|
|
|
|
//
|
|
if (!configurations.Keys.Contains (provider)) {
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
return configurations[provider];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare SMTP Client by Using Specified/Default Provider
|
|
/// </summary>
|
|
/// <param name="provider"></param>
|
|
private void PrepareSmtpClient (string provider = null) {
|
|
//
|
|
var config = GetConfiguration (provider);
|
|
if (config.IsNull()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
smtpClient = new SmtpClient () {
|
|
Host = config.Host,
|
|
Port = config.Port,
|
|
EnableSsl = config.EnableSsl,
|
|
UseDefaultCredentials = false,
|
|
Credentials = new NetworkCredential (
|
|
config.Username,
|
|
config.Password)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Mail Message With Specified/Default Provider
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="provider"></param>
|
|
/// <returns></returns>
|
|
private MailMessage PrepareMailMessage (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
if (message == null ||
|
|
message.Message.IsNullOrEmpty () ||
|
|
message.Recievers.Count == 0) {
|
|
XException.InvalidMessage.Throw ();
|
|
}
|
|
|
|
//
|
|
var config = GetConfiguration (provider);
|
|
var mailMessage = new MailMessage () {
|
|
From = new MailAddress (config.Username),
|
|
Subject = config.Title,
|
|
Body = message.Message
|
|
};
|
|
|
|
//
|
|
foreach (var reciever in message.Recievers) {
|
|
mailMessage.To.Add (reciever);
|
|
}
|
|
|
|
//
|
|
return mailMessage;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send Mail Using Specified/Default Provider
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="provider"></param>
|
|
private void SendMail (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
if (smtpClient.IsNull()) {
|
|
//
|
|
Console.WriteLine ($"SMTP Error: MessageServiceInitialFailed ...");
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
var mailMessage = PrepareMailMessage (message, provider);
|
|
|
|
//
|
|
try {
|
|
smtpClient.Send (mailMessage);
|
|
} catch (Exception ex) {
|
|
//
|
|
Console.WriteLine ($"SMTP Error: {ex.Message}");
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Providers\XMessageProvider.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xMessageService.Interfaces;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Providers {
|
|
public partial class XMessageProvider : IXMessageProvider {
|
|
private readonly XMessageConfiguration configuration;
|
|
private readonly ILogger<XMessageProvider> logger;
|
|
private readonly IXSmsService smsService;
|
|
private readonly IXMailService mailService;
|
|
|
|
public XMessageProvider (
|
|
XMessageConfiguration configuration,
|
|
ILogger<XMessageProvider> logger,
|
|
IXSmsService smsService,
|
|
IXMailService mailService
|
|
) {
|
|
this.configuration = configuration;
|
|
this.logger = logger;
|
|
this.smsService = smsService;
|
|
this.mailService = mailService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send a Mail Message
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="provider"></param>
|
|
/// <param name="throwException"></param>
|
|
/// <param name="exception"></param>
|
|
/// <returns></returns>
|
|
public async Task SendMailAsync (
|
|
XMessage message,
|
|
string provider = null,
|
|
bool throwException = true,
|
|
Exception exception = null
|
|
) {
|
|
//
|
|
if (exception.IsNull ()) {
|
|
exception = XException.ActionFailed.ToException ();
|
|
}
|
|
|
|
//
|
|
try {
|
|
await mailService.SendMailAsync (message, provider);
|
|
} catch (Exception ex) {
|
|
//
|
|
logger.LogError ($"Exeption: {ex.Message}");
|
|
|
|
//
|
|
if (throwException) {
|
|
throw exception;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send SMS Message
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
public async Task SendSmsAsync (
|
|
XMessage message,
|
|
string provider = null,
|
|
bool throwException = true,
|
|
Exception exception = null
|
|
) {
|
|
//
|
|
if (exception.IsNull ()) {
|
|
exception = XException.ActionFailed.ToException ();
|
|
}
|
|
|
|
//
|
|
try {
|
|
await smsService.SendSmsAsync (message, provider);
|
|
} catch {
|
|
if (throwException) {
|
|
throw exception;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Message Provider is Ready or not
|
|
/// </summary>
|
|
/// <param name="checkMailService"></param>
|
|
/// <param name="checkSmsService"></param>
|
|
/// <returns></returns>
|
|
public bool IsReady (
|
|
bool? checkMailService = false,
|
|
bool? checkSmsService = false
|
|
) {
|
|
//
|
|
var result = true;
|
|
|
|
//
|
|
// Check Mail Service ...
|
|
if (checkMailService.HasValue &&
|
|
checkMailService.GetValueOrDefault ()) {
|
|
result = result && mailService != null;
|
|
}
|
|
|
|
//
|
|
// Check Sms Service ...
|
|
if (checkSmsService.HasValue &&
|
|
checkSmsService.GetValueOrDefault ()) {
|
|
result = result && smsService != null;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xMessageService\Providers\XSmsService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using PhoneNumbers;
|
|
using RestSharp;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xMessageService.Interfaces;
|
|
using xMessageService.Models;
|
|
|
|
namespace xMessageService.Providers {
|
|
public partial class XSmsService : IXSmsService {
|
|
private string serviceUrl;
|
|
private readonly string defaultProvider;
|
|
private readonly IDictionary<string, XSmsConfiguration> configurations;
|
|
|
|
public XSmsService (
|
|
string defaultProvider,
|
|
IDictionary<string, XSmsConfiguration> configurations
|
|
) {
|
|
this.defaultProvider = defaultProvider;
|
|
this.configurations = configurations;
|
|
|
|
//
|
|
PrepareServiceUrl ();
|
|
}
|
|
|
|
public Task SendSmsAsync (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
// Run Send SMS Asynchronous ...
|
|
return Task.Run (() => {
|
|
SendSMS (message, provider);
|
|
});
|
|
}
|
|
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Prepare Service Url for Specified/Default Provider
|
|
/// </summary>
|
|
/// <param name="provider"></param>
|
|
private void PrepareServiceUrl (string provider = null) {
|
|
//
|
|
if (provider.IsNullOrEmpty ()) {
|
|
provider = defaultProvider;
|
|
}
|
|
|
|
//
|
|
var config = GetConfiguration (provider);
|
|
if (config.IsNull ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
serviceUrl = config.ServiceUrl;
|
|
serviceUrl += "&username=" + config.Username + "&password=" + config.Password + "&";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Service url for Integrating XMessage by
|
|
/// using Specified/Default Provider Configurations
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="provider"></param>
|
|
private void PrepareSmsMessage (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
if (message == null ||
|
|
message.Message.IsNullOrEmpty () ||
|
|
message.Recievers.Count == 0) {
|
|
XException.InvalidMessage.Throw ();
|
|
}
|
|
|
|
//
|
|
// Validating Mobile Numbers ...
|
|
var phoneNumberUtil = PhoneNumbers.PhoneNumberUtil.GetInstance ();
|
|
var recieversList = "";
|
|
|
|
//
|
|
PrepareServiceUrl (provider);
|
|
|
|
//
|
|
foreach (var reciever in message.Recievers) {
|
|
try {
|
|
//
|
|
var mPhoneNumber = phoneNumberUtil.Parse (reciever, null);
|
|
if (phoneNumberUtil.IsValidNumber (mPhoneNumber)) {
|
|
//
|
|
// Format Phone Numbers to the '+989120000000' pattern ...
|
|
var recieverPhone = phoneNumberUtil.Format (mPhoneNumber, PhoneNumberFormat.E164);
|
|
if (recieversList.Length > 0) {
|
|
recieversList += ",";
|
|
}
|
|
recieversList += reciever;
|
|
}
|
|
} catch { }
|
|
}
|
|
|
|
//
|
|
var config = GetConfiguration ();
|
|
|
|
//
|
|
// Preparing All Content and Configurations for Sending Messages ...
|
|
serviceUrl += "to=" +
|
|
recieversList +
|
|
"&message=" +
|
|
message.Message +
|
|
"&from=" +
|
|
config.LineNumber +
|
|
"&flash=" +
|
|
false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send a Message as SMS by Specified/Default Provider
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="provider"></param>
|
|
private void SendSMS (
|
|
XMessage message,
|
|
string provider = null
|
|
) {
|
|
//
|
|
if (serviceUrl.IsNullOrEmpty ()) {
|
|
//
|
|
Console.WriteLine ($"SMS Error: MessageServiceInitialFailed ...");
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
try {
|
|
//
|
|
// preparing Service Url based on message data ...
|
|
PrepareSmsMessage (message, provider);
|
|
|
|
//
|
|
// Implementing Service Calling Using RestSharp Library ...
|
|
// We Select RestSharp because it supports Sync/Async Calls ...
|
|
var client = new RestClient (serviceUrl);
|
|
var request = new RestRequest (Method.POST);
|
|
|
|
//
|
|
// Send Request ...
|
|
var response = client.Execute (request);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine ($"SMS Error: {ex.Message}");
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate and Retrieve Provider Configuration for Service
|
|
/// </summary>
|
|
/// <param name="provider"></param>
|
|
/// <returns></returns>
|
|
private XSmsConfiguration GetConfiguration (string provider = null) {
|
|
//
|
|
if (
|
|
provider.IsNullOrEmpty () ||
|
|
provider.ToNormalString () == "empty"
|
|
) {
|
|
//
|
|
provider = defaultProvider;
|
|
return null;
|
|
}
|
|
|
|
//
|
|
if (!configurations.Keys.Contains (provider)) {
|
|
XException.MessageServiceInitialFailed.Throw ();
|
|
}
|
|
|
|
//
|
|
return configurations[provider];
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseClass.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// a Base class which carry required things as a Father for it's childs ...
|
|
/// </summary>
|
|
public abstract class XBaseClass {
|
|
//
|
|
#region Properties ...
|
|
/// <summary>
|
|
/// LogTag which Specified for this class ...
|
|
/// </summary>
|
|
private readonly string LOG_TAG;
|
|
|
|
/// <summary>
|
|
/// logger instance ...
|
|
/// </summary>
|
|
private readonly ILogger logger;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseClass (ILoggerFactory loggerFactory) {
|
|
//
|
|
// Preparing Log Tag ...
|
|
LOG_TAG = this.GetType ().Name;
|
|
|
|
//
|
|
Type classType = this.GetType ();
|
|
logger = loggerFactory.CreateLogger (classType);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Protected ...
|
|
/// <summary>
|
|
/// Extract Prepared Log MEssage ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
protected virtual string GetLogMessage (string message) {
|
|
//
|
|
// Prepare Log Message ...
|
|
message = $"{LOG_TAG} => {message}";
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logging specific Message ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="logLevel"></param>
|
|
protected virtual void LogMessage (
|
|
string message,
|
|
LogLevel logLevel = LogLevel.Information
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (message.IsNullOrEmpty ()) {
|
|
throw XException.InvalidArgs
|
|
.ToException ();
|
|
}
|
|
|
|
//
|
|
// Prepare Log Message ...
|
|
message = GetLogMessage (message);
|
|
|
|
//
|
|
// Logging Message ...
|
|
logger.Log (
|
|
message: message,
|
|
logLevel: logLevel
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logging specific Message to Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected virtual void ConsoleMessage (string message) {
|
|
//
|
|
// Validate Args ...
|
|
if (message.IsNullOrEmpty ()) {
|
|
throw XException.InvalidArgs
|
|
.ToException ();
|
|
}
|
|
|
|
//
|
|
// Prepare Log Message ...
|
|
message = GetLogMessage (message);
|
|
|
|
//
|
|
// Logging Message ...
|
|
Console.WriteLine (message);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseDescriptor.cs
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// Descriptors classes Map required data for creating Entities on Seeding time ...
|
|
/// this is a Base Descriptor class ...
|
|
/// </summary>
|
|
public abstract class XBaseDescriptor { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseDto.cs
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// DTO - Data Transfer Objects is a kind of classes which Represent Entities ...
|
|
/// this is base Dto class ...
|
|
/// </summary>
|
|
public abstract class XBaseDto { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseEntity.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// Base Entity Class
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public abstract class XBaseEntity<T> {
|
|
/// <summary>
|
|
/// Entity Id
|
|
/// </summary>
|
|
/// <value>entity unique id</value>
|
|
[Key]
|
|
[Required]
|
|
public T Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// Provided Soft Delete Behaviour ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool Deleted { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseEntityDto.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
/// <summary>
|
|
/// Base Entity Related Dto Class ...
|
|
/// </summary>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public abstract class XBaseEntityDto<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Entity Id
|
|
/// </summary>
|
|
/// <value>entity unique id</value>
|
|
public TKey Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// Provided Soft Delete Behaviour ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool Deleted { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseGuidIDEntity.cs
|
|
|
|
using System;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// a BaseEntity Class which has Id of Guid type
|
|
/// </summary>
|
|
public class XBaseGuidIDEntity : XBaseEntity<Guid> { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseGuidIDEntityDto.cs
|
|
|
|
using System;
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseGuidIDEntityDto : XBaseEntityDto<Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseIntIDEntity.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// a BaseEntity Class which has Id of int type
|
|
/// </summary>
|
|
public abstract class XBaseIntIDEntity : XBaseEntity<int> { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseIntIDEntityDto.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseIntIDEntityDto : XBaseEntityDto<int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseLongIDEntity.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseLongIDEntity : XBaseEntity<long>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseLongIDEntityDto.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseLongIDEntityDto : XBaseEntityDto<long>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseRangeRequest.cs
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// Range Request Classes Carry a List of Objects
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class XBaseRangeRequest<T> {
|
|
public IEnumerable<T> Items { get; set; } = new HashSet<T> ();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseStorableDto.cs
|
|
|
|
namespace xModels.Base {
|
|
public abstract class XBaseStorableDto<TKey> : XBaseDto {
|
|
public abstract TKey Id { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseStorableDtoEventModel.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseStorableDtoEventModel<T>
|
|
{
|
|
public T Model { get; set; }
|
|
|
|
public XBaseStorableDtoEventModel(T model)
|
|
{
|
|
Model = model;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseStoreEvent.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using xModels.Interfaces;
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public abstract class XBaseStoreEvent<T, TKey> : IXBaseStoreEvents<T, TKey>
|
|
where T : XBaseStorableDto<TKey>
|
|
{
|
|
//
|
|
private readonly ISubject<XBaseStorableDtoEventModel<T>> onAddSubject;
|
|
private readonly ISubject<XBaseStorableDtoEventModel<T>> onUpdateSubject;
|
|
private readonly ISubject<XBaseStorableDtoEventModel<T>> onRemoveSubject;
|
|
|
|
//
|
|
private readonly ISubject<XBaseStorableDtoEventModel<IEnumerable<T>>> onAddManySubject;
|
|
private readonly ISubject<XBaseStorableDtoEventModel<IEnumerable<T>>> onUpdateManySubject;
|
|
private readonly ISubject<XBaseStorableDtoEventModel<IEnumerable<T>>> onRemoveManySubject;
|
|
|
|
//
|
|
public IObservable<XBaseStorableDtoEventModel<T>> OnAddObservable => onAddSubject.AsObservable();
|
|
|
|
public IObservable<XBaseStorableDtoEventModel<T>> OnUpdateObservable => onUpdateSubject.AsObservable();
|
|
|
|
public IObservable<XBaseStorableDtoEventModel<T>> OnRemoveObservable => onRemoveSubject.AsObservable();
|
|
|
|
//
|
|
|
|
public IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnAddManyObservable => onAddManySubject.AsObservable();
|
|
|
|
public IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnUpdateManyObservable => onUpdateManySubject.AsObservable();
|
|
|
|
public IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnRemoveManyObservable => onRemoveManySubject.AsObservable();
|
|
|
|
//
|
|
protected XBaseStoreEvent()
|
|
{
|
|
//
|
|
onAddSubject = new ReplaySubject<XBaseStorableDtoEventModel<T>>(1);
|
|
onUpdateSubject = new ReplaySubject<XBaseStorableDtoEventModel<T>>(1);
|
|
onRemoveSubject = new ReplaySubject<XBaseStorableDtoEventModel<T>>(1);
|
|
|
|
//
|
|
onAddManySubject = new ReplaySubject<XBaseStorableDtoEventModel<IEnumerable<T>>>(1);
|
|
onUpdateManySubject = new ReplaySubject<XBaseStorableDtoEventModel<IEnumerable<T>>>(1);
|
|
onRemoveManySubject = new ReplaySubject<XBaseStorableDtoEventModel<IEnumerable<T>>>(1);
|
|
}
|
|
|
|
//
|
|
#region Base Actions ...
|
|
public void AddEvent(XBaseStorableDtoEventModel<T> model)
|
|
{
|
|
onAddSubject.OnNext(model);
|
|
}
|
|
|
|
public void AddManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model)
|
|
{
|
|
onAddManySubject.OnNext(model);
|
|
}
|
|
|
|
public void RemoveEvent(XBaseStorableDtoEventModel<T> model)
|
|
{
|
|
onRemoveSubject.OnNext(model);
|
|
}
|
|
|
|
public void RemoveManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model)
|
|
{
|
|
onRemoveManySubject.OnNext(model);
|
|
}
|
|
|
|
public void UpdateEvent(XBaseStorableDtoEventModel<T> model)
|
|
{
|
|
onUpdateSubject.OnNext(model);
|
|
}
|
|
|
|
public void UpdateManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model)
|
|
{
|
|
onUpdateManySubject.OnNext(model);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseStringIDEntity.cs
|
|
|
|
using System;
|
|
|
|
namespace xModels.Base {
|
|
/// <summary>
|
|
/// a BaseEntity Class which has Id of string type
|
|
/// </summary>
|
|
public class XBaseStringIDEntity : XBaseEntity<string> { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseStringIDEntityDto.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseStringIDEntityDto : XBaseEntityDto<string>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Base\XBaseValueContainer.cs
|
|
|
|
namespace xModels.Base
|
|
{
|
|
public class XBaseValueContainer<T>
|
|
{
|
|
public T Value { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XBaseIndexedDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos
|
|
{
|
|
public class XBaseIndexedDto<T, TKey, TIndex> : XBaseDto
|
|
{
|
|
public T Item { get; set; }
|
|
public TKey Key { get; set; }
|
|
public TIndex Index { get; set; }
|
|
}
|
|
|
|
public class XBaseIntIndexedDto<T> : XBaseIndexedDto<T, string, int> { }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XDeviceDto.cs
|
|
|
|
using xCommons.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos {
|
|
public class XDeviceDto : XBaseDto {
|
|
/// <summary>
|
|
/// Operating System
|
|
/// </summary>
|
|
/// <value>device operating system identifier</value>
|
|
public string Os { get; set; }
|
|
/// <summary>
|
|
/// Operating System Version
|
|
/// </summary>
|
|
/// <value>which version of operatin system is in use</value>
|
|
public string OsVersion { get; set; }
|
|
/// <summary>
|
|
/// Device Browser
|
|
/// </summary>
|
|
/// <value>the Browser identifier</value>
|
|
public string Browser { get; set; }
|
|
/// <summary>
|
|
/// Browser Engine Agent
|
|
/// </summary>
|
|
/// <value>browser engine Agent</value>
|
|
public string UserAgent { get; set; }
|
|
/// <summary>
|
|
/// Type of client Device
|
|
/// </summary>
|
|
/// <value>represent device type <see>XDeviceType</see></value>
|
|
public XDeviceType DeviceType { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XFileDto.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xCommons.Constants;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos {
|
|
public partial class XFileDto : XBaseDto {
|
|
[Required]
|
|
public string AuthorId { get; set; }
|
|
|
|
public XFileType Type { get; set; }
|
|
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string Name { get; set; }
|
|
|
|
[StringLength (255)]
|
|
public string Thumb { get; set; }
|
|
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string Path { get; set; }
|
|
|
|
[StringLength (255)]
|
|
public string ThumbPath { get; set; }
|
|
|
|
[Required]
|
|
public DateTime UploadedOn { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XObjectResponseResult.cs
|
|
|
|
namespace xModels.Dtos {
|
|
/// <summary>
|
|
/// Some Requests Get Object Response Result of Data ...
|
|
/// </summary>
|
|
public struct XObjectResponseResult<T> {
|
|
|
|
public XObjectResponseResult (T responseObject, string responseText) {
|
|
this.Object = responseObject;
|
|
this.Text = responseText;
|
|
}
|
|
|
|
public T Object { get; }
|
|
|
|
public string Text { get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XPersonDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos
|
|
{
|
|
/// <summary>
|
|
/// Since in Many Cases we have to Retrieve Specified User's Minimal
|
|
/// Infos for Handle Data Transfering, this Dto is Used ...
|
|
/// </summary>
|
|
public class XPersonDto : XBaseDto
|
|
{
|
|
public string Username { get; set; }
|
|
public string Firstname { get; set; }
|
|
public string Lastname { get; set; }
|
|
public string Avatar { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XQuery.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos {
|
|
/// <summary>
|
|
/// Request a Page of Data Based on Query ...
|
|
/// this can used in every Data Providers ...
|
|
/// </summary>
|
|
public class XQuery : XBaseDto {
|
|
/// <summary>
|
|
/// an string for filtering results
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Filter { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// determines fully load object with it's relational fields or not
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool ContainsDetail { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// specifiy sorting of items
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string SortBy { get; set; } = nameof (XBaseIntIDEntity.Id);
|
|
|
|
/// <summary>
|
|
/// specify sorting direction
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool IsAscending { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// specify page number
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int Page { get; set; } = 1;
|
|
|
|
/// <summary>
|
|
/// specify page size
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int PageSize { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XQueryResult.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos {
|
|
/// <summary>
|
|
/// Result of a Requested Page of Data Based on Query ...
|
|
/// this can used in every Data Providers ...
|
|
/// </summary>
|
|
public class XQueryResult<T> : XBaseDto {
|
|
/// <summary>
|
|
/// a collection of items for a page ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public IEnumerable<T> Items { get; set; }
|
|
|
|
/// <summary>
|
|
/// Current Page Number ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long Page { get; set; }
|
|
|
|
/// <summary>
|
|
/// Current Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long PageSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Total Pages ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long TotalPages { get; set; }
|
|
|
|
/// <summary>
|
|
/// Total Filtered Items Pages Count ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int TotalFilteredPages { get; set; }
|
|
|
|
/// <summary>
|
|
/// Total Filtered Items ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long TotalFilteredItems { get; set; }
|
|
|
|
/// <summary>
|
|
/// Total Exists Items ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long TotalItems { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XResourceDto.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Dtos
|
|
{
|
|
public class XLocaleResourceDto : XBaseDto
|
|
{
|
|
public string Language { get; set; }
|
|
public string Value { get; set; }
|
|
}
|
|
|
|
public class XResourceDto : XBaseDto
|
|
{
|
|
public string Resource { get; set; }
|
|
public IEnumerable<XLocaleResourceDto> Locales { get; set; } = new HashSet<XLocaleResourceDto>();
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Dtos\XValidateRevisionRequest.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace xModels.Dtos {
|
|
/// <summary>
|
|
/// in some cases we have to validate a revision of request, this is a model
|
|
/// which used to request a revision validator ...
|
|
/// </summary>
|
|
public class XValidateRevisionRequest {
|
|
[Required]
|
|
public string Revision { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Extensions\DIExtensions.cs
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
using xModels.Interfaces;
|
|
|
|
namespace xModels.Extensions {
|
|
public static class DIExtensions {
|
|
/// <summary>
|
|
/// Register an Specific Store in DI ...
|
|
/// </summary>
|
|
/// <param name="services">DI service collection ...</param>
|
|
/// <param name="store">an implementation of inetrface of store ...</param>
|
|
/// <param name="lifeTime">service lifetime</param>
|
|
/// <typeparam name="TImplementation">implementation of TType ...</typeparam>
|
|
/// <typeparam name="TType">an inetrface which implements IXBaseStore<TStoreItemDto, TKey></typeparam>
|
|
/// <typeparam name="TStoreItemDto">type of an instance of XBaseStorable<TKey></typeparam>
|
|
/// <typeparam name="TKey">type of key of StorableItem</typeparam>
|
|
/// <returns></returns>
|
|
public static void AddXStore<TImplementation, TType, TStoreItemDto, TKey> (
|
|
this IServiceCollection services,
|
|
TImplementation store,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Singleton
|
|
)
|
|
where TImplementation : TType
|
|
where TType : IXBaseStore<TStoreItemDto, TKey>
|
|
where TStoreItemDto : XBaseStorableDto<TKey> {
|
|
//
|
|
// Validate Args ...
|
|
if (store.IsNull ()) {
|
|
throw XException.InvalidArgs
|
|
.ToException ();
|
|
}
|
|
|
|
//
|
|
// Register Service in DI ...
|
|
services.Add (new ServiceDescriptor (typeof (TType), typeof (TImplementation), lifeTime));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Extensions\XModelExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xModels.Dtos;
|
|
|
|
namespace xModels.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Check to XDevice instance to be same or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dest"></param>
|
|
/// <returns></returns>
|
|
public static bool IsSameAs(this XDeviceDto source, XDeviceDto dest)
|
|
{
|
|
//
|
|
if (source.IsNull() ||
|
|
dest.IsNull())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var isSame = source.Os.ToNormalString() == dest.Os.ToNormalString() &&
|
|
source.OsVersion.ToNormalString() == dest.OsVersion.ToNormalString() &&
|
|
source.Browser.ToNormalString() == dest.Browser.ToNormalString() &&
|
|
source.UserAgent.ToNormalString() == dest.UserAgent.ToNormalString() &&
|
|
source.DeviceType == dest.DeviceType;
|
|
|
|
//
|
|
return isSame;
|
|
}
|
|
|
|
public static IEnumerable<T> AsEnumerable<T, TKey, TIndex>(
|
|
this IEnumerable<XBaseIndexedDto<T, TKey, TIndex>> source
|
|
)
|
|
{
|
|
return source.Select(i => i.Item);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Interfaces\IXAuditable.cs
|
|
|
|
using System;
|
|
|
|
namespace xModels.Interfaces {
|
|
/// <summary>
|
|
/// Some times we need to wrap Entities by some logs or audits ...
|
|
/// this class provide Audit fields for an Auditable Entity ...
|
|
/// </summary>
|
|
public interface IXAuditable {
|
|
string UserAgent { get; }
|
|
string UserIp { get; }
|
|
DateTime TransactionTime { get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Interfaces\IXBaseStore.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using System.Threading.Tasks;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Interfaces {
|
|
public interface IXBaseStore<T, TKey> where T : XBaseStorableDto<TKey> {
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<T>> GetAll ();
|
|
|
|
/// <summary>
|
|
/// Retrieve specific Item by key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Task<T> Get (TKey key);
|
|
|
|
/// <summary>
|
|
/// retrieve items based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<T>> FindMany (Expression<Func<T, bool>> condition);
|
|
|
|
/// <summary>
|
|
/// retrieve item based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
Task<T> FindOne (Expression<Func<T, bool>> condition);
|
|
#endregion
|
|
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add specific item to Store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
Task<bool> Add (T item);
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Items on Store ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddMany (XBaseRangeRequest<T> items);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// Remove an item from store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
Task<bool> Remove (T item);
|
|
|
|
/// <summary>
|
|
/// remove an item by it's Key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveByKey (TKey key);
|
|
|
|
/// <summary>
|
|
/// remove a collection of items at once ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveMany(XBaseRangeRequest<T> items);
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update Exists Item in store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="propertyValueProviders"></param>
|
|
/// <param name="updateWithNullOrEmptyValues"></param>
|
|
/// <returns></returns>
|
|
Task<T> Update (
|
|
T item,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<T, object>>> propertyValueProviders = null,
|
|
bool updateWithNullOrEmptyValues = false
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update a Collection of Exists Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="propertyValueProviders"></param>
|
|
/// <param name="updateWithNullOrEmptyValues"></param>
|
|
/// <returns></returns>
|
|
Task<bool> UpdateMany (
|
|
XBaseRangeRequest<T> items,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<T, object>>> propertyValueProviders = null,
|
|
bool updateWithNullOrEmptyValues = false
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// retrieve item(s) exists based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExists (Expression<Func<T, bool>> condition);
|
|
|
|
/// <summary>
|
|
/// is exists an item by providing it's key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsByKey (TKey key);
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// Count Exists items ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
Task<int> Count ();
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Interfaces\IXBaseStoreEvents.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xModels.Interfaces
|
|
{
|
|
public interface IXBaseStoreEvents<T, TKey> where T : XBaseStorableDto<TKey>
|
|
{
|
|
//
|
|
void AddEvent(XBaseStorableDtoEventModel<T> model);
|
|
void UpdateEvent(XBaseStorableDtoEventModel<T> model);
|
|
void RemoveEvent(XBaseStorableDtoEventModel<T> model);
|
|
|
|
//
|
|
void AddManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model);
|
|
void UpdateManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model);
|
|
void RemoveManyEvent(XBaseStorableDtoEventModel<IEnumerable<T>> model);
|
|
|
|
//
|
|
IObservable<XBaseStorableDtoEventModel<T>> OnAddObservable { get; }
|
|
IObservable<XBaseStorableDtoEventModel<T>> OnUpdateObservable { get; }
|
|
IObservable<XBaseStorableDtoEventModel<T>> OnRemoveObservable { get; }
|
|
|
|
//
|
|
IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnAddManyObservable { get; }
|
|
IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnUpdateManyObservable { get; }
|
|
IObservable<XBaseStorableDtoEventModel<IEnumerable<T>>> OnRemoveManyObservable { get; }
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xModels\Providers\XBaseInMemoryStore.cs
|
|
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xModels.Interfaces;
|
|
|
|
namespace xModels.Providers
|
|
{
|
|
public abstract class XBaseInMemoryStore<T, TKey> : IXBaseStore<T, TKey>
|
|
where T : XBaseStorableDto<TKey>
|
|
{
|
|
/// <summary>
|
|
/// this is main store of items ...
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
private static ConcurrentBag<T> STORE = new ConcurrentBag<T>();
|
|
|
|
//
|
|
private readonly IXBaseStoreEvents<T, TKey> events;
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseInMemoryStore(
|
|
IXBaseStoreEvents<T, TKey> events = null
|
|
)
|
|
{
|
|
this.events = events;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Task<IEnumerable<T>> GetAll()
|
|
{
|
|
//
|
|
var result = STORE.AsEnumerable();
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve specific Item by key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public Task<T> Get(TKey key)
|
|
{
|
|
//
|
|
return IsExistsByKey(key)
|
|
.ContinueWith(isExistsTask =>
|
|
{
|
|
//
|
|
var isExists = isExistsTask
|
|
.RunTask();
|
|
|
|
//
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
var result = STORE
|
|
.FirstOrDefault(i => GetKey(i).Equals(key));
|
|
return result;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve items based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
public Task<IEnumerable<T>> FindMany(Expression<Func<T, bool>> condition)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (condition.IsNull())
|
|
{
|
|
return Task.FromResult(new List<T>().AsEnumerable());
|
|
}
|
|
|
|
//
|
|
var whereFunc = condition.Compile();
|
|
var result = STORE.Where(whereFunc);
|
|
|
|
//
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve item based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
public Task<T> FindOne(Expression<Func<T, bool>> condition)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (condition.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var whereFunc = condition.Compile();
|
|
var result = STORE.FirstOrDefault(whereFunc);
|
|
|
|
//
|
|
return Task.FromResult(result);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Add ...
|
|
/// <summary>
|
|
/// add specific item to Store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> Add(T item)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (item.IsNull() || GetKey(item).IsNull())
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
// Try to add item ...
|
|
return IsExistsByKey(GetKey(item))
|
|
.ContinueWith(isExistsTask =>
|
|
{
|
|
//
|
|
// Check item exists in Store or not ...
|
|
var isExists = isExistsTask.RunTask();
|
|
if (isExists)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Add Item to Store ...
|
|
STORE.Add(item);
|
|
OnAdd(item);
|
|
|
|
//
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Items on Store ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> AddMany(XBaseRangeRequest<T> items)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
items.IsNull() ||
|
|
!items.Items.HasChild()
|
|
)
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
// Retrieve Must Add Items ...
|
|
var mustAddItems = items.Items
|
|
.Where(i => !GetKey(i)
|
|
.IsNull() && !STORE
|
|
.Any(si => GetKey(i).Equals(GetKey(si)))
|
|
);
|
|
if (!mustAddItems.HasChild())
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
// Add Items ...
|
|
try
|
|
{
|
|
//
|
|
mustAddItems
|
|
.ToList()
|
|
.ForEach(mi => STORE.Add(mi));
|
|
|
|
//
|
|
OnAddMany(mustAddItems);
|
|
|
|
//
|
|
return Task.FromResult(true);
|
|
}
|
|
catch
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove ...
|
|
/// <summary>
|
|
/// Remove an item from store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> Remove(T item)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
item.IsNull() ||
|
|
!STORE
|
|
.Any(i => GetKey(i)
|
|
.Equals(GetKey(item)))
|
|
)
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
RemoveItemFromStore(item);
|
|
return Task.FromResult(true);
|
|
}
|
|
catch
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an item by it's Key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> RemoveByKey(TKey key)
|
|
{
|
|
return Get(key)
|
|
.ContinueWith(getTask =>
|
|
{
|
|
//
|
|
// retrieve item by it's Key ...
|
|
var item = getTask
|
|
.RunTask();
|
|
|
|
//
|
|
// Check item exists ...
|
|
if (item.IsNull())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Try to remove item ...
|
|
var result = false;
|
|
try
|
|
{
|
|
//
|
|
result = Remove(item)
|
|
.RunTask();
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove a collection of items at once ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> RemoveMany(XBaseRangeRequest<T> items)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
items.IsNull() ||
|
|
!items.Items.HasChild()
|
|
)
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
var mustRemovedItems = items.Items
|
|
.Where(i => STORE
|
|
.Any(si => GetKey(si).Equals(GetKey(i)))
|
|
);
|
|
if (!mustRemovedItems.HasChild())
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
RemoveItemsFromStore(mustRemovedItems);
|
|
return Task.FromResult(true);
|
|
}
|
|
catch
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update ...
|
|
/// <summary>
|
|
/// Update Exists Item in store ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="propertyValueProviders"></param>
|
|
/// <param name="updateWithNullOrEmptyValues"></param>
|
|
/// <returns></returns>
|
|
public Task<T> Update(
|
|
T item,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<T, object>>> propertyValueProviders = null,
|
|
bool updateWithNullOrEmptyValues = false
|
|
)
|
|
{
|
|
return Get(GetKey(item))
|
|
.ContinueWith(getTask =>
|
|
{
|
|
//
|
|
var existsItem = getTask
|
|
.RunTask();
|
|
|
|
//
|
|
// Validate item Exists ...
|
|
if (existsItem.IsNull())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var updatedItem = existsItem;
|
|
updatedItem.UpdateData(
|
|
updateWith: item,
|
|
propertyWhiteList: propertyWhiteList,
|
|
propertyBlackList: propertyBlackList,
|
|
propertyValueProviders: propertyValueProviders,
|
|
updateWithNullOrEmptyValues: updateWithNullOrEmptyValues,
|
|
throwExceptionOnFails: true
|
|
);
|
|
|
|
//
|
|
RemoveItemFromStore(existsItem);
|
|
STORE.Add(updatedItem);
|
|
OnUpdate(item);
|
|
|
|
//
|
|
return updatedItem;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Collection of Exists Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="propertyWhiteList"></param>
|
|
/// <param name="propertyBlackList"></param>
|
|
/// <param name="propertyValueProviders"></param>
|
|
/// <param name="updateWithNullOrEmptyValues"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> UpdateMany(
|
|
XBaseRangeRequest<T> items,
|
|
ICollection<string> propertyWhiteList = null,
|
|
ICollection<string> propertyBlackList = null,
|
|
ICollection<KeyValuePair<string, Func<T, object>>> propertyValueProviders = null,
|
|
bool updateWithNullOrEmptyValues = false
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
items.IsNull() ||
|
|
!items.Items.HasChild()
|
|
)
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
// retrieve must updated items ...
|
|
var mustUpdateItems = items
|
|
.Items
|
|
.Where(i => STORE
|
|
.Any(
|
|
si => GetKey(i).Equals(GetKey(si)))
|
|
);
|
|
if (!mustUpdateItems.HasChild())
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
// Do Tasks ...
|
|
var mustUpdateTasks = mustUpdateItems.Select(i => Update(
|
|
i,
|
|
propertyWhiteList: propertyWhiteList,
|
|
propertyBlackList: propertyBlackList,
|
|
propertyValueProviders: propertyValueProviders,
|
|
updateWithNullOrEmptyValues: updateWithNullOrEmptyValues
|
|
));
|
|
return Task.WhenAll(mustUpdateTasks)
|
|
.ContinueWith(updateTasks =>
|
|
{
|
|
//
|
|
var updatedItems = updateTasks
|
|
.RunTask();
|
|
|
|
//
|
|
if (!updatedItems.HasChild())
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
OnUpdateMany(mustUpdateItems);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Exists ...
|
|
/// <summary>
|
|
/// retrieve item(s) exists based on specific condition ...
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> IsExists(Expression<Func<T, bool>> condition)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (condition.IsNull())
|
|
{
|
|
return Task.FromResult(false);
|
|
}
|
|
|
|
//
|
|
var whereFunc = condition.Compile();
|
|
var result = STORE.Any(whereFunc);
|
|
|
|
//
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// is exists an item by providing it's key ...
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public Task<bool> IsExistsByKey(TKey key)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
return STORE.Any(i => GetKey(i).Equals(key));
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Count ...
|
|
/// <summary>
|
|
/// Count Exists items ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Task<int> Count()
|
|
{
|
|
//
|
|
var result = STORE.Count();
|
|
return Task.FromResult(result);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Keys ...
|
|
/// <summary>
|
|
/// set Object Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="id"></param>
|
|
public void SetKey(
|
|
ref T item,
|
|
TKey id
|
|
)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
if (keyProp.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Type t = Nullable.GetUnderlyingType(keyProp.PropertyType) ?? keyProp.PropertyType;
|
|
object safeValue = (id == null) ? null : Convert.ChangeType(id, t);
|
|
keyProp.SetValue(item, safeValue, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Object Key ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public TKey GetKey(T item)
|
|
{
|
|
//
|
|
var props = item.GetType().GetProperties();
|
|
var keyProp = props.FirstOrDefault(p => p.Name == "Id");
|
|
|
|
//
|
|
var keyString = string.Empty;
|
|
if (keyProp.IsNull())
|
|
{
|
|
keyString = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
keyString = keyProp.GetValue(item).ToString();
|
|
}
|
|
|
|
//
|
|
if (keyString.IsNullOrEmpty())
|
|
{
|
|
return default(TKey);
|
|
}
|
|
|
|
//
|
|
// Prevent Deserializing issues throug JsonReader ...
|
|
if (keyString.IsGuid() && typeof(TKey) == typeof(Guid))
|
|
{
|
|
return item.Id;
|
|
}
|
|
|
|
//
|
|
TKey result;
|
|
try
|
|
{
|
|
result = keyString.FromJSON<TKey>();
|
|
}
|
|
catch
|
|
{
|
|
result = keyString.ConvertTo<TKey>();
|
|
}
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private void RemoveItemFromStore(T item)
|
|
{
|
|
//
|
|
STORE = new ConcurrentBag<T>(
|
|
STORE.Except(new[] { item })
|
|
);
|
|
|
|
//
|
|
OnRemove(item);
|
|
}
|
|
|
|
private void RemoveItemsFromStore(IEnumerable<T> items)
|
|
{
|
|
//
|
|
STORE = new ConcurrentBag<T>(
|
|
STORE.Except(items)
|
|
);
|
|
|
|
//
|
|
OnRemoveMany(items);
|
|
}
|
|
|
|
//
|
|
#region Event Notifiers ...
|
|
private void OnAdd(T item)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.AddEvent(new XBaseStorableDtoEventModel<T>(item));
|
|
}
|
|
}
|
|
private void OnUpdate(T item)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.UpdateEvent(new XBaseStorableDtoEventModel<T>(item));
|
|
}
|
|
}
|
|
|
|
private void OnRemove(T item)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.RemoveEvent(new XBaseStorableDtoEventModel<T>(item));
|
|
}
|
|
}
|
|
|
|
private void OnAddMany(IEnumerable<T> items)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.AddManyEvent(new XBaseStorableDtoEventModel<IEnumerable<T>>(items));
|
|
}
|
|
}
|
|
|
|
private void OnUpdateMany(IEnumerable<T> items)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.UpdateManyEvent(new XBaseStorableDtoEventModel<IEnumerable<T>>(items));
|
|
}
|
|
}
|
|
|
|
private void OnRemoveMany(IEnumerable<T> items)
|
|
{
|
|
//
|
|
if (!events.IsNull())
|
|
{
|
|
events.RemoveManyEvent(new XBaseStorableDtoEventModel<IEnumerable<T>>(items));
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseDtoHub.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseDtoHub<TEntity, TDto, TKey> : XBaseHub, IXBaseDtoHub<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseDtoHub(ILogger<XBaseHub> logger) : base(logger)
|
|
{ }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Notify a New Item added ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Add(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
item.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify a New Item added ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddOrUpdate(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
item.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Add Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
items.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify an Item Deleted ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Delete(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
item.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Delete Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task DeleteMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
items.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify an Item Updated ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Update(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
item.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Update Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task UpdateMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
items.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseDtoProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseDtoProvider<TEntity, TDto, TKey, THub> : IXBaseDtoProvider<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IHubContext<THub> Hub { get; }
|
|
public IXIdentityProvider IdentityProvider { get; }
|
|
public XDataServiceConfiguration DataConfiguration { get; }
|
|
public IXBaseRepositoryService<TEntity, TDto, TKey> Service { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseDtoProvider(
|
|
IHubContext<THub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXBaseRepositoryService<TEntity, TDto, TKey> service,
|
|
IXIdentityProvider identityProvider = null
|
|
)
|
|
{
|
|
//
|
|
Hub = hub;
|
|
Service = service;
|
|
IdentityProvider = identityProvider;
|
|
DataConfiguration = dataConfiguration;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Update.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Delete.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.GetAsync(
|
|
id: id,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.GetAllAsync(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var enumerable = Service.GetAllAsAsyncEnumerable(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
await foreach (var dto in enumerable)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
//
|
|
yield return dto;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var actions = new List<string>
|
|
{
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
XBaseEntityHubAction.AddMany.GetStringValue(),
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
};
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!Hub.IsNull() &&
|
|
!action.IsNullOrEmpty() &&
|
|
!payLoad.IsNullOrEmpty() &&
|
|
actions.Contains(action);
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Retrieve Connection Id ...
|
|
var clients = Hub.Clients.All;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
clients = Hub.Clients.AllExcept(connectionId);
|
|
}
|
|
|
|
//
|
|
await clients.SendAsync(
|
|
action,
|
|
payLoad,
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseEntityHub.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xModels.Base;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseEntityHub<TEntity, TKey> : XBaseHub, IXBaseEntityHub<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseEntityHub(ILogger<XBaseHub> logger) : base(logger)
|
|
{ }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Notify a New Entity added ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Add(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify a New Entity added ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddOrUpdate(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Add Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task AddMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
entities.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify an Entity Deleted ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Delete(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Delete Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task DeleteMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
entities.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify an Entity Updated ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Update(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify Update Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task UpdateMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
entities.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseEntityProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseEntityProvider<TEntity, TKey, THub> : IXBaseEntityProvider<TEntity, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where THub : XBaseEntityHub<TEntity, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IHubContext<THub> Hub { get; }
|
|
public IXIdentityProvider IdentityProvider { get; }
|
|
public IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
public XDataServiceConfiguration DataConfiguration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseEntityProvider(
|
|
IHubContext<THub> hub,
|
|
IXBaseRepository<TEntity, TKey> repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
)
|
|
{
|
|
//
|
|
Hub = hub;
|
|
Repository = repository;
|
|
IdentityProvider = identityProvider;
|
|
DataConfiguration = dataConfiguration;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TEntity> AddAsync(
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Add.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TEntity> UpdateAsync(
|
|
TKey id,
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Update.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TEntity> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var isValid = !result.IsNullOrDefault();
|
|
if (isValid)
|
|
{
|
|
//
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
action: XBaseEntityHubAction.Delete.GetStringValue()
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TEntity> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.GetAsync(
|
|
id: id,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TEntity>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.GetAllAsync(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TEntity> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TEntity>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TEntity>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Repository.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var actions = new List<string>
|
|
{
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
XBaseEntityHubAction.AddMany.GetStringValue(),
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
};
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!Hub.IsNull() &&
|
|
!action.IsNullOrEmpty() &&
|
|
!payLoad.IsNullOrEmpty() &&
|
|
actions.Contains(action);
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Retrieve Connection Id ...
|
|
var clients = Hub.Clients.All;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
clients = Hub.Clients.AllExcept(connectionId);
|
|
}
|
|
|
|
//
|
|
await clients.SendAsync(
|
|
action,
|
|
payLoad,
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseHub.cs
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseHub : Hub, IXBaseHub
|
|
{
|
|
//
|
|
#region Props ...
|
|
protected readonly ILogger<XBaseHub> logger;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseHub(
|
|
ILogger<XBaseHub> logger
|
|
)
|
|
{
|
|
this.logger = logger;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Overrides ...
|
|
public override async Task OnConnectedAsync()
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Notify Other Clients Which a new Connection Joins ...
|
|
await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.NewConnection.GetStringValue(), connectionId);
|
|
}
|
|
|
|
//
|
|
await base.OnConnectedAsync();
|
|
}
|
|
|
|
public override async Task OnDisconnectedAsync(Exception exception)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Notify Other Clients Which a Connection Closed ...
|
|
await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.ConnectionClosed.GetStringValue(), connectionId);
|
|
}
|
|
await base.OnDisconnectedAsync(exception);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
public async Task SendCustomAction(
|
|
string actionName,
|
|
string payLoad,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
await Clients.AllExcept(connectionId).SendAsync(
|
|
actionName,
|
|
payLoad,
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Constants;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseProvider<TEntity, TDto, TKey> : IXBaseProvider<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
public IXIdentityProvider IdentityProvider { get; }
|
|
public XDataServiceConfiguration DataConfiguration { get; }
|
|
public IHubContext<XBaseEntityHub<TEntity, TKey>> Hub { get; }
|
|
public IXBaseRepositoryService<TEntity, TDto, TKey> RepositoryService { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
if (!result.IsNullOrDefault())
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Add.GetStringValue(),
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Dto values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
if (!result.IsNullOrDefault())
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Update.GetStringValue(),
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
if (!result.IsNullOrDefault())
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Update.GetStringValue(),
|
|
payLoad: result.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Dto exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.GetAsync(
|
|
id: id,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.GetAllAsync(
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Dto by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Dtos by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Dtos based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await RepositoryService.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var actions = new List<string>
|
|
{
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
XBaseEntityHubAction.AddMany.GetStringValue(),
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
};
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!Hub.IsNull() &&
|
|
!action.IsNullOrEmpty() &&
|
|
actions.Contains(action);
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var clients = Hub.Clients.All;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
clients = Hub.Clients.AllExcept(connectionId);
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await clients.SendAsync(
|
|
action,
|
|
payLoad,
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseWebRTCHub.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Interfaces;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xPushService.Constants;
|
|
using xCommons.Extensions;
|
|
using System.Threading;
|
|
|
|
namespace xPushService.Base
|
|
{
|
|
public abstract class XBaseWebRTCHub : XBaseHub, IXBaseWebRTCHub
|
|
{
|
|
//
|
|
#region Props ...
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseWebRTCHub(
|
|
ILogger<XBaseHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
#endregion
|
|
|
|
//
|
|
#region WebRTCActions ...
|
|
/// <summary>
|
|
/// Sending WebRTC Offer To Specified Connection ...
|
|
/// </summary>
|
|
/// <param name="offer"></param>
|
|
/// <param name="to"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Offer(
|
|
string offer,
|
|
string to,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await Clients.Client(to).SendAsync(
|
|
XWebRTCAction.Offer.GetStringValue(),
|
|
offer,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sending WebRTC Answer to Specified Connection ...
|
|
/// </summary>
|
|
/// <param name="answer"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Answer(
|
|
string answer,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await Clients.All.SendAsync(
|
|
XWebRTCAction.Answer.GetStringValue(),
|
|
answer,
|
|
Context.ConnectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sending WebRTC Candidate to Specified Connecton ...
|
|
/// </summary>
|
|
/// <param name="candidate"></param>
|
|
/// <param name="to"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Candidate(
|
|
string candidate,
|
|
string to,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
string actionName = XWebRTCAction.Candidate.GetStringValue();
|
|
if (!string.IsNullOrEmpty(to))
|
|
{
|
|
//
|
|
await Clients.Client(to).SendAsync(
|
|
actionName,
|
|
candidate,
|
|
Context.ConnectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
await Clients.All.SendAsync(
|
|
actionName,
|
|
candidate,
|
|
Context.ConnectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Configurations\XPushServiceConfiguration.cs
|
|
|
|
namespace xPushService.Configurations {
|
|
public partial class XPushServiceConfiguration {
|
|
/// <summary>
|
|
/// Base route of WebSocket Server ...
|
|
/// </summary>
|
|
/// <value>string</value>
|
|
public string BaseRoute { get; set; }
|
|
|
|
/// <summary>
|
|
/// determines log level of signalR ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public object ConnectionLogLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// when client disconnected it's automatically try to reconnect, this
|
|
/// determines max number of try to connect ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int PushConnectionMaxRetry { get; set; }
|
|
|
|
/// <summary>
|
|
/// add support for message protocol ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool AddSupportMessageProtocol { get; set; }
|
|
|
|
/// <summary>
|
|
/// the delay between two connection try ..
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int PushConnectionReconnectDelay { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Constants\XPushAction.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xPushService.Constants
|
|
{
|
|
public enum XBaseHubAction
|
|
{
|
|
/// <summary>
|
|
/// new Connection Join ...
|
|
/// </summary>
|
|
[StringValue("NewConnection")]
|
|
NewConnection,
|
|
/// <summary>
|
|
/// an Exists Connection Closed ...
|
|
/// </summary>
|
|
[StringValue("ConnectionClosed")]
|
|
ConnectionClosed,
|
|
}
|
|
|
|
/// <summary>
|
|
/// All Actions in WebRTC Hubs ...
|
|
/// </summary>
|
|
public enum XWebRTCAction
|
|
{
|
|
//
|
|
[StringValue("Offer")]
|
|
Offer,
|
|
|
|
[StringValue("Answer")]
|
|
Answer,
|
|
|
|
[StringValue("Candidate")]
|
|
Candidate,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provides All Actions Based on Entities ...
|
|
/// </summary>
|
|
public enum XBaseEntityHubAction
|
|
{
|
|
[StringValue("Add")]
|
|
Add,
|
|
[StringValue("AddOrUpdate")]
|
|
AddOrUpdate,
|
|
[StringValue("AddMany")]
|
|
AddMany,
|
|
[StringValue("Update")]
|
|
Update,
|
|
[StringValue("UpdateMany")]
|
|
UpdateMany,
|
|
[StringValue("Delete")]
|
|
Delete,
|
|
[StringValue("DeleteMany")]
|
|
DeleteMany,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Constants\XPushServiceConstants.cs
|
|
|
|
namespace xPushService.Constants {
|
|
public partial class XPushServiceConstants {
|
|
public partial struct XConfigurationNodes {
|
|
public const string XPushServiceConfiguration = "PushServiceConfiguration";
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseProvidedController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Controllers
|
|
{
|
|
[AllowAnonymous]
|
|
public abstract class XBaseProvidedController<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseProvidedController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
private readonly IXBaseProvided<TEntity, TDto, TKey, THub> provider;
|
|
private readonly Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder;
|
|
private readonly Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder;
|
|
|
|
protected XBaseProvidedController(
|
|
ILogger<XBaseProvidedController<TEntity, TDto, TKey, THub>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXBaseProvided<TEntity, TDto, TKey, THub> provider,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.defaultOrderBuilder = defaultOrderBuilder;
|
|
this.defaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
var result = await provider.Get(
|
|
id: id,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetAll(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/One")]
|
|
public virtual async Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindOne(
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find a collection of Items by proving a Query Search ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/Many")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindMany(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.Query(
|
|
query: query,
|
|
predicate: null,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query/Owned")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> QueryOwned(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
|
|
//
|
|
var result = await provider.QueryOwned(
|
|
query: query,
|
|
predicate: null,
|
|
userInfo: userInfo,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Add/Update/Remove ...
|
|
/// <summary>
|
|
/// Add an item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("")]
|
|
public virtual async Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Update(
|
|
id: id,
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Remove(
|
|
id: id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseRepositoryProviderController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xDataService.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Controllers
|
|
{
|
|
[AllowAnonymous]
|
|
public abstract class XBaseRepositoryProviderController<TEntity, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseRepositoryProviderController<TEntity, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where THub : XBaseEntityHub<TEntity, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IXBaseEntityProvider<TEntity, TKey, THub> Provider { get; }
|
|
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
protected XBaseRepositoryProviderController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXBaseEntityProvider<TEntity, TKey, THub> provider,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger: logger,
|
|
appConfiguration: appConfiguration,
|
|
identityProvider: identityProvider,
|
|
validationProvider: validationProvider
|
|
)
|
|
{
|
|
//
|
|
Provider = provider;
|
|
DefaultOrderBuilder = defaultOrderBuilder;
|
|
DefaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public virtual async Task<ActionResult<TEntity>> Add(
|
|
[FromBody] TEntity item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TEntity item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/[action]")]
|
|
public virtual async Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Count")]
|
|
public virtual async Task<ActionResult<long>> Count(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TEntity>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
public virtual async Task<ActionResult<IEnumerable<TEntity>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.GetAllAsync(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne")]
|
|
public virtual async Task<ActionResult<TEntity>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
Expression<Func<TEntity, bool>> predicate = x => x.PropValuesContains(query);
|
|
var result = await Provider.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Query Search ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany")]
|
|
public virtual async Task<ActionResult<IEnumerable<TEntity>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
Expression<Func<TEntity, bool>> predicate = x => x.PropValuesContains(query);
|
|
var result = await Provider.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TEntity>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (query.IsNullOrDefault())
|
|
{
|
|
query = query.NormalizeQuery(Provider.DataConfiguration);
|
|
}
|
|
|
|
//
|
|
var result = await Provider.QueryAsync(
|
|
query: query,
|
|
predicate: null,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region NonActions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public virtual async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await Provider.SendPush(
|
|
action: action,
|
|
payLoad: payLoad,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseServiceProviderController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xDataService.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Controllers
|
|
{
|
|
[AllowAnonymous]
|
|
public abstract class XBaseServiceProviderController<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseServiceProviderController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public IXBaseDtoProvider<TEntity, TDto, TKey, THub> Provider { get; }
|
|
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseServiceProviderController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
//
|
|
Provider = provider;
|
|
DefaultOrderBuilder = defaultOrderBuilder;
|
|
DefaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public virtual async Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.AddAsync(
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(item);
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await Provider.RemoveAsync(
|
|
id: id,
|
|
softDelete: softDelete,
|
|
saveChanges: saveChanges,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/[action]")]
|
|
public virtual async Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Count")]
|
|
public virtual async Task<ActionResult<long>> Count(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.CountAsync(
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Provider.GetAllAsync(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne")]
|
|
public virtual async Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
Expression<Func<TEntity, bool>> predicate = x => x.PropValuesContains(query);
|
|
var result = await Provider.FindOneAsync(
|
|
predicate: predicate,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotEmpty(query);
|
|
|
|
//
|
|
Expression<Func<TEntity, bool>> predicate = x => x.PropValuesContains(query);
|
|
var result = await Provider.FindManyAsync(
|
|
predicate: predicate,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (query.IsNullOrDefault())
|
|
{
|
|
query = query.NormalizeQuery(Provider.DataConfiguration);
|
|
}
|
|
|
|
//
|
|
var result = await Provider.QueryAsync(
|
|
query: query,
|
|
predicate: null,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: DefaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: DefaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
ignoreSoftDeleteds: ignoreSoftDeleteds
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region NonActions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public virtual async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await Provider.SendPush(
|
|
action: action,
|
|
payLoad: payLoad,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Serialization;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xPushService.Configurations;
|
|
using xPushService.Constants;
|
|
using xPushService.Helpers;
|
|
using xPushService.Providers;
|
|
|
|
namespace xPushService.DI
|
|
{
|
|
public static partial class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Extract Module Configuration from provided IConfiguration
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <returns>an instance of XPushServiceConfiguration</returns>
|
|
public static XPushServiceConfiguration GetXPushServiceConfiguration(this IConfiguration config)
|
|
{
|
|
//
|
|
var xPushConfigSection = config.GetSection(XPushServiceConstants.XConfigurationNodes.XPushServiceConfiguration);
|
|
return xPushConfigSection.Get<XPushServiceConfiguration>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XPushServiceHelper ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="helper"></param>
|
|
public static void AddXPushServiceHelper(
|
|
this IServiceCollection services,
|
|
XPushServiceHelper helper
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (helper.IsNull())
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, helper not provided ...");
|
|
throw XException.InvalidArgs.ToException();
|
|
}
|
|
|
|
//
|
|
// Register Helper ...
|
|
services.AddSingleton(helper);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Module Provided Service on DI
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXPushService(
|
|
this IServiceCollection services,
|
|
IConfiguration config,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
AddPushService(
|
|
services,
|
|
config.GetXPushServiceConfiguration(),
|
|
lifeTime
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Module Provided Service on DI
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXPushService(
|
|
this IServiceCollection services,
|
|
XPushServiceConfiguration config,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
AddPushService(
|
|
services,
|
|
config,
|
|
lifeTime
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Module Middlewares on Application Builder
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="helper"></param>
|
|
public static void UseXPushService(
|
|
this IApplicationBuilder app,
|
|
XPushServiceHelper helper
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var isHelperExists = !helper.IsNull();
|
|
if (!isHelperExists)
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, helper not provided ...");
|
|
throw XException.InvalidArgs.ToException();
|
|
}
|
|
|
|
//
|
|
// Create an Scope for Accessing Registered Services ...
|
|
using (var scope = app.ApplicationServices.CreateScope())
|
|
{
|
|
//
|
|
// try to Retrieve Configuration ....
|
|
var config = scope.ServiceProvider.GetService<XPushServiceConfiguration>();
|
|
if (
|
|
config.IsNull() ||
|
|
config.BaseRoute.IsNullOrEmpty() ||
|
|
config.BaseRoute.Trim().IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, Configuration not provided ...");
|
|
throw XException.InvalidConfiguration.ToException();
|
|
}
|
|
|
|
//
|
|
#region Normalize Routes ...
|
|
//
|
|
// Base Reoute ...
|
|
config.BaseRoute = config.BaseRoute.ToNormalString();
|
|
if (!config.BaseRoute.StartsWith("/"))
|
|
{
|
|
config.BaseRoute = "/" + config.BaseRoute;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// add XPushService Hub to Helper ...
|
|
//
|
|
var hubRoutes = new List<string>();
|
|
|
|
//
|
|
// Try to Register Hubs ...
|
|
//
|
|
// Use SignalR in App ...
|
|
app.UseSignalR(routes =>
|
|
{
|
|
//
|
|
helper.GetHubs().ForEach(hubDescriptor =>
|
|
{
|
|
//
|
|
var hubRoute = config.BaseRoute + "/" + hubDescriptor.Route;
|
|
hubRoutes.Add(hubRoute);
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
Type routesType = routes.GetType();
|
|
MethodInfo mapHubMethod = routesType
|
|
.GetMethods()
|
|
.SingleOrDefault(m =>
|
|
m.Name == "MapHub" &&
|
|
m.GetParameters().Length == 1
|
|
);
|
|
if (mapHubMethod.IsNull())
|
|
{
|
|
throw XException.ActionFailed.ToException();
|
|
}
|
|
|
|
//
|
|
object[] genericMapHubMethodArgs = { new PathString(hubRoute) };
|
|
MethodInfo genericMapHubMethod = mapHubMethod.MakeGenericMethod(hubDescriptor.Hub);
|
|
genericMapHubMethod.Invoke(routes, genericMapHubMethodArgs);
|
|
|
|
//
|
|
Log($"Register {hubDescriptor.Hub} Hub: {hubRoute}");
|
|
}
|
|
catch
|
|
{
|
|
throw;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// a LogTag for XPushService ...
|
|
/// </summary>
|
|
private static string XLogTag = "XPushService";
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Push Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddPushService(
|
|
IServiceCollection services,
|
|
XPushServiceConfiguration config,
|
|
ServiceLifetime lifeTime
|
|
)
|
|
{
|
|
//
|
|
#region Validate Args ...
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Config ...
|
|
var isConfigExists = !config.IsNull();
|
|
if (!isConfigExists)
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, configuration not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("AddXPushServiceHelper failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Register XPushService Configuration ...
|
|
services.AddSingleton(config);
|
|
|
|
//
|
|
// Register SignalR ...
|
|
var builder = services.AddSignalR(options =>
|
|
{
|
|
options.KeepAliveInterval = TimeSpan.FromSeconds(10);
|
|
options.ClientTimeoutInterval = TimeSpan.FromSeconds(10);
|
|
});
|
|
|
|
//
|
|
// Add NewtonSoftJson Protocol ...
|
|
builder.AddNewtonsoftJsonProtocol(x =>
|
|
{
|
|
x.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
|
x.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
|
});
|
|
|
|
//
|
|
// Register XPushServiceUserNameProvider ...
|
|
services.AddSingleton<IUserIdProvider, XPushServiceUserNameProvider>();
|
|
|
|
//
|
|
// add Message Protocol Support ...
|
|
if (config.AddSupportMessageProtocol)
|
|
{
|
|
builder.AddMessagePackProtocol();
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Extensions\ClaimsPrincipalExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xIdentityModels.Constants;
|
|
using xPushService.Models;
|
|
|
|
namespace xPushService.Extensions
|
|
{
|
|
public static class ClaimsPrincipalExtensions
|
|
{
|
|
/// <summary>
|
|
/// Generate User Info based on HubCallerContext ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XHubUserInfo GetUserInfo(this HubCallerContext source)
|
|
{
|
|
//
|
|
XHubUserInfo result = null;
|
|
|
|
//
|
|
if (source.IsNull() || source.User.IsNull() || !source.User.Claims.HasChild())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = new XHubUserInfo
|
|
{
|
|
UserId = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "",
|
|
UserName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "",
|
|
FirstName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "",
|
|
LastName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.LastName)?.Value ?? "",
|
|
Picture = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Picture)?.Value ?? "",
|
|
Email = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null,
|
|
PhoneNumber = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null,
|
|
};
|
|
|
|
//
|
|
#region Handle Gender ...
|
|
var genders = ObjectHelper.ToEnumerableKeys<XGender>();
|
|
var genderStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null;
|
|
if (genderStr.IsNullOrEmpty())
|
|
{
|
|
result.Gender = XGender.Male;
|
|
}
|
|
else
|
|
{
|
|
result.Gender = genderStr.GetValue<XGender>();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle IsBanned ...
|
|
var isBannedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null;
|
|
if (isBannedStr.IsNullOrEmpty())
|
|
{
|
|
result.IsBanned = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var isBanned = false;
|
|
Boolean.TryParse(isBannedStr, out isBanned);
|
|
|
|
//
|
|
result.IsBanned = isBanned;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle IsEnabled ...
|
|
var isEnabledStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null;
|
|
if (isEnabledStr.IsNullOrEmpty())
|
|
{
|
|
result.IsEnabled = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var isEnabled = false;
|
|
Boolean.TryParse(isEnabledStr, out isEnabled);
|
|
|
|
//
|
|
result.IsEnabled = isEnabled;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle Email Confirmed ...
|
|
var emailConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null;
|
|
if (emailConfirmedStr.IsNullOrEmpty())
|
|
{
|
|
result.EmailConfirmed = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var emailConfirmed = false;
|
|
Boolean.TryParse(emailConfirmedStr, out emailConfirmed);
|
|
|
|
//
|
|
result.EmailConfirmed = emailConfirmed;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle PhoneNumber Confirmed ...
|
|
var phoneNumberConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null;
|
|
if (phoneNumberConfirmedStr.IsNullOrEmpty())
|
|
{
|
|
result.PhoneNumberConfirmed = false;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var phoneNumberConfirmed = false;
|
|
Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed);
|
|
|
|
//
|
|
result.PhoneNumberConfirmed = phoneNumberConfirmed;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle ExpiredOn ...
|
|
var expiredOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null;
|
|
if (expiredOnStr.IsNullOrEmpty())
|
|
{
|
|
result.ExpiredOn = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
long expiredOn = 0;
|
|
long.TryParse(expiredOnStr, out expiredOn);
|
|
|
|
//
|
|
result.ExpiredOn = expiredOn;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle AuthenticatedOn ...
|
|
var authenticatedOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null;
|
|
if (authenticatedOnStr.IsNullOrEmpty())
|
|
{
|
|
result.AuthenticatedOn = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
long authenticatedOn = 0;
|
|
long.TryParse(authenticatedOnStr, out authenticatedOn);
|
|
|
|
//
|
|
result.AuthenticatedOn = authenticatedOn;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle BrithDate ...
|
|
var brithDateStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? "";
|
|
if (brithDateStr.IsNullOrEmpty())
|
|
{
|
|
// BrithDate = null;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
DateTime bDate;
|
|
DateTime.TryParse(brithDateStr, out bDate);
|
|
|
|
//
|
|
result.BrithDate = bDate;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
result.Issuers = source.User.Claims.Where(c => c.Type == XCustomClaims.Issuer)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
result.Audiences = source.User.Claims.Where(c => c.Type == XCustomClaims.Audience)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
result.ClientIds = source.User.Claims.Where(c => c.Type == XCustomClaims.ClientId)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
result.Scopes = source.User.Claims.Where(c => c.Type == XCustomClaims.Scope)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
result.Roles = source.User.Claims.Where(c => c.Type == XCustomClaims.Role)?
|
|
.Select(c => c.Value) ?? new HashSet<string>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Helpers\XPushServiceHelper.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xPushService.Base;
|
|
using xPushService.Models;
|
|
|
|
namespace xPushService.Helpers {
|
|
public class XPushServiceHelper {
|
|
/// <summary>
|
|
/// a collection of Hubs for Registring ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private List<XHubDescriptor> hubs = new List<XHubDescriptor> ();
|
|
|
|
/// <summary>
|
|
/// add specified hub to provided hubs for registration ...
|
|
/// </summary>
|
|
/// <param name="route"></param>
|
|
/// <typeparam name="TXHub"></typeparam>
|
|
public void AddHub<TXHub> (string route) where TXHub : XBaseHub {
|
|
//
|
|
#region Validate Args ...
|
|
//
|
|
// check route not null ...
|
|
if (
|
|
route.IsNullOrEmpty () ||
|
|
route.Trim ().IsNullOrEmpty ()
|
|
) {
|
|
throw XException.InvalidArgs.ToException ();
|
|
}
|
|
|
|
//
|
|
// Normalize Route ...
|
|
route = route.ToNormalString ();
|
|
|
|
//
|
|
// check route and hub must be unique ...
|
|
var isRouteExists = hubs.Any (hd => hd.Route == route);
|
|
var isHubExists = hubs.Any (hd => hd.Hub == typeof (TXHub));
|
|
if (
|
|
isHubExists ||
|
|
isRouteExists
|
|
) {
|
|
throw XException.Duplicate.ToException ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Add Provided Hub to List ...
|
|
hubs.Add (new XHubDescriptor {
|
|
Route = route,
|
|
Hub = typeof (TXHub)
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an specific hub from provided list ...
|
|
/// </summary>
|
|
/// <typeparam name="TXHub"></typeparam>
|
|
public void RemoveHub<TXHub> () where TXHub : XBaseHub {
|
|
//
|
|
var existsHubDescriptor = hubs.SingleOrDefault (hd => hd.Hub == typeof (TXHub));
|
|
if (!existsHubDescriptor.IsNull ()) {
|
|
hubs.Remove (existsHubDescriptor);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve provided hubs count ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int Count () {
|
|
return hubs.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve all provided hubs for registration ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<XHubDescriptor> GetHubs () {
|
|
return hubs;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseDtoHub.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xModels.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseDtoHub<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Notify a New Item added ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Add(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify a New Item added ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddOrUpdate(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Add Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify an Item Deleted ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Delete(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Delete Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task DeleteMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify an Item Updated ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Update(
|
|
TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Update Many Items ...
|
|
/// </summary>
|
|
/// <param name="items"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task UpdateMany(
|
|
IEnumerable<TDto> items,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseDtoProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseDtoProvider<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
IHubContext<THub> Hub { get; }
|
|
IXIdentityProvider IdentityProvider { get; }
|
|
XDataServiceConfiguration DataConfiguration { get; }
|
|
IXBaseRepositoryService<TEntity, TDto, TKey> Service { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos
|
|
/// as Async Enumerable ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseEntityHub.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xModels.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseEntityHub<TEntity, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
{
|
|
/// <summary>
|
|
/// Notify a New Entity added ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Add(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify a New Entity added ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddOrUpdate(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Add Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AddMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify an Entity Deleted ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Delete(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Delete Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task DeleteMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify an Entity Updated ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Update(
|
|
TEntity entity,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Notify Update Many Entities ...
|
|
/// </summary>
|
|
/// <param name="entities"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task UpdateMany(
|
|
IEnumerable<TEntity> entities,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseEntityProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Provider is a way to Manipulate Data using Repository or Services and Contains Push
|
|
/// notifications ability ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseEntityProvider<TEntity, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where THub : XBaseEntityHub<TEntity, TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
IHubContext<THub> Hub { get; }
|
|
IXIdentityProvider IdentityProvider { get; }
|
|
IXBaseRepository<TEntity, TKey> Repository { get; }
|
|
XDataServiceConfiguration DataConfiguration { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TEntity> AddAsync(
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TEntity> UpdateAsync(
|
|
TKey id,
|
|
TEntity item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TEntity> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TEntity> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TEntity>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TEntity> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TEntity>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TEntity>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseHub.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseHub
|
|
{
|
|
Task SendCustomAction(
|
|
string actionName,
|
|
string payLoad,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvided.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Provided Service Used for Providing Data Based on Validations of Users ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="THub"></typeparam>
|
|
public interface IXBaseProvided<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> Get(
|
|
TKey id,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> GetAll(
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> FindOne(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> FindMany(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TDto>> Query(
|
|
XQuery query,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// if supported ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TDto>> QueryOwned(
|
|
XQuery query,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add an item values ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> Add(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> Update(
|
|
TKey id,
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> Remove(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> Count(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExists(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvidedController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Provided Controller Used for Providing a Provided Service Actions ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="THub"></typeparam>
|
|
public interface IXBaseProvidedController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("")]
|
|
Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/One")]
|
|
Task<ActionResult<TDto>> FindOne(
|
|
[FromQuery] string query,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Find a collection of Items by proving a Query Search ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/Many")]
|
|
Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromQuery] string query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query/Owned")]
|
|
Task<ActionResult<XQueryResult<TDto>>> QueryOwned(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Add/Update/Remove ...
|
|
/// <summary>
|
|
/// Add an item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("")]
|
|
Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xDataService.Configuration;
|
|
using xDataService.Interfaces;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Provider is a way to Manipulate Data using Repository or Services and Contains Push
|
|
/// notifications ability ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
public interface IXBaseProvider<TEntity, TDto, TKey>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
//
|
|
IXIdentityProvider IdentityProvider { get; }
|
|
XDataServiceConfiguration DataConfiguration { get; }
|
|
IHubContext<XBaseEntityHub<TEntity, TKey>> Hub { get; }
|
|
IXBaseRepositoryService<TEntity, TDto, TKey> RepositoryService { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Dto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> AddAsync(
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Dto values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> UpdateAsync(
|
|
TKey id,
|
|
TDto item,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> RemoveAsync(
|
|
TKey id,
|
|
bool softDelete = true,
|
|
bool saveChanges = true,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<int> CountAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check a Dto exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsExistsAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Dto by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> GetAsync(
|
|
TKey id,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Dtos ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> GetAllAsync(
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Dto by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<TDto> FindOneAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Dtos by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<TDto>> FindManyAsync(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
bool ignoreSoftDeleteds = true,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Dtos based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<TDto>> QueryAsync(
|
|
XQuery query,
|
|
bool ignoreSoftDeleteds = true,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseRepositoryProviderController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseRepositoryProviderController<TEntity, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where THub : XBaseEntityHub<TEntity, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
IXBaseEntityProvider<TEntity, TKey, THub> Provider { get; }
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
Task<ActionResult<TEntity>> Add(
|
|
[FromBody] TEntity item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
Task<ActionResult<TEntity>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TEntity item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
Task<ActionResult<TEntity>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/[action]")]
|
|
Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Count")]
|
|
Task<ActionResult<long>> Count(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
Task<ActionResult<TEntity>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
Task<ActionResult<IEnumerable<TEntity>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne")]
|
|
Task<ActionResult<TEntity>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany")]
|
|
Task<ActionResult<IEnumerable<TEntity>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
Task<ActionResult<XQueryResult<TEntity>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Non Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseServiceProviderController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseServiceProviderController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Properties ...
|
|
IXBaseDtoProvider<TEntity, TDto, TKey, THub> Provider { get; }
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// add a new Item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update an Item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// remove an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="softDelete"></param>
|
|
/// <param name="saveChanges"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool softDelete = true,
|
|
[FromQuery] bool saveChanges = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/[action]")]
|
|
Task<ActionResult<bool>> IsExists(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Count")]
|
|
Task<ActionResult<long>> Count(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve an Item by it's Id ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve all exists Items ...
|
|
/// </summary>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet]
|
|
Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find an Item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindOne")]
|
|
Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("FindMany")]
|
|
Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="ignoreSoftDeleteds"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool ignoreSoftDeleteds = true,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Non Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseWebRTCHub.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXBaseWebRTCHub : IXBaseHub
|
|
{
|
|
/// <summary>
|
|
/// Sending WebRTC Offer To Specified Connection ...
|
|
/// </summary>
|
|
/// <param name="offer"></param>
|
|
/// <param name="to"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Offer(
|
|
string offer,
|
|
string to,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Sending WebRTC Answer to Specified Connection ...
|
|
/// </summary>
|
|
/// <param name="answer"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Answer(
|
|
string answer,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Sending WebRTC Candidate to Specified Connecton ...
|
|
/// </summary>
|
|
/// <param name="candidate"></param>
|
|
/// <param name="to"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task Candidate(
|
|
string candidate,
|
|
string to,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXHubContextFactory.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
|
|
namespace xPushService.Interfaces
|
|
{
|
|
public interface IXHubContextFactory
|
|
{
|
|
IHubContext<THub> Create<THub>() where THub : Hub;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubConnectionDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xPushService.Models
|
|
{
|
|
public class XHubConnectionDto : XBaseDto
|
|
{
|
|
public string ConnectionId { get; set; }
|
|
public string UserId { get; set; }
|
|
public string Username { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubDescriptor.cs
|
|
|
|
using System;
|
|
|
|
namespace xPushService.Models {
|
|
/// <summary>
|
|
/// Describe a Hub to Register ...
|
|
/// </summary>
|
|
public class XHubDescriptor {
|
|
/// <summary>
|
|
/// Specified the Hub Route ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Route { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specified the Hub Class Type ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public Type Hub { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubUserInfo.cs
|
|
|
|
using xModels.Base;
|
|
using xIdentityModels.Constants;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace xPushService.Models
|
|
{
|
|
public class XHubUserInfo : XBaseDto
|
|
{
|
|
//
|
|
#region Properties ...
|
|
public string UserId { get; set; }
|
|
public string UserName { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public string Picture { get; set; }
|
|
public string Email { get; set; }
|
|
public string PhoneNumber { get; set; }
|
|
public XGender Gender { get; set; }
|
|
public bool IsBanned { get; set; }
|
|
public bool IsEnabled { get; set; }
|
|
public bool EmailConfirmed { get; set; }
|
|
public bool PhoneNumberConfirmed { get; set; }
|
|
public long? ExpiredOn { get; set; }
|
|
public long? AuthenticatedOn { get; set; }
|
|
public DateTime? BrithDate { get; set; }
|
|
public IEnumerable<string> Issuers { get; set; } = new HashSet<string>();
|
|
public IEnumerable<string> Audiences { get; set; } = new HashSet<string>();
|
|
public IEnumerable<string> ClientIds { get; set; } = new HashSet<string>();
|
|
public IEnumerable<string> Scopes { get; set; } = new HashSet<string>();
|
|
public IEnumerable<string> Roles { get; set; } = new HashSet<string>();
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XBaseProvided.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Providers
|
|
{
|
|
/// <summary>
|
|
/// a Provided Service Used for Providing Data Based on Validations of Users ...
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TDto"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <typeparam name="THub"></typeparam>
|
|
public abstract class XBaseProvided<TEntity, TDto, TKey, THub> : IXBaseProvided<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
private readonly string[] permittedRoles;
|
|
private readonly IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseProvided(
|
|
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
|
|
string[] permittedRoles = null
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.permittedRoles = permittedRoles;
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Check an Items is Owned for User or not ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public abstract bool IsOwned(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
public abstract bool IsOwned(
|
|
TEntity item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check User Has Permission for Manipulate Data or not ...
|
|
/// </summary>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public bool HasPermision(
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!permittedRoles.HasChild() ||
|
|
(!userInfo.IsNullOrDefault() &&
|
|
userInfo.HasAccess(permittedRoles));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Provided Actions ...
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Get(
|
|
TKey id,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> GetAll(
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.GetAllAsync(
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> FindOne(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.FindOneAsync(
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> FindMany(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.FindManyAsync(
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TDto>> Query(
|
|
XQuery query,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// if supported ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TDto>> QueryOwned(
|
|
XQuery query,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
Expression<Func<TEntity, bool>> predicateor = null;
|
|
if (!predicate.IsNull())
|
|
{
|
|
//
|
|
var predicateFnc = predicate.Compile();
|
|
predicateor = x =>
|
|
predicateFnc(x) &&
|
|
IsOwned(x, userInfo);
|
|
}
|
|
else
|
|
{
|
|
predicateor = x => IsOwned(x, userInfo);
|
|
}
|
|
|
|
//
|
|
var result = await provider.QueryAsync(
|
|
query: query,
|
|
predicate: predicateor,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an item values ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Add(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.AddAsync(
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Update(
|
|
TKey id,
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check Permission ...
|
|
var hasPermission =
|
|
IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo);
|
|
if (!hasPermission)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Remove(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check Permission ...
|
|
var item = await Get(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var hasPermission =
|
|
IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo);
|
|
if (!hasPermission)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.RemoveAsync(
|
|
id: id,
|
|
saveChanges: true,
|
|
softDelete: false,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<int> Count(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.CountAsync(
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> IsExists(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XHubContextFactory.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xPushService.Providers
|
|
{
|
|
public class XHubContextFactory : IXHubContextFactory
|
|
{
|
|
private readonly IServiceProvider services;
|
|
|
|
public XHubContextFactory(IServiceProvider services)
|
|
{
|
|
this.services = services;
|
|
}
|
|
|
|
public IHubContext<THub> Create<THub>()
|
|
where THub : Hub
|
|
{
|
|
return services.GetRequiredService<IHubContext<THub>>();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XPushServiceUserNameProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
|
|
namespace xPushService.Providers {
|
|
public class XPushServiceUserNameProvider : IUserIdProvider {
|
|
public string GetUserId (HubConnectionContext connection) {
|
|
//
|
|
var result = connection.User?.Identity?.Name;
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Base\IXBaseService.cs
|
|
|
|
namespace xServices.Base
|
|
{
|
|
public interface IXBaseService
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Base\XBaseService.cs
|
|
|
|
namespace xServices.Base
|
|
{
|
|
public class XBaseService : IXBaseService
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Base\XTestProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Base
|
|
{
|
|
/// <summary>
|
|
/// an Abstract Implementation of Provided Actions for XTest ...
|
|
/// </summary>
|
|
public abstract class XTestProviderControllerBase : XBaseProvidedController<XTest, XTestDto, Guid, XTestDtoHub>, IXTestProviderController
|
|
{
|
|
protected XTestProviderControllerBase(
|
|
ILogger<XTestProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTestProvider provider,
|
|
Func<IQueryable<XTest>, IOrderedQueryable<XTest>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTest>, IIncludableQueryable<XTest, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Configurations\XServicesConfiguration.cs
|
|
|
|
namespace xServices.Configurations
|
|
{
|
|
public partial class XServicesConfiguration
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Configurations\XTestTypeConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Configurations
|
|
{
|
|
public class XTestTypeConfiguration : XBaseEntityTypeConfiguration<XTest, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XTest> builder)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xServices.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames
|
|
{
|
|
public const string SERVICES_NODE = "ServicesConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Constants\xServicesConstancts.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xServices.Constants
|
|
{
|
|
public class xServicesConstancts
|
|
{
|
|
}
|
|
|
|
public enum XQueryServiceEndPoints
|
|
{
|
|
/// <summary>
|
|
/// Specified Endpoint for Users Fetching as Query ...
|
|
/// </summary>
|
|
[StringValue("Account/Users/Query")]
|
|
QueryUsers,
|
|
|
|
/// <summary>
|
|
/// Refresh Tokens ...
|
|
/// </summary>
|
|
[StringValue("Account/RefreshTokens")]
|
|
RefreshTokens,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XCategoryProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Controllers;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XCategoryProviderController : XCategoryProviderControllerBase, IXCategoryProviderController
|
|
{
|
|
public XCategoryProviderController(
|
|
ILogger<XCategoryProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXCategoryProvider provider,
|
|
Func<IQueryable<XCategory>, IOrderedQueryable<XCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XCategory>, IIncludableQueryable<XCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XFileProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xFileService.Controllers;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Models.Entities;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XFileProviderController : XFileProviderControllerBase, IXFileProviderController
|
|
{
|
|
public XFileProviderController(
|
|
ILogger<XFileProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXFileProvider provider,
|
|
IXFileTagProvided tagProvided,
|
|
Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
tagProvided,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XStringProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xStringService.Controllers;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XStringProviderController : XStringProviderControllerBase, IXStringProviderController
|
|
{
|
|
public XStringProviderController(
|
|
ILogger<XStringProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXStringProvider provider,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XSubCategoryProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Controllers;
|
|
using xCategoryService.Interfaces;
|
|
using xCategoryService.Models.Entities;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XSubCategoryProviderController : XSubCategoryProviderControllerBase, IXSubCategoryProviderController
|
|
{
|
|
public XSubCategoryProviderController(
|
|
ILogger<XSubCategoryProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryProvider provider,
|
|
Func<IQueryable<XSubCategory>, IOrderedQueryable<XSubCategory>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XSubCategory>, IIncludableQueryable<XSubCategory, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XTagProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xTagService.Controllers;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XTagProviderController : XTagProviderControllerBase, IXTagProviderController
|
|
{
|
|
public XTagProviderController(
|
|
ILogger<XTagProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTagProvider provider,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XTermsAndConditionsProviderController.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xTermsAndConditionsService.Controllers;
|
|
using xTermsAndConditionsService.Interfaces;
|
|
using xTermsAndConditionsService.Providers;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XTermsAndConditionsProviderController : XTermsAndConditionsControllerBase, IXTermsAndConditionsController
|
|
{
|
|
public XTermsAndConditionsProviderController(
|
|
ILogger<XTermsAndConditionsProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTermsAndConditionsProvider provider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Controllers\XTestProviderController.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xServices.Base;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Controllers
|
|
{
|
|
public class XTestProviderController : XTestProviderControllerBase, IXTestProviderController
|
|
{
|
|
public XTestProviderController(
|
|
ILogger<XTestProviderController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTestProvider provider,
|
|
Func<IQueryable<XTest>, IOrderedQueryable<XTest>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTest>, IIncludableQueryable<XTest, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Databases\XApiDatabaseDescriptor.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using GraphQL.Types;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
using xServices.Models.GraphQL;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Databases
|
|
{
|
|
public class XApiDatabaseDescriptor : XDatabaseDescriptor<XApiDbContext>, IXDatabaseDescriptor<XApiDbContext>
|
|
{
|
|
public XApiDatabaseDescriptor() : base(
|
|
name: "xApiDb",
|
|
repositories: new List<XRepositoryDescriptor>
|
|
{
|
|
//
|
|
// XTest Entity ...
|
|
new XEFRepositoryDescriptor<
|
|
XTest,
|
|
Guid,
|
|
IXTestKeyGenerator,
|
|
XTestKeyGenerator,
|
|
IXTestRepositoryEvents,
|
|
XTestRepositoryEvents,
|
|
XTestGraphType,
|
|
GuidGraphType,
|
|
XTestGraphQuery,
|
|
IXTestGraphQLTypeHelper,
|
|
XTestGraphQLTypeHelper,
|
|
XTestGraphSchema,
|
|
IXTestRepository,
|
|
XTestEFRepository,
|
|
XApiDbContext,
|
|
IXTestSeeder,
|
|
XTestSeeder
|
|
>
|
|
{}
|
|
}
|
|
)
|
|
{
|
|
OptionsBuilder = b => b.MigrationsAssembly("xApi");
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Databases\XApiDbContext.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCategoryService.Providers;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Providers;
|
|
using xFileService.Providers;
|
|
using xServices.Models.Entities;
|
|
using xStringService.Providers;
|
|
using xTagService.Providers;
|
|
using xWebinarService.Providers;
|
|
// using xStringService.Models.Entities;
|
|
|
|
namespace xServices.Databases
|
|
{
|
|
public class XApiDbContext : XDbContext
|
|
{
|
|
//
|
|
#region DbSets ...
|
|
public DbSet<XTest> Tests { get; set; }
|
|
#endregion
|
|
|
|
//
|
|
#region Navigation Property Entities ...
|
|
#endregion
|
|
|
|
public XApiDbContext(
|
|
DbContextOptions options,
|
|
XDataServiceConfiguration config,
|
|
XEntityRegisterarHandlerService dynamicEntityHandlers
|
|
) : base(
|
|
"xApiDb",
|
|
options,
|
|
config,
|
|
dynamicEntityHandlers,
|
|
new string[] {
|
|
nameof(XTagEntityRegisterar),
|
|
nameof(XFileEntityRegisterar),
|
|
nameof(XStringEntityRegisterar),
|
|
nameof(XWebinarEntityRegisterar),
|
|
nameof(XCategoryEntityRegisterar),
|
|
nameof(XSubCategoryEntityRegisterar),
|
|
nameof(XWebinarSubscriberEntityRegisterar),
|
|
}
|
|
)
|
|
{ }
|
|
|
|
//
|
|
public override void OnXModelCreating(ModelBuilder modelBuilder)
|
|
{ }
|
|
|
|
//
|
|
public override void OnXConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\DI\XDIHelperExtension.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCategoryService.DI;
|
|
using xCommons.Extensions;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xFileService.DI;
|
|
using xIdentityService.DI;
|
|
using xMessageService.DI;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
using xServices.Configurations;
|
|
using xServices.Constants;
|
|
using xServices.Databases;
|
|
using xServices.Interfaces;
|
|
using xServices.Providers;
|
|
using xStorageService.DI;
|
|
using xStringService.DI;
|
|
using xTagService.DI;
|
|
using xTermsAndConditionsService.DI;
|
|
using xWebinarService.DI;
|
|
|
|
namespace xServices.DI
|
|
{
|
|
public static partial class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Retrive Services Configurations ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XServicesConfiguration GetXServicesConfiguration(
|
|
this IConfiguration source
|
|
)
|
|
{
|
|
//
|
|
var xConfig = source
|
|
.GetSection(ConfigurationNodeNames.SERVICES_NODE);
|
|
var result = xConfig.Get<XServicesConfiguration>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXServicesConfiguration(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
var config = configuration
|
|
.GetXServicesConfiguration();
|
|
if (config.IsNull())
|
|
{
|
|
config = new XServicesConfiguration();
|
|
}
|
|
|
|
//
|
|
services.AddSingleton(config);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service Configuration ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXServicesConfiguration(
|
|
this IServiceCollection services,
|
|
XServicesConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
if (configuration.IsNull())
|
|
{
|
|
configuration = new XServicesConfiguration();
|
|
}
|
|
|
|
//
|
|
services.AddSingleton(configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Services ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="databases"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXServices(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
IEnumerable<XDatabaseDescriptor> databases = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var config = configuration.GetXServicesConfiguration();
|
|
|
|
//
|
|
AddServices(
|
|
config: config,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
databases: databases,
|
|
configuration: configuration
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Services ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="config"></param>
|
|
/// <param name="databases"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXServices(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
XServicesConfiguration config,
|
|
IEnumerable<XDatabaseDescriptor> databases = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
AddServices(
|
|
config: config,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
databases: databases,
|
|
configuration: configuration
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use All Required Middlewares ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="databases"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXServices(
|
|
this IApplicationBuilder app,
|
|
IEnumerable<XDatabaseDescriptor> databases = null,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
// Use Storage Service ...
|
|
app.UseXStorageService();
|
|
|
|
//
|
|
#region Use Data Data Service ...
|
|
if (databases.HasChild())
|
|
{
|
|
//
|
|
databases
|
|
.ToList()
|
|
.ForEach(database =>
|
|
{
|
|
//
|
|
app.UseXDatabase(
|
|
descriptor: database,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Use Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
pushHelper.AddHub<XTestDtoHub>("testDto");
|
|
pushHelper.AddHub<XTestEntityHub>("testEntity");
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using String Service ...
|
|
app.UseXStringService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using Terms and Conditions Service ...
|
|
app.UseXTermsAndConditionsService();
|
|
|
|
//
|
|
// Using Tag Service ...
|
|
app.UseXTagService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using File Service ...
|
|
app.UseXFileService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using Category Service ...
|
|
app.UseXCategoryService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using XWebinar Service ...
|
|
app.UsexWebinarService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Register Required Services ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="databases"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddServices(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
XServicesConfiguration config = null,
|
|
IEnumerable<XDatabaseDescriptor> databases = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
// Check config ...
|
|
if (config.IsNull())
|
|
{
|
|
config = new XServicesConfiguration();
|
|
}
|
|
|
|
//
|
|
// Storage Service ...
|
|
services.AddXStorageService(configuration);
|
|
|
|
//
|
|
// Message Service ...
|
|
services.AddXMessageService(config: configuration);
|
|
|
|
//
|
|
#region Register Identity Service ...
|
|
services.AddXIdentityService(
|
|
configuration: configuration,
|
|
lifeTime: ServiceLifetime.Scoped
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Register Data Service ...
|
|
//
|
|
if (databases.HasChild())
|
|
{
|
|
//
|
|
databases
|
|
.ToList()
|
|
.ForEach(database =>
|
|
{
|
|
//
|
|
// Register DataBase ...
|
|
services.AddXDatabase(
|
|
lifeTime: lifeTime,
|
|
descriptor: database,
|
|
configuration: configuration
|
|
);
|
|
});
|
|
}
|
|
|
|
//
|
|
// Register Repository Services ...
|
|
services.AddScoped<IXTestProvider, XTestProvider>();
|
|
services.AddScoped<IXTestRepositoryService, XTestRepositoryService>();
|
|
#endregion
|
|
|
|
//
|
|
#region Register Push Service ...
|
|
//
|
|
// Push Service ...
|
|
services.AddXPushService(
|
|
config: configuration,
|
|
lifeTime: ServiceLifetime.Scoped
|
|
);
|
|
|
|
//
|
|
// Register Provider Services ...
|
|
// since Hubs required Identity Provider, you Have to Register IdentityService as Requirements ...
|
|
// a Provider Service, Provides Repository (Entity) or Service (Dto) based
|
|
// Data Manipulation Actions by Supporting Hub Contexts Events ...
|
|
services.AddScoped<IXTestServiceProvider, XTestServiceProvider>();
|
|
services.AddScoped<IXTestRepositoryProvider, XTestRepositoryProvider>();
|
|
#endregion
|
|
|
|
//
|
|
var repositoryType = xDataService.Constants.XRepositoryType.EF;
|
|
|
|
//
|
|
// Register String Service ...
|
|
services.AddXStringService<XApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register Terms and Conditions Service ...
|
|
services.AddXTermsConditionsService(
|
|
lifeTime: lifeTime,
|
|
configuration: configuration
|
|
);
|
|
|
|
//
|
|
// Register Tag Service ...
|
|
services.AddXTagService<XApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register File Service ...
|
|
services.AddXFileService<XApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register Category Service ...
|
|
services.AddXCategoryServiceConfiguration(configuration);
|
|
services.AddXCategoryService<XApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register Webinar Service ...
|
|
services.AddXWebinarService<XApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Extensions\xServicesExtensions.cs
|
|
|
|
namespace xServices.Extensions
|
|
{
|
|
public static class xServicesExtensions
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestDtoHub.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestDtoHub : IXBaseDtoHub<XTest, XTestDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestEntityHub.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestEntityHub : IXBaseEntityHub<XTest, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XTest, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
using xServices.Models.GraphQL;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestGraphQuery : IXBaseGraphQLQuery<XTest, Guid, XTestGraphType, GuidGraphType>
|
|
{}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestKeyGenerator.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestKeyGenerator : IXKeyGenerator<XTest, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestProvider.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestProvider : IXBaseProvided<XTest, XTestDto, Guid, XTestDtoHub>
|
|
{}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestProviderController.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestProviderController : IXBaseProvidedController<XTest, XTestDto, Guid, XTestDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestRepository : IXBaseRepository<XTest, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestRepositoryEvents : IXBaseRepositoryEvents<XTest>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestRepositoryProvider : IXBaseEntityProvider<XTest, Guid, XTestEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestRepositoryService.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestRepositoryService : IXBaseRepositoryService<XTest, XTestDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestSeeder.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestSeeder : IXBaseDbSeeder<XTest, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Interfaces\IXTestServiceProvider.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
using xServices.Providers;
|
|
|
|
namespace xServices.Interfaces
|
|
{
|
|
public interface IXTestServiceProvider : IXBaseDtoProvider<XTest, XTestDto, Guid, XTestDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Models\Dtos\XTestDto.cs
|
|
|
|
using System;
|
|
using xModels.Base;
|
|
|
|
namespace xServices.Models.Dtos
|
|
{
|
|
public class XTestDto : XBaseEntityDto<Guid>
|
|
{
|
|
public string Firstname { get; set; }
|
|
public string Lastname { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Models\Entities\XTest.cs
|
|
|
|
using System;
|
|
using xModels.Base;
|
|
|
|
namespace xServices.Models.Entities
|
|
{
|
|
public class XTest : XBaseEntity<Guid>
|
|
{
|
|
public string Firstname { get; set; }
|
|
public string Lastname { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Models\GraphQL\XTestGraphType.cs
|
|
|
|
using System;
|
|
using xDataService.GraphQL;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Models.GraphQL
|
|
{
|
|
public class XTestGraphType : XBaseGraphObjectType<XTest, Guid>
|
|
{
|
|
public XTestGraphType() : base()
|
|
{
|
|
Field(x => x.Firstname);
|
|
Field(x => x.Lastname);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Models\XGroupedData.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using xModels.Base;
|
|
|
|
namespace xServices.Models
|
|
{
|
|
public class XGroupedDataEntity<T, TKey, TGroupedKey>
|
|
where T : XBaseEntity<TKey>
|
|
{
|
|
public TGroupedKey GroupedBy { set; get; }
|
|
public IEnumerable<T> Members { set; get; }
|
|
public DateTime TimeStamp { set; get; }
|
|
}
|
|
|
|
public class XGroupedDataDto<T, TGroupedKey>
|
|
where T : XBaseDto
|
|
{
|
|
public TGroupedKey GroupedBy { set; get; }
|
|
public IEnumerable<T> Members { set; get; }
|
|
public DateTime TimeStamp { set; get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestDtoHub : XBaseDtoHub<XTest, XTestDto, Guid>, IXTestDtoHub
|
|
{
|
|
public XTestDtoHub(ILogger<XTestDtoHub> logger) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestEFRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xDataService.Interfaces;
|
|
using xServices.Databases;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestEFRepository : XBaseEFRepository<XTest, Guid, XApiDbContext>, IXTestRepository
|
|
{
|
|
public XTestEFRepository(
|
|
IXUnitOfWorks<XApiDbContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXTestKeyGenerator keyGenerator = null,
|
|
IXTestRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestEntityHub : XBaseEntityHub<XTest, Guid>, IXTestEntityHub
|
|
{
|
|
public XTestEntityHub(ILogger<XBaseHub> logger) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestGraphQLTypeHelper : XBaseGraphQLTypeHelper<XTest, Guid>, IXTestGraphQLTypeHelper
|
|
{
|
|
public XTestGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{
|
|
}
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return "tests";
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return "test";
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
using xServices.Models.GraphQL;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestGraphQuery : XBaseGraphQLQuery<XTest, Guid, XTestGraphType, GuidGraphType>
|
|
{
|
|
public XTestGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXTestRepository repository,
|
|
IXTestGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestGraphSchema : Schema
|
|
{
|
|
public XTestGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XTestGraphQuery)services.GetService(typeof(XTestGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestInMemoryRepository : XBaseInMemoryRepository<XTest, Guid>
|
|
{
|
|
public XTestInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXTestKeyGenerator keyGenerator = null,
|
|
IXTestRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestKeyGenerator : XGuidKeyGenerator<XTest>, IXTestKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestMongoRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestMongoRepository : XBaseMongoRepository<XTest, Guid>
|
|
{
|
|
public XTestMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXTestKeyGenerator keyGenerator = null,
|
|
IXTestRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestProvider.cs
|
|
|
|
using System;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xPushService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestProvider : XBaseProvided<XTest, XTestDto, Guid, XTestDtoHub>, IXTestProvider
|
|
{
|
|
public XTestProvider(
|
|
IXTestServiceProvider provider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{ }
|
|
|
|
public override bool IsOwned(
|
|
XTestDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XTest item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return item.IsNullOrDefault();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestRepositoryEvents : XBaseRepositoryEvents<XTest>, IXTestRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestRepositoryProvider : XBaseEntityProvider<XTest, Guid, XTestEntityHub>, IXTestRepositoryProvider
|
|
{
|
|
public XTestRepositoryProvider(
|
|
IXTestRepository repository,
|
|
IHubContext<XTestEntityHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub: hub,
|
|
repository: repository,
|
|
identityProvider: identityProvider,
|
|
dataConfiguration: dataConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestRepositoryService : XBaseRepositoryService<XTest, XTestDto, Guid>, IXTestRepositoryService
|
|
{
|
|
public XTestRepositoryService(
|
|
IXTestRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(repository, mapperProfiles)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestSeeder.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestSeeder : XBaseDbSeeder<XTest, Guid>, IXTestSeeder
|
|
{
|
|
public XTestSeeder(
|
|
IXTestRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
database: "xApiDb",
|
|
entity: nameof(XTest),
|
|
repository: repository,
|
|
dataServiceConfiguration: dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xServices\Providers\XTestServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xServices.Interfaces;
|
|
using xServices.Models.Dtos;
|
|
using xServices.Models.Entities;
|
|
|
|
namespace xServices.Providers
|
|
{
|
|
public class XTestServiceProvider : XBaseDtoProvider<XTest, XTestDto, Guid, XTestDtoHub>, IXTestServiceProvider
|
|
{
|
|
public XTestServiceProvider(
|
|
IHubContext<XTestDtoHub> hub,
|
|
IXTestRepositoryService service,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub: hub,
|
|
service: service,
|
|
identityProvider: identityProvider,
|
|
dataConfiguration: dataConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xStorageService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string STORAGE_SERVICE_NODE_NAME = "StorageConfiguration";
|
|
}
|
|
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\FileExtensions.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xStorageService.Constants {
|
|
public enum FileExtensions {
|
|
//
|
|
// Document
|
|
[StringValue (".txt")]
|
|
TEXT = 100,
|
|
|
|
[StringValue (".pdf")]
|
|
PDF = 101,
|
|
|
|
[StringValue (".ppt")]
|
|
PPT = 102,
|
|
|
|
[StringValue (".pptx")]
|
|
PPTX = 103,
|
|
|
|
[StringValue (".odp")]
|
|
ODP = 104,
|
|
|
|
[StringValue (".pps")]
|
|
PPS = 105,
|
|
|
|
[StringValue (".ods")]
|
|
ODS = 106,
|
|
|
|
[StringValue (".xlr")]
|
|
XLR = 107,
|
|
|
|
[StringValue (".xls")]
|
|
XLS = 108,
|
|
|
|
[StringValue (".xlsx")]
|
|
XLSX = 109,
|
|
|
|
[StringValue (".xml")]
|
|
XML = 110,
|
|
|
|
[StringValue (".doc")]
|
|
DOC = 111,
|
|
|
|
[StringValue (".docx")]
|
|
DOCX = 112,
|
|
|
|
[StringValue (".odt")]
|
|
ODT = 113,
|
|
|
|
[StringValue (".rtf")]
|
|
RTF = 114,
|
|
|
|
[StringValue (".tex")]
|
|
TEX = 115,
|
|
|
|
[StringValue (".wpd")]
|
|
WPD = 116,
|
|
|
|
[StringValue (".md")]
|
|
MD = 117,
|
|
|
|
//
|
|
// Archive
|
|
[StringValue (".zip")]
|
|
ZIP = 200,
|
|
|
|
//
|
|
// Internal Supports
|
|
[StringValue (".ttf")]
|
|
TTF = 300,
|
|
|
|
[StringValue (".js")]
|
|
JAVASCRIPT = 301,
|
|
|
|
[StringValue (".css")]
|
|
CSS = 302,
|
|
|
|
[StringValue (".htm")]
|
|
HTM = 303,
|
|
|
|
[StringValue (".html")]
|
|
HTML = 304,
|
|
|
|
[StringValue (".sdw")]
|
|
SAHER_DASHBOARD_WIDGET = 305,
|
|
|
|
[StringValue (".sdwmanifest")]
|
|
SAHER_DASHBOARD_WIDGET_MANIFEST = 306,
|
|
|
|
//
|
|
// Video
|
|
[StringValue (".mp4")]
|
|
MP4 = 400,
|
|
|
|
[StringValue (".avi")]
|
|
AVI = 401,
|
|
|
|
[StringValue (".mpg")]
|
|
MPG = 402,
|
|
|
|
[StringValue (".mpeg")]
|
|
MPEG = 403,
|
|
|
|
[StringValue (".wmv")]
|
|
WMV = 404,
|
|
|
|
//
|
|
// Audio
|
|
[StringValue (".mp3")]
|
|
MP3 = 500,
|
|
|
|
[StringValue (".ogg")]
|
|
OGG = 501,
|
|
|
|
[StringValue (".wav")]
|
|
WAV = 502,
|
|
|
|
[StringValue (".wma")]
|
|
WMA = 503,
|
|
|
|
//
|
|
// Image
|
|
[StringValue (".png")]
|
|
PNG = 600,
|
|
|
|
[StringValue (".jpeg")]
|
|
JPEG = 601,
|
|
|
|
[StringValue (".jpg")]
|
|
JPG = 602,
|
|
|
|
// [StringValue (".ico")]
|
|
// ICON = 603,
|
|
|
|
[StringValue (".gif")]
|
|
GIF = 604,
|
|
|
|
[StringValue (".bmp")]
|
|
BITMAP = 605,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\DI\XDIHelperExtension.cs
|
|
|
|
using System.IO;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
using xStorageService.Providers;
|
|
|
|
namespace xStorageService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XStorage Configuration from AppSettings
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XStorageConfiguration GetXStorageConfiguration (this IConfiguration configuration) {
|
|
//
|
|
var storageConfigurationSection = configuration.GetSection (ConfigurationNodeNames.STORAGE_SERVICE_NODE_NAME);
|
|
return storageConfigurationSection.Get<XStorageConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XStorage Configuration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXStorageConfiguration (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Check wwwroot Folder ...
|
|
if (!Directory.Exists ("wwwroot")) {
|
|
Directory.CreateDirectory ("wwwroot");
|
|
}
|
|
|
|
//
|
|
// Retrieve and Register XStorage Configurations ...
|
|
var xStorageConfiguration = configuration.GetXStorageConfiguration ();
|
|
if (xStorageConfiguration.IsNull ()) {
|
|
XException.InvalidConfiguration.Throw ();
|
|
}
|
|
|
|
//
|
|
xStorageConfiguration.BaseFolder = Path.Combine (Directory.GetCurrentDirectory (), "wwwroot");
|
|
xStorageConfiguration.RootFolder = Directory.GetDirectoryRoot (xStorageConfiguration.BaseFolder);
|
|
|
|
//
|
|
services.AddSingleton<XStorageConfiguration> (xStorageConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XStorage Service
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
public static void AddXStorageService (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Register and Retrieve XStorage Configuration
|
|
services.AddXStorageConfiguration (configuration);
|
|
var xStorageConfiguration = services.GetRegisteredService<XStorageConfiguration> ();
|
|
|
|
//
|
|
// Add File Provider ...
|
|
services.AddSingleton<IFileProvider> (
|
|
new PhysicalFileProvider (xStorageConfiguration.BaseFolder)
|
|
);
|
|
|
|
//
|
|
// Register XStorageHelper Service ...
|
|
services.AddSingleton<XStorageHelper> ();
|
|
|
|
//
|
|
// Register ThumbnailHelper ...
|
|
services.AddSingleton<IXThumbnailProvider, XThumbnailProvider> ();
|
|
|
|
//
|
|
// Register Storage Provider ...
|
|
services.AddScoped<IXStorageProvider, XStorageProvider> ();
|
|
|
|
//
|
|
// StorageService Preperation...
|
|
var xStorageService = services.GetRegisteredService<IXStorageProvider> ();
|
|
xStorageService.Prepare ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XStorage Service
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXStorageService (this IApplicationBuilder app) {
|
|
//
|
|
// Get Instance of Scope and Service and Prepare Folder Structure ...
|
|
using (var scope = app.ApplicationServices.CreateScope ()) {
|
|
//
|
|
var storageProvider = scope.ServiceProvider.GetService<IXStorageProvider> ();
|
|
|
|
//
|
|
storageProvider.Prepare ();
|
|
}
|
|
|
|
//
|
|
// available Static Files ...
|
|
app.UseStaticFiles ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Helpers\XStorageHelper.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xStorageService.Constants;
|
|
|
|
namespace xStorageService.Helpers {
|
|
public partial class XStorageHelper {
|
|
|
|
private int[] DocumentTypeThreshold = new int[] { 99, 307 };
|
|
private int[] ImageTypeThreshold = new int[] { 599, 606 };
|
|
private int[] AudioTypeThreshold = new int[] { 499, 504 };
|
|
private int[] VideoTypeThreshold = new int[] { 399, 405 };
|
|
|
|
public XStorageHelper () { }
|
|
|
|
/// <summary>
|
|
/// Retrieve FileType
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetType (int fileExtension) {
|
|
//
|
|
// Compare File Extension Integer Value and
|
|
// Find Propper Type for it ...
|
|
if (fileExtension > DocumentTypeThreshold[0] && fileExtension < DocumentTypeThreshold[1]) {
|
|
return XFileType.Document;
|
|
} else if (fileExtension > VideoTypeThreshold[0] && fileExtension < VideoTypeThreshold[1]) {
|
|
return XFileType.Video;
|
|
} else if (fileExtension > AudioTypeThreshold[0] && fileExtension < AudioTypeThreshold[1]) {
|
|
return XFileType.Audio;
|
|
} else if (fileExtension > ImageTypeThreshold[0] && fileExtension < ImageTypeThreshold[1]) {
|
|
return XFileType.Image;
|
|
} else {
|
|
//
|
|
// if not in case return Document Type
|
|
return XFileType.Document;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File Type
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetType (string fileName) {
|
|
//
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
XException.InavlidFile.Throw ();
|
|
}
|
|
|
|
//
|
|
var ext = GetFileExtension (fileName);
|
|
var extType = GetExtensionType (ext);
|
|
return GetType (extType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// used for validating Extension in Widget Upload ...
|
|
/// </summary>
|
|
/// <returns>an string array</returns>
|
|
public string[] GetAllowedExtensionsForWidgetUpload () {
|
|
return new [] {
|
|
FileExtensions.SAHER_DASHBOARD_WIDGET.GetStringValue ()
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Files Extension string
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileExtension (string fileName) {
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var fileExt = "";
|
|
try {
|
|
fileExt = Path.GetExtension (fileName);
|
|
} catch { }
|
|
|
|
//
|
|
return fileExt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a File Name Without it's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileNameWithoutExtension (string fileName) {
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var fileNameWithoutExt = "";
|
|
try {
|
|
fileNameWithoutExt = Path
|
|
.GetFileNameWithoutExtension (fileName);
|
|
} catch { }
|
|
|
|
//
|
|
return fileNameWithoutExt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get File Extension Type
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public int GetExtensionType (string fileExtension) {
|
|
//
|
|
foreach (var extItem in Enum
|
|
.GetValues (typeof (FileExtensions))
|
|
.Cast<FileExtensions> ()) {
|
|
if (extItem.GetStringValue ()
|
|
.Contains (fileExtension.ToLower ())) {
|
|
return (int) extItem;
|
|
}
|
|
}
|
|
|
|
//
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXStorageProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Constants;
|
|
using xModels.Dtos;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Interfaces
|
|
{
|
|
public partial interface IXStorageProvider
|
|
{
|
|
XStorageConfiguration Configuration { get; }
|
|
XStorageHelper StorageHelper { get; }
|
|
IFileProvider FileProvider { get; }
|
|
IXThumbnailProvider ThumbnailProvider { get; }
|
|
|
|
//
|
|
#region Special Folders Path Getter (s) ...
|
|
string GetStorageFolderPath();
|
|
string GetTempFolderPath();
|
|
string GetThumbFolderPath();
|
|
string GetUploadsFolderPath();
|
|
string GetWidgetsFolderPath();
|
|
string GetImageFolderPath();
|
|
string GetAudioFolderPath();
|
|
string GetVideoFolderPath();
|
|
string GetDocumentFolderPath();
|
|
string FilePathResolver(string fullPath);
|
|
string ConvertToFileUrl(string fullPath);
|
|
#endregion
|
|
|
|
//
|
|
#region Prepare Storage Structure ...
|
|
void Prepare();
|
|
#endregion
|
|
|
|
//
|
|
#region Validators ...
|
|
bool IsFolderExists(string path);
|
|
bool IsFileExists(string filePath);
|
|
bool IsSupportThumb(string fileName);
|
|
bool IsSupportThumb(XFileType type);
|
|
void ValidateFileExists(string filePath);
|
|
void ValidateFileModel(XFileDto file);
|
|
void ValidateFile(IFormFile file);
|
|
void ValidateProfileImage(IFormFile file);
|
|
#endregion
|
|
|
|
//
|
|
#region Generators ...
|
|
string NewFileName();
|
|
string GenerateThumbName(string fileName);
|
|
string GetNewFileName(string fileName);
|
|
#endregion
|
|
|
|
//
|
|
#region Tools Actions ...
|
|
|
|
string GetFileExtension(string fileName);
|
|
string GetFileNameWithoutExtension(string fileName);
|
|
FileExtensions GetFileExtensionType(string fileName);
|
|
XFileType GetFileType(string fileName);
|
|
XFileType GetFileType(FileExtensions fileExtension);
|
|
string GetThumbnailFileFullPath(string thumFileName);
|
|
string GetRelatedThumbnailFullPath(string fileName);
|
|
string GetFileTypeFolderPath(XFileType type);
|
|
string GetFileFolderPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
);
|
|
string GetFileFullPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
);
|
|
Task<string> SaveFileAsync(
|
|
IFormFile file,
|
|
bool isTemp = false,
|
|
bool isWidget = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
void DeleteFile(
|
|
string fileFullPath,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
);
|
|
ICollection<string> DeleteFiles(
|
|
ICollection<string> fileFullPaths,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
);
|
|
// Task CreateThumbnail (XFile file);
|
|
Task CreateThumbnail(
|
|
XFileDto file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task CreateThumbnail(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<XFileResult> HandleProfileImageSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<XFileResult> HandleFileSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<IEnumerable<XFileResult>> HandleFilesSave(
|
|
IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXThumbnailProvider.cs
|
|
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Interfaces {
|
|
public partial interface IXThumbnailProvider {
|
|
void SetTempFolder (string folder);
|
|
XImageInfo GetImageInfo (string filePath);
|
|
void ResizeImage (
|
|
string filePath,
|
|
string resizedFilePath,
|
|
int size,
|
|
int quality
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XFileResult.cs
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XFileResult {
|
|
public string Name { get; set; }
|
|
public string FileName { get; set; }
|
|
public string FilePath { get; set; }
|
|
public string Thmbnail { get; set; }
|
|
public string ThmbnailPath { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XImageInfo.cs
|
|
|
|
using ImageMagick;
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XImageInfo {
|
|
public Interlace Interlace { get; }
|
|
public int Height { get; }
|
|
public MagickFormat Format { get; }
|
|
public string FileName { get; }
|
|
public Density Density { get; }
|
|
public CompressionMethod Compression { get; }
|
|
public ColorSpace ColorSpace { get; }
|
|
public int Width { get; }
|
|
public int Quality { get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XStorageConfiguration.cs
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XStorageConfiguration {
|
|
/// <summary>
|
|
/// Base Path of Identity Host Server
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IdentityAuthority { get; set; }
|
|
|
|
/// <summary>
|
|
/// Base Path of Host Server
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Authority { get; set; }
|
|
|
|
/// <summary>
|
|
/// Root Directory Of File Storage
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string RootFolder { get; set; }
|
|
|
|
/// <summary>
|
|
/// Base Root of Usable Folder for Files
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string BaseFolder { get; set; }
|
|
|
|
/// <summary>
|
|
/// Storage Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Storage { get; set; }
|
|
|
|
/// <summary>
|
|
/// Temp Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Temp { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumb Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Thumb { get; set; }
|
|
|
|
/// <summary>
|
|
/// Uploads Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Uploads { get; set; }
|
|
|
|
/// <summary>
|
|
/// Widgets Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Widgets { get; set; }
|
|
|
|
/// <summary>
|
|
/// Images Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Image { get; set; }
|
|
|
|
/// <summary>
|
|
/// Audios Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Audio { get; set; }
|
|
|
|
/// <summary>
|
|
/// Videos Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Video { get; set; }
|
|
|
|
/// <summary>
|
|
/// Documents Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Document { get; set; }
|
|
|
|
/// <summary>
|
|
/// new Files Prefix
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string FilePrefix { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumb Files Prefix
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string ThumbPrefix { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail File Sizes
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int ThumbSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail File Quality
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int ThumbQuality { get; set; }
|
|
|
|
/// <summary>
|
|
/// Max File Size
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long MaxFileSize { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XStorageProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Providers
|
|
{
|
|
public partial class XStorageProvider : IXStorageProvider
|
|
{
|
|
|
|
public readonly string BasePath;
|
|
private readonly XFileType[] ThumbSupprtedTypes = new XFileType[] {
|
|
XFileType.Image, XFileType.CoverImage, XFileType.ProfileImasge
|
|
};
|
|
|
|
public IFileProvider FileProvider { get; }
|
|
public XStorageHelper StorageHelper { get; }
|
|
public IXThumbnailProvider ThumbnailProvider { get; }
|
|
public XStorageConfiguration Configuration { get; }
|
|
|
|
public XStorageProvider(
|
|
IFileProvider fileProvider,
|
|
XStorageHelper storageHelper,
|
|
IXThumbnailProvider thumbnailProvider,
|
|
XStorageConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
FileProvider = fileProvider;
|
|
Configuration = configuration;
|
|
StorageHelper = storageHelper;
|
|
ThumbnailProvider = thumbnailProvider;
|
|
|
|
//
|
|
BasePath = Path
|
|
.Combine(Directory
|
|
.GetCurrentDirectory(), Configuration.BaseFolder);
|
|
}
|
|
|
|
//
|
|
#region Special Folders Path Getter (s) ...
|
|
/// <summary>
|
|
/// Get Storage Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetStorageFolderPath()
|
|
{
|
|
return Path.Combine(BasePath, Configuration.Storage);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Temp Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetTempFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Temp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Uploads Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetUploadsFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Uploads);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Widgets Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetWidgetsFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Widgets);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Thumb Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetThumbFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Thumb);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Images Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetImageFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Image);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Audios Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetAudioFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Audio);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Videos Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetVideoFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Video);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Documents Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetDocumentFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Document);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Full Path to Use for Static Files
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string FilePathResolver(string fullPath)
|
|
{
|
|
return fullPath.Replace(BasePath, "");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a File Path to Url
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string ConvertToProfileImageUrl(string fullPath)
|
|
{
|
|
//
|
|
var authority = !Configuration.IdentityAuthority.IsNullOrEmpty() &&
|
|
Configuration.IdentityAuthority.EndsWith("/") ?
|
|
Configuration.IdentityAuthority.Substring(0, Configuration.IdentityAuthority.Length - 1) :
|
|
Configuration.IdentityAuthority;
|
|
|
|
//
|
|
return $"{authority}{FilePathResolver(fullPath)}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a File Path to Url
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string ConvertToFileUrl(string fullPath)
|
|
{
|
|
//
|
|
var authority = !Configuration.Authority.IsNullOrEmpty() &&
|
|
Configuration.Authority.EndsWith("/") ?
|
|
Configuration.Authority.Substring(0, Configuration.Authority.Length - 1) :
|
|
Configuration.Authority;
|
|
|
|
//
|
|
return $"{authority}/{FilePathResolver(fullPath)}";
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Prepare Storage Structure ...
|
|
/// <summary>
|
|
/// Check Folder Structure of Storage Area
|
|
/// and Create them if not Exists
|
|
/// </summary>
|
|
public void Prepare()
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Storage Folder Path Check ...
|
|
if (!IsFolderExists(GetStorageFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetStorageFolderPath());
|
|
}
|
|
|
|
//
|
|
// Temp Folder Path Check ...
|
|
if (!IsFolderExists(GetTempFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetTempFolderPath());
|
|
}
|
|
|
|
//
|
|
// Temp Folder Path Check ...
|
|
if (!IsFolderExists(GetThumbFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetThumbFolderPath());
|
|
}
|
|
|
|
//
|
|
// Widgets Folder Path Chekc ...
|
|
if (!IsFolderExists(GetWidgetsFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetWidgetsFolderPath());
|
|
}
|
|
|
|
//
|
|
// Uploads Folder Path Chekc ...
|
|
if (!IsFolderExists(GetUploadsFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetUploadsFolderPath());
|
|
}
|
|
|
|
//
|
|
// Image Folder Path Chekc ...
|
|
if (!IsFolderExists(GetImageFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetImageFolderPath());
|
|
}
|
|
|
|
//
|
|
// Music Folder Path Chekc ...
|
|
if (!IsFolderExists(GetAudioFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetAudioFolderPath());
|
|
}
|
|
|
|
//
|
|
// Video Folder Path Chekc ...
|
|
if (!IsFolderExists(GetVideoFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetVideoFolderPath());
|
|
}
|
|
|
|
//
|
|
// Document Folder Path Chekc ...
|
|
if (!IsFolderExists(GetDocumentFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetDocumentFolderPath());
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
XException.StorageServiceInitialFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Set Temp Folder for Actions ...
|
|
ThumbnailProvider.SetTempFolder(GetTempFolderPath());
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Validators ...
|
|
/// <summary>
|
|
/// Detrmines a Path Exists or not
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public bool IsFolderExists(string path)
|
|
{
|
|
return Directory.Exists(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a File Exists or not
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public bool IsFileExists(string filePath)
|
|
{
|
|
return File.Exists(filePath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a File Name Support Thumbnail or not
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public bool IsSupportThumb(string fileName)
|
|
{
|
|
//
|
|
if (!fileName.StartsWith(Configuration.FilePrefix))
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
var fileType = StorageHelper.GetType(fileName);
|
|
return IsSupportThumb(fileType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a FileType Support Thumbnail or not
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public bool IsSupportThumb(XFileType type)
|
|
{
|
|
return ThumbSupprtedTypes.Contains(type);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a File Exists or not
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
public void ValidateFileExists(string filePath)
|
|
{
|
|
//
|
|
if (!IsFileExists(filePath))
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a File Model with it's Related Physical File
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateFileModel(XFileDto file)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (file == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Full File Path ...
|
|
var fileFullPath = file.Path;
|
|
if (fileFullPath.IsNullOrEmpty())
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve is File Exists or not ...
|
|
var isPhysicalFileExists = IsFileExists(file.Path);
|
|
if (!isPhysicalFileExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate File for Upload
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateFile(IFormFile file)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (file == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check File Size not Zero ...
|
|
if (file.Length == 0)
|
|
{
|
|
XException.EmptyFile.Throw();
|
|
}
|
|
|
|
//
|
|
// Check File Max Size ...
|
|
if (file.Length > Configuration.MaxFileSize)
|
|
{
|
|
XException.MaxFileSizeExceeded.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Collection of IFormFile
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
public void ValidateFiles(IFormFileCollection files)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!files.HasChild())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
files.ToList()
|
|
.ForEach(f => ValidateFile(f));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate File for Profile Image
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateProfileImage(IFormFile file)
|
|
{
|
|
//
|
|
// Check File Validation ...
|
|
// since Args Checked in File Validation, there is no need to
|
|
// double check it ...
|
|
ValidateFile(file);
|
|
|
|
//
|
|
// Check File Type ...
|
|
var fileType = GetFileType(file.FileName);
|
|
if (fileType != XFileType.Image)
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Generators ...
|
|
/// <summary>
|
|
/// Generate New File
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string NewFileName()
|
|
{
|
|
return Configuration.FilePrefix + Guid.NewGuid().ToString().ToLower();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Related Thumnail File
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GenerateThumbName(string fileName)
|
|
{
|
|
//
|
|
if (!IsSupportThumb(fileName))
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
|
|
//
|
|
return fileName.Replace(Configuration.FilePrefix, Configuration.ThumbPrefix);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a New FileName with Extension based on Given fileName
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetNewFileName(string fileName)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var fileExt = GetFileExtension(fileName);
|
|
var newFileNameWithoutExt = NewFileName();
|
|
|
|
//
|
|
// Generate New File Name ...
|
|
var newFileName = string.Format("{0}{1}", newFileNameWithoutExt, fileExt);
|
|
|
|
//
|
|
return newFileName;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools Actions ...
|
|
/// <summary>
|
|
/// Extract a FileName's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileExtension(string fileName)
|
|
{
|
|
//
|
|
var result = StorageHelper.GetFileExtension(fileName);
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract a FileName's Without it's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileNameWithoutExtension(string fileName)
|
|
{
|
|
//
|
|
var result = StorageHelper.GetFileNameWithoutExtension(fileName);
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get file Extension of Specified File Name
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public FileExtensions GetFileExtensionType(string fileName)
|
|
{
|
|
//
|
|
var fileExt = GetFileExtension(fileName);
|
|
if (fileExt.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
var result = StorageHelper.GetExtensionType(fileExt);
|
|
if (result == -1)
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
|
|
//
|
|
return (FileExtensions)result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return File Type of Specific File Name
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetFileType(string fileName)
|
|
{
|
|
//
|
|
var fileExtension = GetFileExtensionType(fileName);
|
|
return GetFileType(fileExtension);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return File Type of Specific Extension
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetFileType(FileExtensions fileExtension)
|
|
{
|
|
return StorageHelper.GetType((int)fileExtension);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Full Path of thumbnail File
|
|
/// </summary>
|
|
/// <param name="thumFileName"></param>
|
|
/// <returns></returns>
|
|
public string GetThumbnailFileFullPath(string thumFileName)
|
|
{
|
|
//
|
|
if (!thumFileName.StartsWith(Configuration.ThumbPrefix))
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
return Path.Combine(GetThumbFolderPath(), thumFileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File Thumbnail Path if Supported
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetRelatedThumbnailFullPath(string fileName)
|
|
{
|
|
//
|
|
var thumbName = GenerateThumbName(fileName);
|
|
return GetThumbnailFileFullPath(thumbName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Special File Type's Folder Path
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public string GetFileTypeFolderPath(XFileType type)
|
|
{
|
|
//
|
|
// Retrieve Folder Path Based on file ...
|
|
switch (type)
|
|
{
|
|
case XFileType.Image:
|
|
case XFileType.CoverImage:
|
|
case XFileType.ProfileImasge:
|
|
return GetImageFolderPath();
|
|
|
|
case XFileType.Audio:
|
|
return GetAudioFolderPath();
|
|
|
|
case XFileType.Video:
|
|
return GetVideoFolderPath();
|
|
|
|
case XFileType.Document:
|
|
default:
|
|
return GetDocumentFolderPath();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File's Folder path
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <returns></returns>
|
|
public string GetFileFolderPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var fileType = GetFileType(fileName);
|
|
|
|
//
|
|
var folderPath = "";
|
|
|
|
//
|
|
// if isTemp equals true
|
|
// ignore file type and return Temp Folder ...
|
|
if (isTemp)
|
|
{
|
|
folderPath = GetTempFolderPath();
|
|
}
|
|
|
|
//
|
|
// if isWidget equals true and isTemp equals false
|
|
// ignore file type and return Widget's Folder ...
|
|
if (isWidget && !isTemp)
|
|
{
|
|
folderPath = GetWidgetsFolderPath();
|
|
}
|
|
|
|
//
|
|
// if both isTemp and isWidget equals false
|
|
// which is the default state, retrieve proper folder path
|
|
// based on file type and return it ...
|
|
if (!isTemp && !isWidget)
|
|
{
|
|
folderPath = GetFileTypeFolderPath(fileType);
|
|
}
|
|
|
|
//
|
|
// Check folderPath restrict to have Value ...
|
|
if (folderPath.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// return result ...
|
|
return folderPath;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Full path of a File
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <returns></returns>
|
|
public string GetFileFullPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
)
|
|
{
|
|
//
|
|
var folderPath = GetFileFolderPath(
|
|
fileName,
|
|
isTemp: isTemp,
|
|
isWidget: isWidget
|
|
);
|
|
|
|
//
|
|
if (folderPath.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return Path.Combine(folderPath, fileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save a File into Storage Based on it's Type
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> SaveFileAsync(
|
|
IFormFile file,
|
|
bool isTemp = false,
|
|
bool isWidget = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidateFile(file);
|
|
|
|
//
|
|
// Extract and Generate required Data ...
|
|
var fileName = GetNewFileName(file.FileName);
|
|
var folderPath = GetFileFolderPath(file.FileName, isTemp, isWidget);
|
|
var fileFullPath = Path.Combine(folderPath, fileName);
|
|
|
|
//
|
|
// Save File ...
|
|
using (var stream = new FileStream(fileFullPath, FileMode.Create))
|
|
{
|
|
//
|
|
await file.CopyToAsync(
|
|
stream,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Since all Required data can be Generated based on
|
|
// a simple file Name, there is no need to return additional
|
|
// data as result ...
|
|
return fileName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete a Physical File by Validate it's Exists
|
|
/// </summary>
|
|
/// <param name="fileFullPath"></param>
|
|
/// <param name="forceFileExists"></param>
|
|
/// <param name="exception"></param>
|
|
public void DeleteFile(
|
|
string fileFullPath,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!forceFileExists &&
|
|
fileFullPath.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
// Check File Exists ...
|
|
var isFileExists = File.Exists(fileFullPath);
|
|
if (forceFileExists &&
|
|
!isFileExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Handle Prevent Error when forceFileExists false
|
|
// and File doesn't Exists ...
|
|
if (!forceFileExists &&
|
|
!isFileExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
File.Delete(fileFullPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a List of Physical Files Path
|
|
/// and return Un Removable Files ...
|
|
/// </summary>
|
|
/// <param name="fileFullPaths"></param>
|
|
/// <param name="forceFileExists"></param>
|
|
/// <param name="exception"></param>
|
|
/// <returns></returns>
|
|
public ICollection<string> DeleteFiles(
|
|
ICollection<string> fileFullPaths,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
if (exception.IsNull())
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
var result = fileFullPaths.Where(f => !IsFileExists(GetFileFullPath(f))).ToList();
|
|
if (forceFileExists && result.HasChild())
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
var existsFile = fileFullPaths.Where(f => IsFileExists(f)).ToList();
|
|
existsFile.ForEach(f =>
|
|
{
|
|
DeleteFile(
|
|
f,
|
|
forceFileExists: forceFileExists,
|
|
exception: exception
|
|
);
|
|
});
|
|
|
|
//
|
|
return fileFullPaths.Except(existsFile).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create Thumbnail based on FileName.Ext
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateThumbnail(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
await Task.Run(() =>
|
|
{
|
|
//
|
|
var fileFullPath = GetFileFullPath(fileName);
|
|
if (!IsFileExists(fileFullPath))
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var thumbFileName = GenerateThumbName(fileName);
|
|
var thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
ThumbnailProvider.ResizeImage(
|
|
fileFullPath,
|
|
thumbFullPath,
|
|
Configuration.ThumbSize,
|
|
Configuration.ThumbQuality
|
|
);
|
|
}, cancellationToken);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create Thumbnail based on XFile model
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateThumbnail(
|
|
XFileDto file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await CreateThumbnail(
|
|
file.Name,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save and Create a Thumbnail For Profile Image
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileResult> HandleProfileImageSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateProfileImage(file);
|
|
|
|
//
|
|
var savedFileName = await SaveFileAsync(
|
|
file,
|
|
isTemp: false,
|
|
isWidget: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var thumbFileName = GenerateThumbName(savedFileName);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
var thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(
|
|
savedFileName,
|
|
cancellationToken
|
|
);
|
|
|
|
//
|
|
return new XFileResult
|
|
{
|
|
Name = file.Name,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToProfileImageUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToProfileImageUrl(thumbFullPath)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle File Upload with Support of Thumbnails ...
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileResult> HandleFileSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateFile(file);
|
|
|
|
//
|
|
var savedFileName = await SaveFileAsync(file, isTemp: false, isWidget: false);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
|
|
//
|
|
var thumbFileName = "";
|
|
var thumbFullPath = "";
|
|
var fileType = GetFileType(savedFileName);
|
|
if (fileType.IsImageKind())
|
|
{
|
|
//
|
|
thumbFileName = GenerateThumbName(savedFileName);
|
|
thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(savedFileName);
|
|
}
|
|
|
|
//
|
|
var result =
|
|
new XFileResult
|
|
{
|
|
Name = file.FileName,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToFileUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToFileUrl(thumbFullPath),
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle File Upload with Support of Thumbnails ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XFileResult>> HandleFilesSave(
|
|
IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateFiles(files);
|
|
|
|
//
|
|
var result = new Collection<XFileResult>();
|
|
foreach (var file in files)
|
|
{
|
|
//
|
|
var savedFileName = await SaveFileAsync(
|
|
file,
|
|
isTemp: false,
|
|
isWidget: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
|
|
//
|
|
var thumbFileName = "";
|
|
var thumbFullPath = "";
|
|
var fileType = GetFileType(savedFileName);
|
|
if (fileType.IsImageKind())
|
|
{
|
|
//
|
|
thumbFileName = GenerateThumbName(savedFileName);
|
|
thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(
|
|
savedFileName,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
result.Add(
|
|
new XFileResult
|
|
{
|
|
Name = file.FileName,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToFileUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToFileUrl(thumbFullPath),
|
|
});
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XThumbnailProvider.cs
|
|
|
|
using ImageMagick;
|
|
using xCommons.Extensions;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Providers {
|
|
public partial class XThumbnailProvider : IXThumbnailProvider {
|
|
public void SetTempFolder (string folder) {
|
|
MagickNET.SetTempDirectory (folder);
|
|
}
|
|
|
|
public XImageInfo GetImageInfo (string filePath) {
|
|
//
|
|
MagickImageInfo info = new MagickImageInfo (filePath);
|
|
return info.MapConvert<XImageInfo, MagickImageInfo> ();
|
|
}
|
|
|
|
public void ResizeImage (
|
|
string filePath,
|
|
string resizedFilePath,
|
|
int size,
|
|
int quality
|
|
) {
|
|
//
|
|
using (var image = new MagickImage (filePath)) {
|
|
//
|
|
image.Resize (size, size);
|
|
image.Strip ();
|
|
image.Quality = quality;
|
|
image.Write (resizedFilePath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Configurations\Entities\XStringEntityConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xStringService.Constants;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Configurations.Entities
|
|
{
|
|
public class XStringEntityConfiguration : XBaseEntityTypeConfiguration<XString, int>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XString> builder)
|
|
{
|
|
builder.ToTable(XStringServiceConstants.XStringTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Constants\XStringServiceConstants.cs
|
|
|
|
namespace xStringService.Constants
|
|
{
|
|
public struct XStringServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XStringServiceDILogTag = "XStringService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XStringTable = "Strings";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XStringSingleName = "string";
|
|
public const string XStringCollectionName = "strings";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XStringDtoHub = "stringDto";
|
|
public const string XStringEntityHub = "stringEntity";
|
|
|
|
//
|
|
// Custome Constants ...
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXStringEFRepositoryDescriptor = "GetXStringEFRepositoryDescriptor";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XBaseItemResourceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XBaseItemResourceProviderControllerBase : XBaseIdentityApiV1Controller, IXBaseItemResourceProviderController
|
|
{
|
|
private readonly IXItemResourceProvider provider;
|
|
|
|
protected XBaseItemResourceProviderControllerBase(
|
|
ILogger<XBaseItemResourceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXItemResourceProvider provider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="identifier">if null or empty, check all languages in Item Side</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
[FromQuery] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = Enumerable.Empty<string>();
|
|
if (!identifier.IsNull())
|
|
{
|
|
//
|
|
result = await provider.GetLanguages(
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await provider.GetLanguages(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceLocales")]
|
|
public virtual async Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
[FromQuery] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = Enumerable.Empty<XStringDto>();
|
|
if (!identifier.IsNull())
|
|
{
|
|
//
|
|
result = await provider.GetResourceLocales(
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await provider.GetResourceLocales(
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales/{identifier}")]
|
|
public virtual async Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
[FromRoute] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Language Locale of Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language">if null or empty Remove all Locales</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Locales/{identifier}")]
|
|
public virtual async Task<ActionResult<XResourceDto>> RemoveLocale(
|
|
[FromRoute] object identifier,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Connection ID ...
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
XResourceDto result = null;
|
|
if (!language.IsNullOrEmpty())
|
|
{
|
|
//
|
|
result = await provider.RemoveLocale(
|
|
language: language,
|
|
identifier: identifier,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
await provider.RemoveLocales(
|
|
identifier: identifier,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified ocale Exists for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales/{identifier}/{language}/Has")]
|
|
public virtual async Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] object identifier,
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(language)
|
|
.AddNotNull(identifier)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Calculate Result ...
|
|
var result = await provider.HasLocale(
|
|
language: language,
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Exists Locales Representaion based on Specified Identitifer
|
|
/// as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resource/{identifier}")]
|
|
public virtual async Task<ActionResult<XResourceDto>> GetResource(
|
|
[FromRoute] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
ValidationProvider.NotNull(identifier);
|
|
|
|
//
|
|
var result = await provider.GetResource(
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale for Specified Identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locales/{identifier}")]
|
|
public virtual async Task<ActionResult<XResourceDto>> AddOrUpdateLocale(
|
|
[FromRoute] object identifier,
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(identifier)
|
|
.AddNotNull(locale)
|
|
.AddNotEmpty(locale.Value)
|
|
.AddNotEmpty(locale.Language)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Retrieve Connection ID ...
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.AddOrUpdateLocale(
|
|
locale: locale,
|
|
identifier: identifier,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Resource State ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resource/{identifier}")]
|
|
public virtual async Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromRoute] object identifier,
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(identifier)
|
|
.AddNotNull(resource)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Retrieve Connection ID ...
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.AddOrUpdateResource(
|
|
resource: resource,
|
|
identifier: identifier,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XBaseResourceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XBaseResourceProviderControllerBase<TResourceProvider> : XBaseIdentityApiV1Controller, IXBaseResourceProviderController
|
|
where TResourceProvider : IXResourceProvider
|
|
{
|
|
private readonly TResourceProvider provider;
|
|
|
|
protected XBaseResourceProviderControllerBase(
|
|
ILogger<XBaseResourceProviderControllerBase<TResourceProvider>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
TResourceProvider provider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLanguages(cancellationToken);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("LocalesResource")]
|
|
public virtual async Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResourceLocales(cancellationToken);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract Translation of in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Translation")]
|
|
public virtual async Task<ActionResult<string>> GetResourceTranslation(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResourceTranslation(
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Has Specified Translation or not ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Has")]
|
|
public virtual async Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.HasLocale(
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Locale")]
|
|
public virtual async Task<ActionResult<XLocaleResourceDto>> GetLocale(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLocale(
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Locale Models ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales")]
|
|
public virtual async Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLocales(cancellationToken);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resource")]
|
|
public virtual async Task<ActionResult<XResourceDto>> GetResource(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResource(cancellationToken);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("")]
|
|
public virtual async Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.AddOrUpdateResource(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locales")]
|
|
public virtual async Task<ActionResult<XResourceDto>> AddOrUpdateLocale(
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.AddOrUpdateLocale(
|
|
locale: locale,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locale/Remove")]
|
|
public virtual async Task<ActionResult<XResourceDto>> RemoveLocale(
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.RemoveLocale(
|
|
locale: locale,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resource/Remove")]
|
|
public virtual async Task<ActionResult> RemoveResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await provider
|
|
.RemoveResource(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XStringProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xPushService.Controllers;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XStringProviderControllerBase : XBaseProvidedController<XString, XStringDto, int, XStringDtoHub>, IXStringProviderController
|
|
{
|
|
private readonly IXStringProvider provider;
|
|
|
|
protected XStringProviderControllerBase(
|
|
ILogger<XStringProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXStringProvider provider,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLanguages(cancellationToken);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of Resource Titles ...
|
|
/// </summary>
|
|
/// <param name="language">if provided, returns all language Specified resource titles, if not, all Resource Titles</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceTitles")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetResourceTitles(
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResourceTitles(
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items which belongs to Specified Resource Title ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceLocales")]
|
|
public virtual async Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResourceLocales(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract Translation of a Resource in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Translation")]
|
|
public virtual async Task<ActionResult<string>> GetResourceTranslation(
|
|
[FromQuery] string language,
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResourceTranslation(
|
|
language: language,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Resource as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locale")]
|
|
public virtual async Task<ActionResult<XLocaleResourceDto>> GetLocale(
|
|
[FromQuery] string language,
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLocale(
|
|
language: language,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Resource Instances as Locale Models ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales")]
|
|
public virtual async Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetLocales(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Locales of Specified Resource and Represent as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("GetResource")]
|
|
public virtual async Task<ActionResult<XResourceDto>> GetResource(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var result = await provider
|
|
.GetResource(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddOrUpdateResource")]
|
|
public virtual async Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(resource)
|
|
.AddNotEmpty(resource.Resource)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider
|
|
.AddOrUpdateResource(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("RemoveResource")]
|
|
public virtual async Task<ActionResult> RemoveResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(resource)
|
|
.AddNotEmpty(resource.Resource)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
await provider
|
|
.RemoveResource(
|
|
resource: resource,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XStringRepositoryControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XStringRepositoryControllerBase : XBaseRepositoryController<XString, int>, IXBaseRepositoryController<XString, int>
|
|
{
|
|
protected XStringRepositoryControllerBase(
|
|
ILogger<XStringRepositoryControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXStringRepository repository,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repository,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XStringRepositoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Entities;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XStringRepositoryProviderControllerBase : XBaseRepositoryProviderController<XString, int, XStringEntityHub>, IXBaseRepositoryProviderController<XString, int, XStringEntityHub>
|
|
{
|
|
protected XStringRepositoryProviderControllerBase(
|
|
ILogger<XStringRepositoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXStringRepositoryProvider provider,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XStringServiceControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XStringServiceControllerBase : XBaseServiceController<XString, XStringDto, int>, IXBaseServiceController<XString, XStringDto, int>
|
|
{
|
|
protected XStringServiceControllerBase(
|
|
ILogger<XStringServiceControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXStringRepositoryService repositoryService,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repositoryService,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Controllers\XStringServiceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Controllers
|
|
{
|
|
public abstract class XStringServiceProviderControllerBase : XBaseServiceProviderController<XString, XStringDto, int, XStringDtoHub>, IXBaseServiceProviderController<XString, XStringDto, int, XStringDtoHub>
|
|
{
|
|
protected XStringServiceProviderControllerBase(
|
|
ILogger<XStringServiceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXStringServiceProvider provider,
|
|
Func<IQueryable<XString>, IOrderedQueryable<XString>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XString>, IIncludableQueryable<XString, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xExceptions.Constants;
|
|
using xCommons.Extensions;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xStringService.Helpers;
|
|
using xCommons.Helpers;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers.Dtos;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Providers.Entities;
|
|
using xPushService.Helpers;
|
|
using xPushService.DI;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Providers;
|
|
using xStringService.Constants;
|
|
|
|
namespace xStringService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXStringService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddStringService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXStringService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddStringService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XStringService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXStringService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using XString Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
pushHelper.AddHub<XStringDtoHub>(XStringServiceConstants.XStringDtoHub);
|
|
pushHelper.AddHub<XStringEntityHub>(XStringServiceConstants.XStringEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XString Repository Descriptor ...
|
|
if (!descriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: descriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor descriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XStringServiceConstants.XStringServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddStringService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch(repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
descriptor = typeof(XStringServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XStringServiceConstants.GetXStringEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
descriptor = XStringServiceHelper.GetXStringMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
descriptor = XStringServiceHelper.GetXStringInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Register XString Repository Descriptor ...
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: descriptor
|
|
);
|
|
|
|
//
|
|
// Register Dto Services ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXStringServiceProvider), typeof(XStringServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXStringRepositoryService), typeof(XStringRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXStringRepositoryProvider), typeof(XStringRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// Register XString Provider ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXStringProvider), typeof(XStringProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Extensions\XModelExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Converts an Entity to LocaleResource Dto ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLocaleResourceDto ToXLocaleResourceDto(this XString source)
|
|
{
|
|
//
|
|
var result = new XLocaleResourceDto
|
|
{
|
|
Language = source.IsNull() ? "" : source.Language,
|
|
Value = source.IsNull() ? "" : source.TranslatedValue,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an Dto to LocaleResource Dto ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XLocaleResourceDto ToXLocaleResourceDto(this XStringDto source)
|
|
{
|
|
//
|
|
var result = new XLocaleResourceDto
|
|
{
|
|
Language = source.IsNull() ? "" : source.Language,
|
|
Value = source.IsNull() ? "" : source.TranslatedValue,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a Collection of Entities to Locale Resource Presentation ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<XLocaleResourceDto> ToXLocaleResourceDtos(this IEnumerable<XString> source)
|
|
{
|
|
//
|
|
var result = source.Select(e => ToXLocaleResourceDto(e));
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a Collection of Dtos to Locale Resource Presentation ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<XLocaleResourceDto> ToXLocaleResourceDtos(this IEnumerable<XStringDto> source)
|
|
{
|
|
//
|
|
var result = source.Select(e => ToXLocaleResourceDto(e));
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Helpers\XStringServiceHelper.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataHelper.Providers.GraphQL;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Entities;
|
|
using xStringService.Providers.GraphQL;
|
|
|
|
namespace xStringService.Helpers
|
|
{
|
|
public static class XStringServiceHelper
|
|
{
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringEFRepository<TContext>,
|
|
TContext
|
|
> GetXStringEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringEFRepository<TContext>,
|
|
TContext,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
> GetXStringEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XString, int>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringEFRepository<TContext>,
|
|
TContext,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringMongoRepository
|
|
> GetXStringMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringMongoRepository,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
> GetXStringMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XString, int>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringMongoRepository,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringInMemoryRepository
|
|
> GetXStringInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringInMemoryRepository,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
> GetXStringInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XString, int>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XString,
|
|
int,
|
|
IXStringKeyGenerator,
|
|
XStringKeyGenerator,
|
|
IXStringRepositoryEvents,
|
|
XStringRepositoryEvents,
|
|
XStringGraphType,
|
|
IntGraphType,
|
|
XStringGraphQuery,
|
|
IXStringGraphQLTypeHelper,
|
|
XStringGraphQLTypeHelper,
|
|
XStringGraphSchema,
|
|
IXStringRepository,
|
|
XStringInMemoryRepository,
|
|
IXStringSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Dtos\IXStringDtoHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Dtos
|
|
{
|
|
public interface IXStringDtoHub : IXBaseDtoHub<XString, XStringDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Dtos\IXStringRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Dtos
|
|
{
|
|
public interface IXStringRepositoryService : IXBaseRepositoryService<XString, XStringDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Dtos\IXStringServiceProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Configurations;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Interfaces.Dtos
|
|
{
|
|
public interface IXStringServiceProvider : IXBaseDtoProvider<XString, XStringDto, int, XStringDtoHub>
|
|
{
|
|
/// <summary>
|
|
/// Application Configuration ...
|
|
/// </summary>
|
|
XAppConfiguration AppConfiguration { get; }
|
|
|
|
//
|
|
#region Retrievers ...
|
|
/// <summary>
|
|
/// Retrieve all Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Specified Resource Exists or not ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> IsResourceExists(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XStringDto> Get(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Translation of Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<string> GetResourceValue(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve an Specified Resource Items ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> GetResources(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Resource Items as XResourceDto Presentation ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> GetResource(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Query ...
|
|
/// <summary>
|
|
/// Query Resource IDs ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<string>> QueryResourceIds(
|
|
XQuery query,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Query Specified Language Resources ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XStringDto>> QueryLanguageResources(
|
|
XQuery query,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Query Locale Resources ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XQueryResult<XLocaleResourceDto>> QueryLocaleResources(
|
|
XQuery query,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Add/Update Actions ...
|
|
/// <summary>
|
|
/// Add Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> Add(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> Update(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddOrUpdate(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Specified Locale Resource ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XStringDto> AddByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update Specified Locale Resource ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XStringDto> UpdateByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Resource By Locale ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XStringDto> AddOrUpdateByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update all XResourceDto(s) Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> AddByResource(
|
|
XResourceDto item,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Remove Actions ...
|
|
/// <summary>
|
|
/// Remove all Specified Language's Resources ...
|
|
/// </summary>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveLanguageResources(
|
|
string language,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove all Specified Resource Ids instances ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> RemoveResource(
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> Remove(
|
|
string resource,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove all Resource of Specified XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveByResource(
|
|
XResourceDto item,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringEntityHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringEntityHub : IXBaseEntityHub<XString, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringGraphQLTypeHelper.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XString, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringKeyGenerator.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringKeyGenerator : IXKeyGenerator<XString, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringRepository.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringRepository : IXBaseRepository<XString, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringRepositoryEvents : IXBaseRepositoryEvents<XString>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringRepositoryProvider.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringRepositoryProvider : IXBaseEntityProvider<XString, int, XStringEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\Entities\IXStringSeeder.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Interfaces.Entities
|
|
{
|
|
public interface IXStringSeeder : IXBaseDbSeeder<XString, int>
|
|
{}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXBaseItemResourceProviderController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXBaseItemResourceProviderController
|
|
{
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="identifier">if null or empty, check all languages in Item Side</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
[FromQuery] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceLocales")]
|
|
Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
[FromQuery] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales/{identifier}")]
|
|
Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
[FromRoute] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Language Locale of Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language">if null or empty Remove all Locales</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Locales/{identifier}")]
|
|
Task<ActionResult<XResourceDto>> RemoveLocale(
|
|
[FromRoute] object identifier,
|
|
[FromQuery] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Specified ocale Exists for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales/{identifier}/{language}/Has")]
|
|
Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] object identifier,
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get all Exists Locales Representaion based on Specified Identitifer
|
|
/// as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resource/{identifier}")]
|
|
Task<ActionResult<XResourceDto>> GetResource(
|
|
[FromRoute] object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale for Specified Identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locales/{identifier}")]
|
|
Task<ActionResult<XResourceDto>> AddOrUpdateLocale(
|
|
[FromRoute] object identifier,
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update a Resource State ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resource/{identifier}")]
|
|
Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromRoute] object identifier,
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXBaseResourceProviderController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXBaseResourceProviderController
|
|
{
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("LocalesResource")]
|
|
Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Extract Translation of in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Translation")]
|
|
Task<ActionResult<string>> GetResourceTranslation(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Has Specified Translation or not ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Has")]
|
|
Task<ActionResult<bool>> HasLocale(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{language}/Locale")]
|
|
Task<ActionResult<XLocaleResourceDto>> GetLocale(
|
|
[FromRoute] string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Locale Models ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales")]
|
|
Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Resource")]
|
|
Task<ActionResult<XResourceDto>> GetResource(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("")]
|
|
Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locales")]
|
|
Task<ActionResult<XResourceDto>> AddOrUpdateLocale(
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Locale/Remove")]
|
|
Task<ActionResult<XResourceDto>> RemoveLocale(
|
|
[FromBody] XLocaleResourceDto locale,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Resource/Remove")]
|
|
Task<ActionResult> RemoveResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXItemResourceProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXItemResourceProvider
|
|
{
|
|
//
|
|
#region Group Actions ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages for Current Item ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items of type ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove all Exists Locales which Related to this Provider ...
|
|
/// </summary>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveResourceLocales(
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Item Actions ...
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get all Exists Locales Representaion based on Specified Identitifer
|
|
/// as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> GetResource(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale for Specified Identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="locale"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> AddOrUpdateLocale(
|
|
object identifier,
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Update a Resource State ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> AddOrUpdateResource(
|
|
object identifier,
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Language Locale of Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> RemoveLocale(
|
|
object identifier,
|
|
string language,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove all Exists Locales for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveLocales(
|
|
object identifier,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Specified ocale Exists for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> HasLocale(
|
|
object identifier,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get all Exists Languages for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetLanguages(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Resource Title Action ...
|
|
/// <summary>
|
|
/// Retrieve Resource Title ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <returns></returns>
|
|
string GetResourceTitle(object identifier = null);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXResourceProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xModels.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXResourceProvider
|
|
{
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Extract Translation of in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<string> GetResourceTranslation(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check Has Specified Translation or not ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> HasLocale(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XLocaleResourceDto> GetLocale(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Locale Models ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> GetResource(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> AddOrUpdateResource(
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> AddOrUpdateLocale(
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> RemoveLocale(
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveResource(
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXStringProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXStringProvider : IXBaseProvided<XString, XStringDto, int, XStringDtoHub>
|
|
{
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of Resource Titles ...
|
|
/// </summary>
|
|
/// <param name="language">if provided, returns all language Specified resource titles, if not, all Resource Titles</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetResourceTitles(
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items which belongs to Specified Resource Title ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Extract Translation of a Resource in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<string> GetResourceTranslation(
|
|
string language,
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve a Resource as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XLocaleResourceDto> GetLocale(
|
|
string language,
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Resource Instances as Locale Models ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Locales of Specified Resource and Represent as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> GetResource(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="userInfo">Actor User for Permissions ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<XResourceDto> AddOrUpdateResource(
|
|
XResourceDto resource,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="userInfo">Actor User for Permissions ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task RemoveResource(
|
|
XResourceDto resource,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Interfaces\IXStringProviderController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xModels.Dtos;
|
|
using xPushService.Interfaces;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Interfaces
|
|
{
|
|
public interface IXStringProviderController : IXBaseProvidedController<XString, XStringDto, int, XStringDtoHub>
|
|
{
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Languages")]
|
|
Task<ActionResult<IEnumerable<string>>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of Resource Titles ...
|
|
/// </summary>
|
|
/// <param name="language">if provided, returns all language Specified resource titles, if not, all Resource Titles</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceTitles")]
|
|
Task<ActionResult<IEnumerable<string>>> GetResourceTitles(
|
|
[FromQuery] string language = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items which belongs to Specified Resource Title ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("ResourceLocales")]
|
|
Task<ActionResult<IEnumerable<XStringDto>>> GetResourceLocales(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Extract Translation of a Resource in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Translation")]
|
|
Task<ActionResult<string>> GetResourceTranslation(
|
|
[FromQuery] string language,
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve a Resource as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locale")]
|
|
Task<ActionResult<XLocaleResourceDto>> GetLocale(
|
|
[FromQuery] string language,
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Resource Instances as Locale Models ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Locales")]
|
|
Task<ActionResult<IEnumerable<XLocaleResourceDto>>> GetLocales(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Retrieve all Locales of Specified Resource and Represent as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("GetResource")]
|
|
Task<ActionResult<XResourceDto>> GetResource(
|
|
[FromQuery] string resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("AddOrUpdateResource")]
|
|
Task<ActionResult<XResourceDto>> AddOrUpdateResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("RemoveResource")]
|
|
Task<ActionResult> RemoveResource(
|
|
[FromBody] XResourceDto resource,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Models\Dtos\XStringDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xStringService.Models.Dtos
|
|
{
|
|
public class XStringDto : XBaseIntIDEntityDto
|
|
{
|
|
public string Language { get; set; }
|
|
public string ResourceTitle { get; set; }
|
|
public string TranslatedValue { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Models\Entities\XString.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
|
|
namespace xStringService.Models.Entities
|
|
{
|
|
public class XString : XBaseIntIDEntity
|
|
{
|
|
[Required]
|
|
[StringLength (10)]
|
|
public string Language { get; set; }
|
|
|
|
[Required]
|
|
[StringLength (255)]
|
|
public string ResourceTitle { get; set; }
|
|
|
|
[Required]
|
|
public string TranslatedValue { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Dtos\XStringDtoHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Dtos
|
|
{
|
|
public class XStringDtoHub : XBaseDtoHub<XString, XStringDto, int>, IXStringDtoHub
|
|
{
|
|
public XStringDtoHub(
|
|
ILogger<XStringDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Dtos\XStringRepositoryService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Dtos
|
|
{
|
|
public class XStringRepositoryService : XBaseRepositoryService<XString, XStringDto, int>, IXStringRepositoryService
|
|
{
|
|
public XStringRepositoryService(
|
|
IXStringRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Dtos\XStringServiceProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Constants;
|
|
using xStringService.Extensions;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Dtos
|
|
{
|
|
public class XStringServiceProvider : XBaseDtoProvider<XString, XStringDto, int, XStringDtoHub>, IXStringServiceProvider
|
|
{
|
|
public XAppConfiguration AppConfiguration { get; }
|
|
|
|
public XStringServiceProvider(
|
|
IHubContext<XStringDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXStringRepositoryService service,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{
|
|
AppConfiguration = appConfiguration;
|
|
}
|
|
|
|
//
|
|
#region Retrievers ...
|
|
/// <summary>
|
|
/// Retrieve all Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await Service.GetAllAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Language)
|
|
))
|
|
.AsQueryable()
|
|
.Select(e => e.Language)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
// Check Configuration Default Language Exists ...
|
|
var hasDefaultLanguage = !AppConfiguration.DefaultLanguage.IsNullOrEmpty();
|
|
if (hasDefaultLanguage)
|
|
{
|
|
//
|
|
// Find Default Language on Result ...
|
|
hasDefaultLanguage = result.Any(e => e.ToNormalString() == AppConfiguration.DefaultLanguage.ToNormalString());
|
|
if (!hasDefaultLanguage)
|
|
{
|
|
result.Add(AppConfiguration.DefaultLanguage);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = result
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified Resource Exists or not ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsResourceExists(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = !resource.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XStringDto dto = null;
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
//
|
|
dto = await Service
|
|
.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: e => e.ResourceTitle == resource
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
dto = await Service
|
|
.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate:
|
|
e => e.ResourceTitle == resource &&
|
|
e.Language.ToNormalString() == language.ToNormalString()
|
|
);
|
|
}
|
|
|
|
//
|
|
result = !dto.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XStringDto> Get(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
if (resource.IsNullOrEmpty() || language.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Resource Exists ...
|
|
var isExists = await IsResourceExists(
|
|
resource: resource,
|
|
language: language
|
|
);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Service
|
|
.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: e =>
|
|
e.ResourceTitle == resource &&
|
|
e.Language.ToNormalString() == language.ToNormalString()
|
|
);
|
|
if (result.IsNullOrDefault())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Translation of Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetResourceValue(
|
|
string resource,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = "";
|
|
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!resource.IsNullOrEmpty() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Langauage Exists ...
|
|
var languages = await GetLanguages(cancellationToken);
|
|
isValid = languages.Any(l => l.ToNormalString() == language.ToNormalString());
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Resource Exists ...
|
|
isValid = await IsResourceExists(
|
|
resource: resource,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var dto = await Service.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: e =>
|
|
e.ResourceTitle == resource &&
|
|
e.Language.ToNormalString() == language.ToNormalString()
|
|
);
|
|
isValid = !dto.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
result = dto.TranslatedValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve an Specified Resource Items ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XStringDto>> GetResources(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = await IsResourceExists(resource);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Service
|
|
.FindManyAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
predicate: e =>
|
|
e.ResourceTitle == resource,
|
|
orderBuilder: x =>
|
|
x.OrderBy(y => y.ResourceTitle),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Resource Items as XResourceDto Presentation ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XResourceDto> GetResource(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isExists = await IsResourceExists(
|
|
language: null,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve String Dto (s) ...
|
|
var resources = await GetResources(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!resource.HasChild())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new XResourceDto
|
|
{
|
|
Resource = resource,
|
|
Locales = resources.ToXLocaleResourceDtos()
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Query ...
|
|
/// <summary>
|
|
/// Query Resource IDs ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<string>> QueryResourceIds(
|
|
XQuery query,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var dtoResult = await Service.QueryAsync(
|
|
query: query,
|
|
predicate: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: x =>
|
|
x.OrderBy(y => y.ResourceTitle),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var result = new XQueryResult<string>()
|
|
.UpdateData(
|
|
updateWith: dtoResult,
|
|
propertyBlackList: new List<string>
|
|
{
|
|
nameof(XQueryResult<string>.Items)
|
|
});
|
|
|
|
//
|
|
result.Items = dtoResult.Items.ToList().Select(dto => dto.ResourceTitle);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified Language Resources ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XStringDto>> QueryLanguageResources(
|
|
XQuery query,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await Service.QueryAsync(
|
|
query: query,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: x => x
|
|
.OrderBy(y => y.Language)
|
|
.ThenBy(y => y.ResourceTitle),
|
|
cancellationToken: cancellationToken,
|
|
predicate: x =>
|
|
x.Language.ToNormalString() == language.ToNormalString()
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Locale Resources ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XLocaleResourceDto>> QueryLocaleResources(
|
|
XQuery query,
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
Expression<Func<XString, bool>> predicate = null;
|
|
if (!language.IsNullOrEmpty())
|
|
{
|
|
//
|
|
predicate = x =>
|
|
x.Language.ToNormalString() == language.ToNormalString();
|
|
}
|
|
|
|
//
|
|
var dtoResult = await Service.QueryAsync(
|
|
query: query,
|
|
includeBuilder: null,
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: x => x
|
|
.OrderBy(y => y.Language)
|
|
.ThenBy(y => y.ResourceTitle),
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var result = new XQueryResult<XLocaleResourceDto>()
|
|
.UpdateData(
|
|
updateWith: dtoResult,
|
|
propertyBlackList: new List<string>
|
|
{
|
|
nameof(XQueryResult<XLocaleResourceDto>.Items)
|
|
});
|
|
|
|
//
|
|
result.Items = dtoResult.Items.ToList().ToXLocaleResourceDtos();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Add/Update Actions ...
|
|
/// <summary>
|
|
/// Add Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> Add(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!value.IsNullOrEmpty() &&
|
|
!resource.IsNullOrEmpty() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Exists ...
|
|
bool isExists = await IsResourceExists(
|
|
resource: resource,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !isExists;
|
|
if (!result)
|
|
{
|
|
XException.Duplicate.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Entity to Add ...
|
|
XStringDto item = new XStringDto
|
|
{
|
|
Language = language,
|
|
TranslatedValue = value,
|
|
ResourceTitle = resource,
|
|
};
|
|
item = await AddAsync(
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !item.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> Update(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!value.IsNullOrEmpty() &&
|
|
!language.IsNullOrEmpty() &&
|
|
!resource.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Value Must Exists ...
|
|
result = await IsResourceExists(
|
|
resource: resource,
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await Get(
|
|
language: language,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
item.TranslatedValue = value;
|
|
item = await UpdateAsync(
|
|
item: item,
|
|
id: item.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !item.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddOrUpdate(
|
|
string resource,
|
|
string value,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Check Existsance ...
|
|
bool isExists = await IsResourceExists(
|
|
resource: resource,
|
|
language: language
|
|
);
|
|
|
|
//
|
|
// Act Based on Existance ...
|
|
if (isExists)
|
|
{
|
|
//
|
|
result = await Update(
|
|
value: value,
|
|
resource: resource,
|
|
language: language,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await Add(
|
|
value: value,
|
|
resource: resource,
|
|
language: language,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Specified Locale Resource ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XStringDto> AddByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.IsNull() &&
|
|
!resource.IsNullOrEmpty() &&
|
|
!item.Value.IsNullOrEmpty() &&
|
|
!item.Language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Specified Resource / Language Exists ...
|
|
isValid = await IsResourceExists(
|
|
resource: resource,
|
|
language: item.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (isValid)
|
|
{
|
|
XException.Duplicate.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Item to Add ...
|
|
var result = new XStringDto
|
|
{
|
|
Language = item.Language,
|
|
ResourceTitle = resource,
|
|
TranslatedValue = item.Value
|
|
};
|
|
result = await AddAsync(
|
|
item: result,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update Specified Locale Resource ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XStringDto> UpdateByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.IsNull() &&
|
|
!resource.IsNullOrEmpty() &&
|
|
!item.Value.IsNullOrEmpty() &&
|
|
!item.Language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Specified Resource / Language Exists ...
|
|
isValid = await IsResourceExists(
|
|
resource: resource,
|
|
language: item.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Get(
|
|
resource: resource,
|
|
language: item.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !result.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Update ...
|
|
result.TranslatedValue = item.Value;
|
|
result = await UpdateAsync(
|
|
item: result,
|
|
id: result.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !result.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Resource By Locale ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XStringDto> AddOrUpdateByLocaleResource(
|
|
XLocaleResourceDto item,
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.IsNull() &&
|
|
!resource.IsNullOrEmpty() &&
|
|
!item.Value.IsNullOrEmpty() &&
|
|
!item.Language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Specified Resource / Language Exists ...
|
|
isValid = await IsResourceExists(
|
|
resource: resource,
|
|
language: item.Language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
XStringDto result = null;
|
|
if (!isValid)
|
|
{
|
|
//
|
|
result = await AddByLocaleResource(
|
|
item: item,
|
|
resource: resource,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await UpdateByLocaleResource(
|
|
item: item,
|
|
resource: resource,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
if (result.IsNullOrDefault())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update all XResourceDto(s) Locales ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XStringDto>> AddByResource(
|
|
XResourceDto item,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.IsNull() &&
|
|
item.Locales.HasChild() &&
|
|
!item.Resource.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Task
|
|
.WhenAll(item.Locales
|
|
.Select(async e => await AddOrUpdateByLocaleResource(
|
|
item: e,
|
|
resource: item.Resource,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken)));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Remove Actions ...
|
|
/// <summary>
|
|
/// Remove all Specified Language's Resources ...
|
|
/// </summary>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveLanguageResources(
|
|
string language,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid = !language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var dtos = await Service
|
|
.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: e =>
|
|
e.Language.ToNormalString() == language.ToNormalString());
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await Service.RemoveRangeAsync(
|
|
items: dtos,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var ids = dtos.Select(e => e.Id);
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
payLoad: ids.ToJSON(camelCase: true),
|
|
cancellationToken: cancellationToken,
|
|
action: XBaseEntityHubAction.DeleteMany.GetStringValue()
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove all Specified Resource Ids instances ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XStringDto>> RemoveResource(
|
|
string resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid = !resource.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await Service
|
|
.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: e =>
|
|
e.ResourceTitle.ToNormalString() == resource.ToNormalString());
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await Service.RemoveRangeAsync(
|
|
items: result,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var ids = result.Select(e => e.Id);
|
|
await SendPush(
|
|
connectionId: connectionId,
|
|
payLoad: ids.ToJSON(camelCase: true),
|
|
cancellationToken: cancellationToken,
|
|
action: XBaseEntityHubAction.DeleteMany.GetStringValue()
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> Remove(
|
|
string resource,
|
|
string language = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
if (language.IsNullOrEmpty())
|
|
{
|
|
language = AppConfiguration.DefaultLanguage;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!language.IsNullOrEmpty() &&
|
|
!resource.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Resource Exists ...
|
|
result = await IsResourceExists(
|
|
language: language,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var dto = await Get(
|
|
language: language,
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !dto.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
dto = await RemoveAsync(
|
|
id: dto.Id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !dto.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove all Resource of Specified XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveByResource(
|
|
XResourceDto item,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
bool isValid =
|
|
!item.IsNullOrDefault() &&
|
|
item.Locales.HasChild() &&
|
|
!item.Resource.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
foreach (var locale in item.Locales)
|
|
{
|
|
//
|
|
await Remove(
|
|
resource: item.Resource,
|
|
language: locale.Language,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringEFRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringEFRepository<TContext> : XBaseEFRepository<XString, int, TContext>, IXStringRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XStringEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXStringKeyGenerator keyGenerator = null,
|
|
IXStringRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringEntityHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringEntityHub : XBaseEntityHub<XString, int>, IXStringEntityHub
|
|
{
|
|
public XStringEntityHub(
|
|
ILogger<XStringEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringInMemoryRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringInMemoryRepository : XBaseInMemoryRepository<XString, int>, IXStringRepository
|
|
{
|
|
public XStringInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXStringKeyGenerator keyGenerator = null,
|
|
IXStringRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringKeyGenerator : XIntKeyGenerator<XString>, IXStringKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringMongoRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringMongoRepository : XBaseMongoRepository<XString, int>, IXStringRepository
|
|
{
|
|
public XStringMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXStringKeyGenerator keyGenerator = null,
|
|
IXStringRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringRepositoryEvents : XBaseRepositoryEvents<XString>, IXStringRepositoryEvents
|
|
{}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringRepositoryProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public class XStringRepositoryProvider : XBaseEntityProvider<XString, int, XStringEntityHub>, IXStringRepositoryProvider
|
|
{
|
|
public XStringRepositoryProvider(
|
|
IHubContext<XStringEntityHub> hub,
|
|
IXStringRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\Entities\XStringSeederBase.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.Entities
|
|
{
|
|
public abstract class XStringSeederBase : XBaseDbSeeder<XString, int>, IXStringSeeder
|
|
{
|
|
protected XStringSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXStringRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\GraphQL\XStringGraphQLTypeHelper.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xStringService.Constants;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers.GraphQL
|
|
{
|
|
public class XStringGraphQLTypeHelper : XBaseGraphQLTypeHelper<XString, int>, IXStringGraphQLTypeHelper
|
|
{
|
|
public XStringGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XStringServiceConstants.XStringCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XStringServiceConstants.XStringSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\GraphQL\XStringGraphQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xStringService.Interfaces.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xDataHelper.Providers.GraphQL
|
|
{
|
|
public class XStringGraphQuery : XBaseGraphQLQuery<XString, int, XStringGraphType, IntGraphType>
|
|
{
|
|
public XStringGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXStringRepository repository,
|
|
IXStringGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\GraphQL\XStringGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xDataHelper.Providers.GraphQL
|
|
{
|
|
public class XStringGraphSchema : Schema
|
|
{
|
|
public XStringGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XStringGraphQuery)services.GetService(typeof(XStringGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\GraphQL\XStringGraphType.cs
|
|
|
|
using xDataService.GraphQL;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xDataHelper.Providers.GraphQL
|
|
{
|
|
public class XStringGraphType : XBaseGraphObjectType<XString, int>
|
|
{
|
|
public XStringGraphType() : base()
|
|
{
|
|
Field(x => x.Language);
|
|
Field(x => x.ResourceTitle);
|
|
Field(x => x.TranslatedValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\XBaseItemResourceProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Providers
|
|
{
|
|
public abstract class XBaseItemResourceProvider : IXItemResourceProvider
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Item Name for Resource Providing ...
|
|
/// </summary>
|
|
private readonly string item;
|
|
|
|
/// <summary>
|
|
/// an Implementation of Item Resource Provider
|
|
/// </summary>
|
|
/// <value></value>
|
|
private readonly XBaseResourceProvider provider;
|
|
|
|
/// <summary>
|
|
/// String Provider Service ...
|
|
/// </summary>
|
|
private readonly IXStringServiceProvider stringProvider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
protected XBaseItemResourceProvider(
|
|
string item,
|
|
IXStringServiceProvider stringProvider
|
|
)
|
|
{
|
|
//
|
|
this.item = item;
|
|
this.stringProvider = stringProvider;
|
|
provider = new XBaseResourceProvider(
|
|
item,
|
|
stringProvider
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Group Actions ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages for Current Item ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await ExtractItems(cancellationToken))
|
|
.Select(x => x.Language)
|
|
.Distinct();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items of type ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await ExtractItems(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove all Exists Locales which Related to this Provider ...
|
|
/// </summary>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task RemoveResourceLocales(
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isDelete = false;
|
|
XStringDto deleted = null;
|
|
var items = await ExtractItems(cancellationToken);
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
// Check Cancellation ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Remove Item ...
|
|
deleted = await stringProvider.RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Removation Succeed ...
|
|
isDelete = !deleted.IsNullOrDefault();
|
|
if (!isDelete)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Item Actions ...
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
// Retrieve Resource List ...
|
|
var result = await provider
|
|
.GetResourceLocales(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Exists Items for Specified identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
// Retrieve Resource List ...
|
|
var result = await provider
|
|
.GetLocales(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Exists Locales Representaion based on Specified Identitifer
|
|
/// as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> GetResource(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
// Retrieve Resource List ...
|
|
var result = await provider
|
|
.GetResource(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale for Specified Identitifer ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="locale"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> AddOrUpdateLocale(
|
|
object identifier,
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!identifier.IsNull() &&
|
|
!locale.IsNullOrDefault() &&
|
|
!locale.Value.IsNullOrEmpty() &&
|
|
!locale.Language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
// Retrieve Resource List ...
|
|
var result = await provider
|
|
.AddOrUpdateLocale(
|
|
locale: locale,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Resource State ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="resource"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> AddOrUpdateResource(
|
|
object identifier,
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Identified Resource Title ...
|
|
var identifiedResource = GetResourceTitle(identifier);
|
|
isValid =
|
|
!resource.IsNullOrDefault() &&
|
|
(resource.Resource.IsNullOrEmpty() ||
|
|
resource.Resource == identifiedResource);
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
if (resource.Resource.IsNullOrEmpty())
|
|
{
|
|
resource.Resource = identifiedResource;
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
// Retrieve Resource List ...
|
|
var result = await provider
|
|
.AddOrUpdateResource(
|
|
resource: resource,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Language Locale of Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> RemoveLocale(
|
|
object identifier,
|
|
string language,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!identifier.IsNull() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Locale Exists ...
|
|
isValid = await HasLocale(
|
|
language: language,
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var locale = (await GetLocales(
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
))
|
|
.FirstOrDefault(x =>
|
|
x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase));
|
|
isValid = !locale.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
var result = await provider.RemoveLocale(
|
|
locale: locale,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove all Exists Locales for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task RemoveLocales(
|
|
object identifier,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var resource = await GetResource(
|
|
identifier: identifier,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid = !resource.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
await provider.RemoveResource(
|
|
resource: resource,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified ocale Exists for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="language"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> HasLocale(
|
|
object identifier,
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!identifier.IsNull() &&
|
|
!language.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
var result = await provider.HasLocale(
|
|
language: language,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Exists Languages for Specified Identifier ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<string>> GetLanguages(
|
|
object identifier,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !identifier.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Setting Resource Title ...
|
|
SetResourceTitle(identifier);
|
|
|
|
//
|
|
var result = await provider
|
|
.GetLanguages(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Resource Title Action ...
|
|
/// <summary>
|
|
/// Retrieve Resource Title ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
/// <returns></returns>
|
|
public string GetResourceTitle(object identifier = null)
|
|
{
|
|
//
|
|
var result = item;
|
|
|
|
//
|
|
if (!identifier.IsNull())
|
|
{
|
|
result = $"{item}_{identifier}";
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Set Resource Title ...
|
|
/// </summary>
|
|
/// <param name="identifier"></param>
|
|
private void SetResourceTitle(object identifier = null)
|
|
{
|
|
//
|
|
var itemIdentifier = GetResourceTitle(identifier);
|
|
provider.SetField(
|
|
field: "resource",
|
|
value: $"{itemIdentifier}"
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// xtract all Items which Belongs to Provider ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
private async Task<IEnumerable<XStringDto>> ExtractItems(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await stringProvider
|
|
.FindManyAsync(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Id),
|
|
predicate: x =>
|
|
x.ResourceTitle.StartsWith(
|
|
item,
|
|
StringComparison.InvariantCultureIgnoreCase)
|
|
);
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\XBaseResourceProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
using xStringService.Extensions;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xStringService.Providers
|
|
{
|
|
public class XBaseResourceProvider : IXResourceProvider
|
|
{
|
|
protected string resource;
|
|
private readonly IXStringServiceProvider provider;
|
|
|
|
public XBaseResourceProvider(
|
|
string resource,
|
|
IXStringServiceProvider provider
|
|
)
|
|
{
|
|
this.resource = resource;
|
|
this.provider = provider;
|
|
}
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await ExtractItems(cancellationToken))
|
|
.Select(x => x.Language)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await ExtractItems(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract Translation of in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<string> GetResourceTranslation(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = (await ExtractItems(cancellationToken))
|
|
.FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
var result = item?.TranslatedValue ?? string.Empty;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Has Specified Translation or not ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> HasLocale(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = (await ExtractItems(cancellationToken))
|
|
.FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
var result = !item.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XLocaleResourceDto> GetLocale(
|
|
string language,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = (await ExtractItems(cancellationToken))
|
|
.FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
//
|
|
var result =
|
|
!item.IsNullOrDefault()
|
|
? item.ToXLocaleResourceDto()
|
|
: null;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Locale Models ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await ExtractItems(cancellationToken))
|
|
.Select(x => x.ToXLocaleResourceDto())
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> GetResource(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var locales = await GetLocales();
|
|
|
|
//
|
|
var result = new XResourceDto
|
|
{
|
|
Locales = locales,
|
|
Resource = resource,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> AddOrUpdateResource(
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var isValid =
|
|
!resource.IsNullOrDefault() &&
|
|
resource.Resource == this.resource;
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Exists Resource ...
|
|
var result = await GetResource(cancellationToken);
|
|
isValid = !result.IsNullOrDefault() && result.Locales.HasChild();
|
|
if (isValid)
|
|
{
|
|
await RemoveResource(
|
|
resource: result,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
foreach (var locale in resource.Locales)
|
|
{
|
|
//
|
|
var item = new XStringDto
|
|
{
|
|
Language = locale.Language,
|
|
ResourceTitle = this.resource,
|
|
TranslatedValue = locale.Value,
|
|
};
|
|
|
|
//
|
|
await provider.AddAsync(
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
result = await GetResource(cancellationToken);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Or Update Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> AddOrUpdateLocale(
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = (await ExtractItems(cancellationToken))
|
|
.FirstOrDefault(x =>
|
|
x.ResourceTitle == resource &&
|
|
x.Language == locale.Language);
|
|
var isExists = !item.IsNullOrDefault();
|
|
if (isExists)
|
|
{
|
|
item.TranslatedValue = locale.Value;
|
|
item = await provider.UpdateAsync(
|
|
item: item,
|
|
id: item.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
item = new XStringDto
|
|
{
|
|
ResourceTitle = resource,
|
|
Language = locale.Language,
|
|
TranslatedValue = locale.Value
|
|
};
|
|
item = await provider.AddAsync(
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
var result = await GetResource(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Locale ...
|
|
/// </summary>
|
|
/// <param name="locale"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XResourceDto> RemoveLocale(
|
|
XLocaleResourceDto locale,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var item = (await ExtractItems(cancellationToken))
|
|
.FirstOrDefault(x =>
|
|
x.ResourceTitle == resource &&
|
|
x.Language == locale.Language);
|
|
var isExists = !item.IsNullOrDefault();
|
|
if (isExists)
|
|
{
|
|
await provider.RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
var result = await GetResource(cancellationToken);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task RemoveResource(
|
|
XResourceDto resource,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Resource ...
|
|
var isValid =
|
|
!resource.IsNullOrDefault() &&
|
|
!resource.Resource.IsNullOrEmpty() &&
|
|
resource.Resource == this.resource;
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var items = await ExtractItems(cancellationToken);
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
await provider.RemoveAsync(
|
|
id: item.Id,
|
|
softDelete: false,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private async Task<IEnumerable<XStringDto>> ExtractItems(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.FindManyAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: x => x
|
|
.OrderBy(y => y.Language)
|
|
.ThenBy(y => y.ResourceTitle),
|
|
cancellationToken: cancellationToken,
|
|
predicate: x =>
|
|
x.ResourceTitle.Equals(resource, StringComparison.InvariantCultureIgnoreCase)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\XStringEntityRegisterar.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xStringService.Configurations.Entities;
|
|
using xStringService.Models.Entities;
|
|
|
|
namespace xStringService.Providers
|
|
{
|
|
/// <summary>
|
|
/// an Entity Registerar class for XStringService ...
|
|
/// </summary>
|
|
public class XStringEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XStringEntityRegisterar()
|
|
: base(nameof(XStringEntityRegisterar))
|
|
{
|
|
//
|
|
// Add XString Entity ...
|
|
AddEntity<XString, int>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XStringEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStringService\Providers\XStringProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using xPushService.Providers;
|
|
using xStringService.Extensions;
|
|
using xStringService.Interfaces;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Models.Dtos;
|
|
using xStringService.Models.Entities;
|
|
using xStringService.Providers.Dtos;
|
|
|
|
namespace xStringService.Providers
|
|
{
|
|
public class XStringProvider : XBaseProvided<XString, XStringDto, int, XStringDtoHub>, IXStringProvider
|
|
{
|
|
public XStringProvider(
|
|
IXStringServiceProvider provider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{ }
|
|
|
|
public override bool IsOwned(
|
|
XStringDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XString item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Retrieve a List of Exists Languages ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<string>> GetLanguages(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await GetAll(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Language)
|
|
))
|
|
.Select(x => x.Language)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of Resource Titles ...
|
|
/// </summary>
|
|
/// <param name="language">if provided, returns all language Specified resource titles, if not, all Resource Titles</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<string>> GetResourceTitles(
|
|
string language = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await FindMany(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.ResourceTitle),
|
|
predicate: x =>
|
|
string.IsNullOrWhiteSpace(language) ||
|
|
x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase)
|
|
))
|
|
.Select(x => x.ResourceTitle)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Items which belongs to Specified Resource Title ...
|
|
/// </summary>
|
|
/// <param name="resource">Specified Resource Title</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XStringDto>> GetResourceLocales(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await FindMany(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Language),
|
|
predicate: x =>
|
|
!string.IsNullOrWhiteSpace(resource) &&
|
|
resource.Equals(x.ResourceTitle, System.StringComparison.InvariantCultureIgnoreCase)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract Translation of a Resource in Specified Language ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetResourceTranslation(
|
|
string language,
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await FindOne(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x =>
|
|
!string.IsNullOrWhiteSpace(language) &&
|
|
!string.IsNullOrWhiteSpace(resource) &&
|
|
x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase) &&
|
|
x.ResourceTitle.Equals(resource, System.StringComparison.InvariantCultureIgnoreCase)
|
|
))?
|
|
.TranslatedValue ?? "";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Resource as Locale Model ...
|
|
/// </summary>
|
|
/// <param name="language">Specified Language ...</param>
|
|
/// <param name="resource">Specified Resource Title ...</param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XLocaleResourceDto> GetLocale(
|
|
string language,
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await FindOne(
|
|
includeBuilder: null,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x =>
|
|
!string.IsNullOrWhiteSpace(language) &&
|
|
!string.IsNullOrWhiteSpace(resource) &&
|
|
x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase) &&
|
|
x.ResourceTitle.Equals(resource, System.StringComparison.InvariantCultureIgnoreCase)
|
|
))?
|
|
.ToXLocaleResourceDto() ?? null;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Resource Instances as Locale Models ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XLocaleResourceDto>> GetLocales(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = (await GetResourceLocales(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
))
|
|
.ToList()
|
|
.Select(x => x.ToXLocaleResourceDto())
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Locales of Specified Resource and Represent as XResourceDto ...
|
|
/// </summary>
|
|
/// <param name="resource"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XResourceDto> GetResource(
|
|
string resource,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
XResourceDto result = null;
|
|
|
|
//
|
|
// Validate Resource ...
|
|
if (resource.IsNullOrEmpty())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Locales of Resource ...
|
|
var locales = await GetLocales(
|
|
resource: resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Prepare Result ...
|
|
result = new XResourceDto
|
|
{
|
|
Locales = locales,
|
|
Resource = resource,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add or Update a Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="userInfo">Actor User for Permissions ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XResourceDto> AddOrUpdateResource(
|
|
XResourceDto resource,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
XResourceDto result = null;
|
|
|
|
//
|
|
// Validate Args ...
|
|
var isValid =
|
|
!resource.IsNullOrDefault() &&
|
|
!resource.Resource.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Permissions ...
|
|
isValid =
|
|
userInfo.IsNullOrDefault() ||
|
|
HasPermision(userInfo);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
// Remove all Resources if Exists ...
|
|
result = await GetResource(
|
|
resource: resource.Resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var isExists = !result.IsNullOrDefault();
|
|
if (isExists)
|
|
{
|
|
//
|
|
await RemoveResource(
|
|
resource: result,
|
|
userInfo: userInfo,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Loop through all Exists Locales and Add them ...
|
|
foreach (var locale in resource.Locales)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
var item = new XStringDto
|
|
{
|
|
Language = locale.Language,
|
|
TranslatedValue = locale.Value,
|
|
ResourceTitle = resource.Resource,
|
|
};
|
|
await Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Reload Result after Updates ...
|
|
result = await GetResource(
|
|
resource: resource.Resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Resource Model ...
|
|
/// </summary>
|
|
/// <param name="resource">a XResourceDto Model ...</param>
|
|
/// <param name="userInfo">Actor User for Permissions ...</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task RemoveResource(
|
|
XResourceDto resource,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !resource.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var items = await GetResourceLocales(
|
|
resource: resource.Resource,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!items.IsNullOrDefault() &&
|
|
items.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
await Remove(
|
|
id: item.Id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Configurations\Entities\XTagEntityConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Configurations.Entities
|
|
{
|
|
public class XTagEntityConfiguration : XBaseEntityTypeConfiguration<XTag, int>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XTag> builder)
|
|
{
|
|
builder.ToTable("Tags");
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Constants\XTagServiceConstants.cs
|
|
|
|
namespace xTagService.Constants
|
|
{
|
|
public struct XTagServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XTagServiceDILogTag = "XTagService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XTagTable = "Tags";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XTagSingleName = "tag";
|
|
public const string XTagCollectionName = "tags";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XTagDtoHub = "tagDto";
|
|
public const string XTagEntityHub = "tagEntity";
|
|
|
|
//
|
|
// Custome Constants ...
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXTagEFRepositoryDescriptor = "GetXTagEFRepositoryDescriptor";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XBaseProvidedHasTagControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
[AllowAnonymous]
|
|
public abstract class XBaseProvidedHasTagControllerBase<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseProvidedHasTagController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
private readonly IXBaseProvided<TEntity, TDto, TKey, THub> provider;
|
|
private readonly IXTagProvided<TEntity, TDto, TKey, THub> tagProvided;
|
|
private readonly Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder;
|
|
private readonly Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder;
|
|
|
|
protected XBaseProvidedHasTagControllerBase(
|
|
ILogger<XBaseProvidedHasTagControllerBase<TEntity, TDto, TKey, THub>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXBaseProvided<TEntity, TDto, TKey, THub> provider,
|
|
IXTagProvided<TEntity, TDto, TKey, THub> tagProvided,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.tagProvided = tagProvided;
|
|
this.defaultOrderBuilder = defaultOrderBuilder;
|
|
this.defaultIncludeBuilder = defaultIncludeBuilder;
|
|
}
|
|
|
|
//
|
|
#region Provided ...
|
|
//
|
|
#region Retrieve ...
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Get(
|
|
[FromRoute] TKey id,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
ValidationProvider.NotNull(id);
|
|
|
|
//
|
|
var result = await provider.Get(
|
|
id: id,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> GetAll(
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.GetAll(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/One")]
|
|
public virtual async Task<ActionResult<TDto>> FindOne(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindOne(
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find a collection of Items by proving a Query Search ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Find/Many")]
|
|
public virtual async Task<ActionResult<IEnumerable<TDto>>> FindMany(
|
|
[FromRoute] string query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.FindMany(
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.PropValuesContains(query)
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> Query(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await provider.Query(
|
|
query: query,
|
|
predicate: null,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="useDefaultOrders"></param>
|
|
/// <param name="useDefaultIncludes"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("Query/Owned")]
|
|
public virtual async Task<ActionResult<XQueryResult<TDto>>> QueryOwned(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] bool useDefaultOrders = false,
|
|
[FromQuery] bool useDefaultIncludes = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(query)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
|
|
//
|
|
var result = await provider.QueryOwned(
|
|
query: query,
|
|
predicate: null,
|
|
userInfo: userInfo,
|
|
orderBuilder: !useDefaultOrders
|
|
? null
|
|
: defaultOrderBuilder,
|
|
includeBuilder: !useDefaultIncludes
|
|
? null
|
|
: defaultIncludeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Add/Update/Remove ...
|
|
/// <summary>
|
|
/// Add an item ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("")]
|
|
public virtual async Task<ActionResult<TDto>> Add(
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Add(
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPut("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Update(
|
|
[FromRoute] TKey id,
|
|
[FromBody] TDto item,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(item)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Update(
|
|
id: id,
|
|
item: item,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id}")]
|
|
public virtual async Task<ActionResult<TDto>> Remove(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
var result = await provider.Remove(
|
|
id: id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region Tag ...
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attach")]
|
|
public virtual async Task<ActionResult> AttachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tag)
|
|
.AddNotEmpty(tag.Value)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.AttachTag(
|
|
id: id,
|
|
tag: tag.Value,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tag of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detach")]
|
|
public virtual async Task<ActionResult> DetachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tag)
|
|
.AddNotEmpty(tag.Value)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.DetachTag(
|
|
id: id,
|
|
tag: tag.Value,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Tags to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attachs")]
|
|
public virtual async Task<ActionResult> AttachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tags)
|
|
.AddNotZeroChilds(tags.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.AttachTags(
|
|
id: id,
|
|
tags: tags.Items,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tags of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detachs")]
|
|
public virtual async Task<ActionResult> DetachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
if (!tags.IsNull())
|
|
{
|
|
//
|
|
await tagProvided
|
|
.DetachTags(
|
|
id: id,
|
|
tags: tags.Items,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
await tagProvided
|
|
.DetachTags(
|
|
id: id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Item Tags ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/tags")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetTags(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await tagProvided.GetTags(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagProvidedControllerBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
using xTagService.Interfaces;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagProvidedControllerBase<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXTagProvidedController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
private readonly IXTagProvided<TEntity, TDto, TKey, THub> tagProvided;
|
|
|
|
protected XTagProvidedControllerBase(
|
|
ILogger<XTagProvidedControllerBase<TEntity, TDto, TKey, THub>> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXIdentityProvider identityProvider,
|
|
IXTagProvided<TEntity, TDto, TKey, THub> tagProvided
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.tagProvided = tagProvided;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attach")]
|
|
public virtual async Task<ActionResult> AttachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tag)
|
|
.AddNotEmpty(tag.Value)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.AttachTag(
|
|
id: id,
|
|
tag: tag.Value,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tag of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detach")]
|
|
public virtual async Task<ActionResult> DetachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tag)
|
|
.AddNotEmpty(tag.Value)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.DetachTag(
|
|
id: id,
|
|
tag: tag.Value,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Tags to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attachs")]
|
|
public virtual async Task<ActionResult> AttachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.AddNotNull(tags)
|
|
.AddNotZeroChilds(tags.Items)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
await tagProvided
|
|
.AttachTags(
|
|
id: id,
|
|
tags: tags.Items,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tags of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detachs")]
|
|
public virtual async Task<ActionResult> DetachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userInfo = await GetUserInfo();
|
|
var connectionId = GetConnectionId();
|
|
|
|
//
|
|
// Get Result ...
|
|
if (!tags.IsNull())
|
|
{
|
|
//
|
|
await tagProvided
|
|
.DetachTags(
|
|
id: id,
|
|
tags: tags.Items,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
await tagProvided
|
|
.DetachTags(
|
|
id: id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Item Tags ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/tags")]
|
|
public virtual async Task<ActionResult<IEnumerable<string>>> GetTags(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(id)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Result ...
|
|
var result = await tagProvided.GetTags(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return Ok(result.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagProviderControllerBase : XBaseProvidedController<XTag, XTagDto, int, XTagDtoHub>, IXTagProviderController
|
|
{
|
|
protected XTagProviderControllerBase(
|
|
ILogger<XTagProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTagProvider provider,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagRepositoryControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagRepositoryControllerBase : XBaseRepositoryController<XTag, int>, IXBaseRepositoryController<XTag, int>
|
|
{
|
|
protected XTagRepositoryControllerBase(
|
|
ILogger<XTagRepositoryControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXTagRepository repository,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repository,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagRepositoryProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Entities;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagRepositoryProviderControllerBase : XBaseRepositoryProviderController<XTag, int, XTagEntityHub>, IXBaseRepositoryProviderController<XTag, int, XTagEntityHub>
|
|
{
|
|
protected XTagRepositoryProviderControllerBase(
|
|
ILogger<XTagRepositoryProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTagRepositoryProvider provider,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagServiceControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xDataService.Controllers;
|
|
using xDataService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagServiceControllerBase : XBaseServiceController<XTag, XTagDto, int>, IXBaseServiceController<XTag, XTagDto, int>
|
|
{
|
|
protected XTagServiceControllerBase(
|
|
ILogger<XTagServiceControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXTagRepositoryService repositoryService,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider,
|
|
repositoryService,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Controllers\XTagServiceProviderControllerBase.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Controllers;
|
|
using xPushService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Controllers
|
|
{
|
|
public abstract class XTagServiceProviderControllerBase : XBaseServiceProviderController<XTag, XTagDto, int, XTagDtoHub>, IXBaseServiceProviderController<XTag, XTagDto, int, XTagDtoHub>
|
|
{
|
|
protected XTagServiceProviderControllerBase(
|
|
ILogger<XTagServiceProviderControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTagServiceProvider provider,
|
|
Func<IQueryable<XTag>, IOrderedQueryable<XTag>> defaultOrderBuilder = null,
|
|
Func<IQueryable<XTag>, IIncludableQueryable<XTag, object>> defaultIncludeBuilder = null
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider,
|
|
defaultOrderBuilder,
|
|
defaultIncludeBuilder
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
using xTagService.Constants;
|
|
using xTagService.Helpers;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Providers;
|
|
using xTagService.Providers.Dtos;
|
|
using xTagService.Providers.Entities;
|
|
|
|
namespace xTagService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXTagService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddTagService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXTagService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddTagService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XTagService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UseXTagService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using XTag Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
pushHelper.AddHub<XTagDtoHub>(XTagServiceConstants.XTagDtoHub);
|
|
pushHelper.AddHub<XTagEntityHub>(XTagServiceConstants.XTagEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XTag Repository Descriptor ...
|
|
if (!descriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: descriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor descriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XTagServiceConstants.XTagServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddTagService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch (repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
descriptor = typeof(XTagServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XTagServiceConstants.GetXTagEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
descriptor = XTagServiceHelper.GetXTagMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
descriptor = XTagServiceHelper.GetXTagInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Register XTag Repository Descriptor ...
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: descriptor
|
|
);
|
|
|
|
//
|
|
// Register Dto Services ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXTagServiceProvider), typeof(XTagServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXTagRepositoryService), typeof(XTagRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXTagRepositoryProvider), typeof(XTagRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXTagProvider), typeof(XTagProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Extensions\XModelExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XTag source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract References of a Model ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static IList<XReference<string>> GetReferences(
|
|
this XTagDto source
|
|
)
|
|
{
|
|
//
|
|
var result = new List<XReference<string>>();
|
|
|
|
//
|
|
if (
|
|
!source.IsNullOrDefault() &&
|
|
!source.References.IsNullOrEmpty()
|
|
)
|
|
{
|
|
//
|
|
result = source.References
|
|
.ParseXReferenceList<string>()
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XTag UpdateReferences(
|
|
this XTag source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XTag result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Model's References by Providing References List ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="references"></param>
|
|
/// <param name="forceClean"></param>
|
|
/// <returns></returns>
|
|
public static XTagDto UpdateReferences(
|
|
this XTagDto source,
|
|
IList<XReference<string>> references,
|
|
bool forceClean = true
|
|
)
|
|
{
|
|
//
|
|
XTagDto result = source;
|
|
|
|
//
|
|
if (!source.IsNullOrDefault())
|
|
{
|
|
//
|
|
result = source;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
result.References = string.Empty;
|
|
}
|
|
|
|
//
|
|
if (!references.IsNull() &&
|
|
references.HasChild())
|
|
{
|
|
result.References = references.ToXReferenceString();
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Helpers\XTagServiceHelper.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Entities;
|
|
using xTagService.Providers.GraphQL;
|
|
|
|
namespace xTagService.Helpers
|
|
{
|
|
public static class XTagServiceHelper
|
|
{
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagEFRepository<TContext>,
|
|
TContext
|
|
> GetXTagEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagEFRepository<TContext>,
|
|
TContext,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
> GetXTagEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XTag, int>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagEFRepository<TContext>,
|
|
TContext,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagMongoRepository
|
|
> GetXTagMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagMongoRepository,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
> GetXTagMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XTag, int>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagMongoRepository,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagInMemoryRepository
|
|
> GetXTagInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagInMemoryRepository,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
> GetXTagInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XTag, int>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XTag,
|
|
int,
|
|
IXTagKeyGenerator,
|
|
XTagKeyGenerator,
|
|
IXTagRepositoryEvents,
|
|
XTagRepositoryEvents,
|
|
XTagGraphType,
|
|
IntGraphType,
|
|
XTagGraphQuery,
|
|
IXTagGraphQLTypeHelper,
|
|
XTagGraphQLTypeHelper,
|
|
XTagGraphSchema,
|
|
IXTagRepository,
|
|
XTagInMemoryRepository,
|
|
IXTagSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Dtos\IXTagDtoHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Dtos
|
|
{
|
|
public interface IXTagDtoHub : IXBaseDtoHub<XTag, XTagDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Dtos\IXTagRepositoryService.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Dtos
|
|
{
|
|
public interface IXTagRepositoryService : IXBaseRepositoryService<XTag, XTagDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Dtos\IXTagServiceProvider.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Interfaces.Dtos
|
|
{
|
|
public interface IXTagServiceProvider : IXBaseDtoProvider<XTag, XTagDto, int, XTagDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagEntityHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagEntityHub : IXBaseEntityHub<XTag, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagGraphQLTypeHelper.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XTag, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagKeyGenerator.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagKeyGenerator : IXKeyGenerator<XTag, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagRepository.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagRepository : IXBaseRepository<XTag, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagRepositoryEvents : IXBaseRepositoryEvents<XTag>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagRepositoryProvider.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagRepositoryProvider : IXBaseEntityProvider<XTag, int, XTagEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\Entities\IXTagSeeder.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Interfaces.Entities
|
|
{
|
|
public interface IXTagSeeder : IXBaseDbSeeder<XTag, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXBaseProvidedHasTag.cs
|
|
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXBaseProvidedHasTag<TEntity, TDto, TKey, THub> : IXBaseProvided<TEntity, TDto, TKey, THub>, IXTagProvided<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXBaseProvidedHasTagController.cs
|
|
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXBaseProvidedHasTagController<TEntity, TDto, TKey, THub> : IXBaseProvidedController<TEntity, TDto, TKey, THub>, IXTagProvidedController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXBaseTagProvider.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
using xTagService.Models.Dtos;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXBaseTagProvider<TKey> : IXBaseReferencedProvider<XTagDto, TKey>
|
|
{
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Add Reference a Tag to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
string tag,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Add Reference a Tag to Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> AddReference(
|
|
string tag,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Tag for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
string tag,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Tag for Specific XRefence<TKey/> ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<bool> RemoveReference(
|
|
string tag,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXTagProvided.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// a Tag Provided Service is a Model Provider Service which
|
|
/// can Contains Tags ...
|
|
/// </summary>
|
|
public interface IXTagProvided<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AttachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Detach Tag of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task DetachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Attach Tags to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task AttachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Detach Tags of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task DetachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Detach all Attached Tags of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task DetachTags(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get Specified Item Tags ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<IEnumerable<string>> GetTags(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXTagProvidedController.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXTagProvidedController<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attach")]
|
|
Task<ActionResult> AttachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Detach Tag of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detach")]
|
|
Task<ActionResult> DetachTag(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseValueContainer<string> tag,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Attach Tags to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/attachs")]
|
|
Task<ActionResult> AttachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Detach Tags of Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("{id}/tags/detachs")]
|
|
Task<ActionResult> DetachTags(
|
|
[FromRoute] TKey id,
|
|
[FromBody] XBaseRangeRequest<string> tags = null,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get Specified Item Tags ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
[HttpGet("{id}/tags")]
|
|
Task<ActionResult<IEnumerable<string>>> GetTags(
|
|
[FromRoute] TKey id,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXTagProvider.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXTagProvider : IXBaseProvided<XTag, XTagDto, int, XTagDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Interfaces\IXTagProviderController.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Interfaces
|
|
{
|
|
public interface IXTagProviderController : IXBaseProvidedController<XTag, XTagDto, int, XTagDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Models\Dtos\XTagDto.cs
|
|
|
|
using xModels.Base;
|
|
|
|
namespace xTagService.Models.Dtos
|
|
{
|
|
public class XTagDto : XBaseIntIDEntityDto
|
|
{
|
|
public string Tag { get; set; }
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Models\Entities\XTag.cs
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
|
|
namespace xTagService.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// a Tag Model ...
|
|
/// </summary>
|
|
public class XTag : XBaseIntIDEntity
|
|
{
|
|
/// <summary>
|
|
/// Tag Label ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Tag { get; set; }
|
|
|
|
/// <summary>
|
|
/// Comma Separated List Which Provides Pointer to Specified
|
|
/// Model for Describe ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string References { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Dtos\XTagDtoHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Dtos
|
|
{
|
|
public class XTagDtoHub : XBaseDtoHub<XTag, XTagDto, int>, IXTagDtoHub
|
|
{
|
|
public XTagDtoHub(
|
|
ILogger<XTagDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Dtos\XTagRepositoryService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Dtos
|
|
{
|
|
public class XTagRepositoryService : XBaseRepositoryService<XTag, XTagDto, int>, IXTagRepositoryService
|
|
{
|
|
public XTagRepositoryService(
|
|
IXTagRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Dtos\XTagServiceProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Dtos
|
|
{
|
|
public class XTagServiceProvider : XBaseDtoProvider<XTag, XTagDto, int, XTagDtoHub>, IXTagServiceProvider
|
|
{
|
|
public XTagServiceProvider(
|
|
IHubContext<XTagDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXTagRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagEFRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagEFRepository<TContext> : XBaseEFRepository<XTag, int, TContext>, IXTagRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XTagEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXTagKeyGenerator keyGenerator = null,
|
|
IXTagRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagEntityHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagEntityHub : XBaseEntityHub<XTag, int>, IXTagEntityHub
|
|
{
|
|
public XTagEntityHub(
|
|
ILogger<XTagEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagInMemoryRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagInMemoryRepository : XBaseInMemoryRepository<XTag, int>, IXTagRepository
|
|
{
|
|
public XTagInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXTagKeyGenerator keyGenerator = null,
|
|
IXTagRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagKeyGenerator : XIntKeyGenerator<XTag>, IXTagKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagMongoRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagMongoRepository : XBaseMongoRepository<XTag, int>, IXTagRepository
|
|
{
|
|
public XTagMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXTagKeyGenerator keyGenerator = null,
|
|
IXTagRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagRepositoryEvents : XBaseRepositoryEvents<XTag>, IXTagRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagRepositoryProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public class XTagRepositoryProvider : XBaseEntityProvider<XTag, int, XTagEntityHub>, IXTagRepositoryProvider
|
|
{
|
|
public XTagRepositoryProvider(
|
|
IHubContext<XTagEntityHub> hub,
|
|
IXTagRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\Entities\XTagSeederBase.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.Entities
|
|
{
|
|
public abstract class XTagSeederBase : XBaseDbSeeder<XTag, int>, IXTagSeeder
|
|
{
|
|
protected XTagSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXTagRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\GraphQL\XTagGraphQLTypeHelper.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xTagService.Constants;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.GraphQL
|
|
{
|
|
public class XTagGraphQLTypeHelper : XBaseGraphQLTypeHelper<XTag, int>, IXTagGraphQLTypeHelper
|
|
{
|
|
public XTagGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XTagServiceConstants.XTagCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XTagServiceConstants.XTagSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\GraphQL\XTagGraphQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xTagService.Interfaces.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.GraphQL
|
|
{
|
|
public class XTagGraphQuery : XBaseGraphQLQuery<XTag, int, XTagGraphType, IntGraphType>
|
|
{
|
|
public XTagGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXTagRepository repository,
|
|
IXTagGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\GraphQL\XTagGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xTagService.Providers.GraphQL
|
|
{
|
|
public class XTagGraphSchema : Schema
|
|
{
|
|
public XTagGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XTagGraphQuery)services.GetService(typeof(XTagGraphQuery));
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\GraphQL\XTagGraphType.cs
|
|
|
|
using xDataService.GraphQL;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers.GraphQL
|
|
{
|
|
public class XTagGraphType : XBaseGraphObjectType<XTag, int>
|
|
{
|
|
public XTagGraphType() : base()
|
|
{
|
|
Field(x => x.Tag);
|
|
Field(x => x.References);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\XBaseProvidedHasTag.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
using xTagService.Interfaces;
|
|
using xIdentityModels.Extensions;
|
|
using System.Threading;
|
|
using xExceptions.Constants;
|
|
using System.Linq.Expressions;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
using xModels.Dtos;
|
|
|
|
namespace xTagService.Providers
|
|
{
|
|
public abstract class XBaseProvidedHasTag<TEntity, TDto, TKey, THub> : IXBaseProvidedHasTag<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
private readonly string[] permittedRoles;
|
|
private readonly IXBaseTagProvider<TKey> tagProvider;
|
|
private readonly IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider;
|
|
|
|
protected XBaseProvidedHasTag(
|
|
IXBaseTagProvider<TKey> tagProvider,
|
|
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
|
|
string[] permittedRoles = null
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.tagProvider = tagProvider;
|
|
this.permittedRoles = permittedRoles;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Items is Owned for User or not ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public abstract bool IsOwned(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
public abstract bool IsOwned(
|
|
TEntity item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check User Has Permission for Manipulate Data or not ...
|
|
/// </summary>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public bool HasPermision(
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!userInfo.IsNullOrDefault() &&
|
|
userInfo.HasAccess(permittedRoles);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Tag ...
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task AttachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tag.IsNullOrEmpty() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.AddReference(
|
|
tag: tag,
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tag fro Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tag.IsNullOrEmpty() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.RemoveReference(
|
|
tag: tag,
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task AttachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tags.IsNull() &&
|
|
tags.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Loop through Tags ...
|
|
foreach (var tag in tags)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
await AttachTag(
|
|
id: id,
|
|
tag: tag,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tags.IsNull() &&
|
|
tags.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Loop through Tags ...
|
|
foreach (var tag in tags)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
await DetachTag(
|
|
id: id,
|
|
tag: tag,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach all Attached Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTags(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.RemoveReferences(
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Model's Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<string>> GetTags(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !id.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
isValid = await provider.IsExistsAsync(
|
|
id: id,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = (await tagProvider.GetAllReferences(
|
|
providedForId: id,
|
|
cancellationToken: cancellationToken
|
|
))
|
|
.Select(x => x.Tag)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Provided ...
|
|
/// <summary>
|
|
/// Get Specified Item by ID ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Get(
|
|
TKey id,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Exists Items ...
|
|
/// </summary>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> GetAll(
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.GetAllAsync(
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find an item by providing a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> FindOne(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.FindOneAsync(
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// find a collection of Items by proving a Conditional Expression ...
|
|
/// </summary>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<TDto>> FindMany(
|
|
Expression<Func<TEntity, bool>> predicate,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.FindManyAsync(
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Items based on XQuery Pagination structure ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TDto>> Query(
|
|
XQuery query,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.QueryAsync(
|
|
query: query,
|
|
predicate: predicate,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Owned Items based on XQuery Pagination structure ...
|
|
/// if supported ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="predicate"></param>
|
|
/// <param name="orderBuilder"></param>
|
|
/// <param name="includeBuilder"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<XQueryResult<TDto>> QueryOwned(
|
|
XQuery query,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
Expression<Func<TEntity, bool>> predicate = null,
|
|
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
|
|
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
Expression<Func<TEntity, bool>> predicateor = null;
|
|
if (!predicate.IsNull())
|
|
{
|
|
//
|
|
var predicateFnc = predicate.Compile();
|
|
predicateor = x =>
|
|
predicateFnc(x) &&
|
|
IsOwned(x, userInfo);
|
|
}
|
|
else
|
|
{
|
|
predicateor = x => IsOwned(x, userInfo);
|
|
}
|
|
|
|
//
|
|
var result = await provider.QueryAsync(
|
|
query: query,
|
|
predicate: predicateor,
|
|
ignoreSoftDeleteds: true,
|
|
orderBuilder: orderBuilder,
|
|
includeBuilder: includeBuilder,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an item values ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Add(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.AddAsync(
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update an item values ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Update(
|
|
TKey id,
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check Permission ...
|
|
var hasPermission =
|
|
IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo);
|
|
if (!hasPermission)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.UpdateAsync(
|
|
id: id,
|
|
item: item,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// remove an Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<TDto> Remove(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Check Permission ...
|
|
var item = await Get(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var hasPermission =
|
|
IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo);
|
|
if (!hasPermission)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await provider.RemoveAsync(
|
|
id: id,
|
|
saveChanges: true,
|
|
softDelete: false,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// count all exists Items ...
|
|
/// </summary>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<int> Count(
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.CountAsync(
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Item exists or not ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<bool> IsExists(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = await provider.IsExistsAsync(
|
|
id: id,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\XBaseTagProvided.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xModels.Base;
|
|
using xPushService.Base;
|
|
using xPushService.Interfaces;
|
|
using xTagService.Interfaces;
|
|
using xIdentityModels.Extensions;
|
|
using xExceptions.Constants;
|
|
using System.Linq;
|
|
|
|
namespace xTagService.Providers
|
|
{
|
|
public abstract class XBaseTagProvided<TEntity, TDto, TKey, THub> : IXTagProvided<TEntity, TDto, TKey, THub>
|
|
where TEntity : XBaseEntity<TKey>
|
|
where TDto : XBaseEntityDto<TKey>
|
|
where THub : XBaseDtoHub<TEntity, TDto, TKey>
|
|
{
|
|
private readonly string[] permittedRoles;
|
|
private readonly IXBaseTagProvider<TKey> tagProvider;
|
|
private readonly IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider;
|
|
|
|
protected XBaseTagProvided(
|
|
IXBaseTagProvider<TKey> tagProvider,
|
|
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
|
|
string[] permittedRoles = null
|
|
)
|
|
{
|
|
this.provider = provider;
|
|
this.tagProvider = tagProvider;
|
|
this.permittedRoles = permittedRoles;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check an Items is Owned for User or not ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public abstract bool IsOwned(
|
|
TDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
public abstract bool IsOwned(
|
|
TEntity item,
|
|
XUserClaimsInfoDto userInfo
|
|
);
|
|
|
|
/// <summary>
|
|
/// Check User Has Permission for Manipulate Data or not ...
|
|
/// </summary>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public bool HasPermision(
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
//
|
|
var result =
|
|
!userInfo.IsNullOrDefault() &&
|
|
userInfo.HasAccess(permittedRoles);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Attach Tag to Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task AttachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tag.IsNullOrEmpty() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.AddReference(
|
|
tag: tag,
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tag fro Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tag"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTag(
|
|
TKey id,
|
|
string tag,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tag.IsNullOrEmpty() &&
|
|
!userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.RemoveReference(
|
|
tag: tag,
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task AttachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tags.IsNull() &&
|
|
tags.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Loop through Tags ...
|
|
foreach (var tag in tags)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
await AttachTag(
|
|
id: id,
|
|
tag: tag,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="tags"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTags(
|
|
TKey id,
|
|
IEnumerable<string> tags,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull() &&
|
|
!tags.IsNull() &&
|
|
tags.HasChild();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Loop through Tags ...
|
|
foreach (var tag in tags)
|
|
{
|
|
//
|
|
// Check Cancellation Token ...
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
await DetachTag(
|
|
id: id,
|
|
tag: tag,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detach all Attached Tags for Specified Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task DetachTags(
|
|
TKey id,
|
|
XUserClaimsInfoDto userInfo = null,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!id.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var item = await provider.GetAsync(
|
|
id: id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!item.IsNullOrDefault() &&
|
|
(IsOwned(item, userInfo) ||
|
|
HasPermision(userInfo));
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await tagProvider.RemoveReferences(
|
|
providedForId: id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Model's Item ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public virtual async Task<IEnumerable<string>> GetTags(
|
|
TKey id,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !id.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
isValid = await provider.IsExistsAsync(
|
|
id: id,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = (await tagProvider.GetAllReferences(
|
|
providedForId: id,
|
|
cancellationToken: cancellationToken
|
|
))
|
|
.Select(x => x.Tag)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\XBaseTagProvider.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
using xTagService.Extensions;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
|
|
namespace xTagService.Providers
|
|
{
|
|
public abstract class XBaseTagProvider<TKey> : IXBaseTagProvider<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Provider Identifier ...
|
|
/// </summary>
|
|
public string Provider { get; }
|
|
|
|
/// <summary>
|
|
/// Tag Provider for Maipulating Tags ...
|
|
/// </summary>
|
|
public IXTagServiceProvider TagProvider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseTagProvider(
|
|
string providedFor,
|
|
IXTagServiceProvider tagProvider
|
|
)
|
|
{
|
|
//
|
|
Provider = providedFor;
|
|
TagProvider = tagProvider;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XTagDto> GetReference(
|
|
TKey providedForId,
|
|
int forIndex = 0,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (forIndex < 0)
|
|
{
|
|
forIndex = 0;
|
|
}
|
|
|
|
//
|
|
// Retrieve Last Index ...
|
|
var maxIndex = (await GetReferencingIndexes(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
))
|
|
.Max();
|
|
if (forIndex > maxIndex)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var indexedIdentifier = GetIndexedProvidedID(
|
|
forIndex: forIndex,
|
|
providedForId: providedForId
|
|
);
|
|
var result = await TagProvider.FindOneAsync(
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(indexedIdentifier)
|
|
);
|
|
if (result.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XTagDto>> GetAllReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = await TagProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract all Referencing Models for Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XReference<TKey>>> GetAllReferencings(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
|
|
//
|
|
var result = (await TagProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
))
|
|
.Select(x => x.References)
|
|
.ToList()
|
|
.SelectMany(x => x.ParseXReferenceList<TKey>())
|
|
.Where(x => x.ProvidedFor == Provider && $"{x.ReferencedTo}" == $"{providedForId}")
|
|
.OrderBy(x => x.Index)
|
|
.AsEnumerable();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count References ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<int> CountReferences(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = (await TagProvider.FindManyAsync(
|
|
orderBuilder: null,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
predicate: x => x.References.Contains(identifier)
|
|
))
|
|
.Count();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XTagDto>> QueryReferences(
|
|
XQuery query,
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (query.IsNull() || providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var result = await TagProvider.QueryAsync(
|
|
query: query,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken,
|
|
orderBuilder: x => x.OrderBy(y => y.Id),
|
|
predicate: x => x.References.Contains(identifier)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XTagDto model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = !model.IsNullOrDefault() &&
|
|
!model.Tag.IsNullOrEmpty() &&
|
|
model.Id.IsValidIntId() &&
|
|
!providedForId.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Model Exists ...
|
|
result = await TagProvider.IsExistsAsync(model.Id);
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Model by Retrieving ...
|
|
model = await TagProvider.GetAsync(
|
|
id: model.Id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Retrieve all References ...
|
|
var references = await GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check isReferenced or not ...
|
|
result = references
|
|
.Any(r =>
|
|
r.Id == model.Id &&
|
|
r.GetReferences()
|
|
.Any(rf =>
|
|
rf.ProvidedFor == Provider &&
|
|
rf.ReferencedTo == $"{providedForId}"));
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Here means there is not any reference to ProvidedForId ...
|
|
int forIndex = await CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var modelReferences = model.GetReferences();
|
|
modelReferences.Add(new XReference<string>
|
|
{
|
|
Index = forIndex,
|
|
ProvidedFor = Provider,
|
|
ReferencedTo = $"{providedForId}"
|
|
});
|
|
modelReferences = modelReferences
|
|
.OrderBy(r => r.Index)
|
|
.ToList();
|
|
model = model.UpdateReferences(modelReferences);
|
|
|
|
//
|
|
// Update Data Base ...
|
|
model = await TagProvider.UpdateAsync(
|
|
id: model.Id,
|
|
item: model,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XTagDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
// Since other Validations Handled in Calling, we Ignore them here ...
|
|
var result =
|
|
!model.IsNull() &&
|
|
!reference.IsNullOrDefault() &&
|
|
reference.ProvidedFor == Provider &&
|
|
!reference.ReferencedTo.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
result = await AddReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XTagDto model,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!providedForId.IsNull() &&
|
|
!model.IsNullOrDefault() &&
|
|
model.Id.IsValidIntId();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Model ...
|
|
model = await TagProvider.GetAsync(
|
|
id: model.Id,
|
|
includeBuilder: null,
|
|
ignoreSoftDeleteds: true,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Reading Referencing Indexes ...
|
|
var indexes = await GetReferencingIndexes(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
// Check Model Reference to ID ...
|
|
var referencesCount = await CountReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = referencesCount == 0;
|
|
if (result)
|
|
{
|
|
//
|
|
// There is not any Reference to Remove ...
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Model is Trully Referenced to ProvidedForId or not ...
|
|
var reference = model
|
|
.GetReferences()
|
|
.FirstOrDefault(r =>
|
|
r.ProvidedFor == Provider &&
|
|
r.ReferencedTo == $"{providedForId}");
|
|
result = !reference.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Remove Referenced Item from Model ...
|
|
var modelReferences = model
|
|
.GetReferences()
|
|
.Where(r =>
|
|
!(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo == $"{providedForId}"))
|
|
.ToList();
|
|
model = model.UpdateReferences(modelReferences);
|
|
|
|
//
|
|
// Update DataBase ...
|
|
model = await TagProvider.UpdateAsync(
|
|
item: model,
|
|
id: model.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
result = !model.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Get Max Exists Indexes ...
|
|
var maxIndex = indexes.Max();
|
|
|
|
//
|
|
// Here We Have to Re Arrange Indexed ...
|
|
if (reference.Index < maxIndex)
|
|
{
|
|
//
|
|
var startIndex = reference.Index + 1;
|
|
for (int i = startIndex; i <= maxIndex; i++)
|
|
{
|
|
//
|
|
var dto = await GetReference(
|
|
forIndex: i,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!dto.IsNullOrDefault())
|
|
{
|
|
//
|
|
var dtoReferences = dto.GetReferences();
|
|
dtoReferences
|
|
.ToList()
|
|
.ForEach(iref =>
|
|
{
|
|
//
|
|
if (
|
|
iref.Index == i &&
|
|
iref.ProvidedFor == Provider &&
|
|
iref.ReferencedTo == reference.ReferencedTo
|
|
)
|
|
{
|
|
iref.Index = i - 1;
|
|
}
|
|
});
|
|
dto = dto.UpdateReferences(dtoReferences);
|
|
|
|
//
|
|
dto = await TagProvider.UpdateAsync(
|
|
item: dto,
|
|
id: dto.Id,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XTagDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (model.IsNullOrDefault() ||
|
|
reference.IsNullOrDefault() ||
|
|
reference.ReferencedTo.IsNull() ||
|
|
reference.ProvidedFor != Provider)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await RemoveReference(
|
|
model: model,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReferences(
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = false;
|
|
var references = await GetAllReferences(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!references.IsNull() && references.HasChild())
|
|
{
|
|
//
|
|
foreach (var reference in references)
|
|
{
|
|
//
|
|
// Remove Reference ...
|
|
var itemReferences = reference.GetReferences()
|
|
.Where(r =>
|
|
r.ProvidedFor != Provider ||
|
|
(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo != $"{providedForId}"))
|
|
.ToList();
|
|
var updatedModel = reference.UpdateReferences(itemReferences);
|
|
updatedModel = await TagProvider.UpdateAsync(
|
|
saveChanges: true,
|
|
item: updatedModel,
|
|
id: updatedModel.Id,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!updatedModel.IsNullOrDefault())
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Add Reference a Tag to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
string tag,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = !tag.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Tag Exists ...
|
|
result = await IsExists(
|
|
tag: tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
// Create Tag if Not Exists ...
|
|
var tagDto = new XTagDto
|
|
{
|
|
Tag = tag,
|
|
};
|
|
tagDto = await TagProvider.AddAsync(
|
|
item: tagDto,
|
|
saveChanges: true,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !tagDto.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
|
|
//
|
|
var dto = await GetTagByTag(
|
|
tag: tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !dto.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
result = await AddReference(
|
|
model: dto,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Tag to Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
string tag,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!tag.IsNullOrEmpty() &&
|
|
!reference.IsNullOrDefault() &&
|
|
reference.ProvidedFor == Provider &&
|
|
!reference.ReferencedTo.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
result = await AddReference(
|
|
tag: tag,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Tag for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
string tag,
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!tag.IsNullOrEmpty() &&
|
|
!providedForId.IsNull();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Tag Exists ...
|
|
result = await IsExists(
|
|
tag: tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var dto = await GetTagByTag(
|
|
tag: tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !dto.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
result = await RemoveReference(
|
|
model: dto,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Tag for Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
string tag,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result =
|
|
!tag.IsNullOrEmpty() &&
|
|
!reference.IsNullOrDefault() &&
|
|
!reference.ReferencedTo.IsNull() &&
|
|
reference.ProvidedFor == Provider;
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
result = await RemoveReference(
|
|
tag: tag,
|
|
connectionId: connectionId,
|
|
cancellationToken: cancellationToken,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private string GetProvidedID(
|
|
TKey providedForId,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = $"{Provider}{splitter}{providedForId}";
|
|
return result;
|
|
}
|
|
|
|
private string GetIndexedProvidedID(
|
|
TKey providedForId,
|
|
int forIndex,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{forIndex}";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private async Task<IEnumerable<int>> GetReferencingIndexes(
|
|
TKey providedForId,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new List<int>();
|
|
var referencings = await GetAllReferencings(
|
|
providedForId: providedForId,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
isValid =
|
|
!referencings.IsNull() &&
|
|
referencings.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
referencings
|
|
.OrderBy(r => r.Index)
|
|
.Select(r => r.Index)
|
|
.ToList();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private async Task<XTagDto> GetTagByTag(
|
|
string tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
XTagDto result = null;
|
|
|
|
//
|
|
if (!tag.IsNullOrEmpty())
|
|
{
|
|
//
|
|
result = await TagProvider
|
|
.FindOneAsync(
|
|
predicate: x => x.Tag == tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private async Task<bool> IsExists(
|
|
string tag,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
if (!tag.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var dto = await GetTagByTag(
|
|
tag: tag,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
result = !dto.IsNullOrDefault();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\XTagEntityRegisterar.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xTagService.Configurations.Entities;
|
|
using xTagService.Models.Entities;
|
|
|
|
namespace xTagService.Providers
|
|
{
|
|
public class XTagEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XTagEntityRegisterar()
|
|
: base(nameof(XTagEntityRegisterar))
|
|
{
|
|
//
|
|
// Add XTag Entity ...
|
|
AddEntity<XTag, int>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XTagEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTagService\Providers\XTagProvider.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xPushService.Providers;
|
|
using xTagService.Interfaces;
|
|
using xTagService.Interfaces.Dtos;
|
|
using xTagService.Models.Dtos;
|
|
using xTagService.Models.Entities;
|
|
using xTagService.Providers.Dtos;
|
|
|
|
namespace xTagService.Providers
|
|
{
|
|
public class XTagProvider : XBaseProvided<XTag, XTagDto, int, XTagDtoHub>, IXTagProvider
|
|
{
|
|
public XTagProvider(
|
|
IXTagServiceProvider provider
|
|
) : base(
|
|
provider,
|
|
permittedRoles: new string[] { }
|
|
)
|
|
{ }
|
|
|
|
public override bool IsOwned(
|
|
XTagDto item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
|
|
public override bool IsOwned(
|
|
XTag item,
|
|
XUserClaimsInfoDto userInfo
|
|
)
|
|
{
|
|
return !item.IsNullOrDefault();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Configurations\XTermsAndConditionsServiceConfiguration.cs
|
|
|
|
using System.Collections.Generic;
|
|
using xDataService.Constants;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xTermsAndConditionsService.Configurations
|
|
{
|
|
/// <summary>
|
|
/// Terms and Conditions Configuration ...
|
|
/// </summary>
|
|
public class XTermsAndConditionsServiceConfiguration
|
|
{
|
|
/// <summary>
|
|
/// Terms And Conditions Resource Title in XString Table ...
|
|
/// </summary>
|
|
public string ResourceTitle { get; set; } = "terms_and_conditions";
|
|
|
|
/// <summary>
|
|
/// Seeding Mode for Terms and Conditions ...
|
|
/// </summary>
|
|
public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.AddIfNotExists;
|
|
|
|
/// <summary>
|
|
/// Default Terms and Conditions for Add to Databse on App Startup ...
|
|
/// </summary>
|
|
public List<XStringDto> TermsAndConditions { get; set; } = null;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xTermsAndConditionsService.Constants
|
|
{
|
|
public partial struct ConfigurationNodeNames
|
|
{
|
|
public const string TERMS_AND_CONDITIONS_SERVICE_NODE = "TermsAndConditionsService";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Constants\XTermsAndConditionsServiceConstants.cs
|
|
|
|
namespace xTermsAndConditionsService.Constants
|
|
{
|
|
public struct XTermsAndConditionsServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XTermsAndConditionsServiceDILogTag = "XTermsAndConditionsService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
|
|
//
|
|
// Hubs ...
|
|
|
|
//
|
|
// Custome Constants ...
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Controllers\XTermsAndConditionsControllerBase.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Interfaces;
|
|
using xStringService.Controllers;
|
|
using xTermsAndConditionsService.Interfaces;
|
|
|
|
namespace xTermsAndConditionsService.Controllers
|
|
{
|
|
/// <summary>
|
|
/// a Base Controller Implementation for Providing Base Actions of
|
|
/// Terms and Conditions Provided Actions ...
|
|
/// </summary>
|
|
[AllowAnonymous]
|
|
public abstract class XTermsAndConditionsControllerBase : XBaseResourceProviderControllerBase<IXTermsAndConditionsProvider>, IXTermsAndConditionsController
|
|
{
|
|
protected XTermsAndConditionsControllerBase(
|
|
ILogger<XTermsAndConditionsControllerBase> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider,
|
|
IXTermsAndConditionsProvider provider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider,
|
|
provider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
using xStringService.Interfaces.Dtos;
|
|
using xTermsAndConditionsService.Configurations;
|
|
using xTermsAndConditionsService.Constants;
|
|
using xTermsAndConditionsService.Hubs;
|
|
using xTermsAndConditionsService.Interfaces;
|
|
using xTermsAndConditionsService.Providers;
|
|
|
|
namespace xTermsAndConditionsService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Retrieve xTermsAndConditionsService Configuration from AppSettings ...
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XTermsAndConditionsServiceConfiguration GetXTermsAndConditionsServiceConfiguration(
|
|
this IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
var section = configuration.GetSection(ConfigurationNodeNames.TERMS_AND_CONDITIONS_SERVICE_NODE);
|
|
var result = section.Get<XTermsAndConditionsServiceConfiguration>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract xTermsAndConditionsService Configurations from AppSettings
|
|
/// and Register it in DI ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXTermsAndConditionsConfiguration(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
var serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
|
|
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register xTermsAndConditionsService Configurations in DI ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXTermsAndConditionsConfiguration(
|
|
this IServiceCollection services,
|
|
XTermsAndConditionsServiceConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
if (configuration.IsNull())
|
|
{
|
|
Log($"there is no provided configurations, using default ...");
|
|
configuration = new XTermsAndConditionsServiceConfiguration();
|
|
}
|
|
|
|
//
|
|
services.AddSingleton(configuration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register TermsConditions Provider ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration">provided AppSettings Configuration</param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXTermsConditionsService(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
|
)
|
|
{
|
|
//
|
|
AddTermsAndConditionsService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
configuration: configuration
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register TermsConditions Provider ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration">provided xTermsAndConditionsService Configuration</param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXTermsConditionsService(
|
|
this IServiceCollection services,
|
|
XTermsAndConditionsServiceConfiguration configuration,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
|
)
|
|
{
|
|
//
|
|
AddTermsAndConditionsService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
serviceConfiguration: configuration
|
|
);
|
|
}
|
|
|
|
public static void UseXTermsAndConditionsService(
|
|
this IApplicationBuilder app
|
|
)
|
|
{
|
|
//
|
|
// Create an Scope for Services Acess ...
|
|
using (var scope = app.ApplicationServices.CreateScope())
|
|
{
|
|
//
|
|
// Inject Requirements ...
|
|
var stringProvider = scope.ServiceProvider.GetService<IXStringServiceProvider>();
|
|
var serviceConfiguration = scope.ServiceProvider.GetService<XTermsAndConditionsServiceConfiguration>();
|
|
|
|
//
|
|
// Using XTerms Hub ...
|
|
var pushHelper = new XPushServiceHelper();
|
|
pushHelper.AddHub<XTermsHub>("terms");
|
|
app.UseXPushService(pushHelper);
|
|
|
|
//
|
|
// Validate Requirements Exists ...
|
|
var isValid =
|
|
!stringProvider.IsNull() &&
|
|
!serviceConfiguration.IsNull() &&
|
|
!serviceConfiguration.TermsAndConditions.IsNull() &&
|
|
serviceConfiguration.TermsAndConditions.HasChild() &&
|
|
serviceConfiguration.SeedingMode != xDataService.Constants.XDbSeedingMode.None;
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Prepare Default Terms ...
|
|
serviceConfiguration
|
|
.TermsAndConditions
|
|
.ToList()
|
|
.ForEach(t => t.ResourceTitle = serviceConfiguration.ResourceTitle);
|
|
|
|
//
|
|
// Loop through Terms and Conditions for Seeding ...
|
|
foreach (var item in serviceConfiguration.TermsAndConditions)
|
|
{
|
|
//
|
|
// Detect Exists Item ...
|
|
var exists = stringProvider.FindOneAsync(
|
|
predicate: x =>
|
|
x.Language == item.Language &&
|
|
x.ResourceTitle == item.ResourceTitle
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
var isExists = !exists.IsNullOrDefault();
|
|
|
|
//
|
|
switch (serviceConfiguration.SeedingMode)
|
|
{
|
|
//
|
|
case xDataService.Constants.XDbSeedingMode.AddOrUpdate:
|
|
//
|
|
// Update Exists by new Provided ...
|
|
exists.TranslatedValue = item.TranslatedValue;
|
|
exists = stringProvider.UpdateAsync(
|
|
id: exists.Id,
|
|
item: exists,
|
|
saveChanges: true
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
Log($"Refresh Terms and Conditions of {exists.Language}");
|
|
break;
|
|
|
|
//
|
|
case xDataService.Constants.XDbSeedingMode.AddIfNotExists:
|
|
//
|
|
if (!isExists)
|
|
{
|
|
//
|
|
exists = stringProvider.AddAsync(
|
|
item: item,
|
|
saveChanges: true
|
|
)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
Log($"Add Terms and Conditions for {exists.Language}");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XTermsAndConditionsServiceConstants.XTermsAndConditionsServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Terms and Conditions Provider Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddTermsAndConditionsService(
|
|
IServiceCollection services,
|
|
IConfiguration configuration = null,
|
|
XTermsAndConditionsServiceConfiguration serviceConfiguration = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("AddTermsAndConditions failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Configuration ...
|
|
var isConfigValid = !configuration.IsNull() || !serviceConfiguration.IsNull();
|
|
if (!isConfigValid)
|
|
{
|
|
//
|
|
Log("AddTermsAndConditions failed, configuration not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("AddTermsAndConditions failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Check Dependencies Exists ...
|
|
var isDependenciesPassed = !services
|
|
.GetRegisteredService<XAppConfiguration>()
|
|
.IsNull() &&
|
|
!services.GetRegisteredService<IXStringServiceProvider>()
|
|
.IsNull();
|
|
if (!isDependenciesPassed)
|
|
{
|
|
//
|
|
Log("AddTermsAndConditions failed due Dependencies Issues, IXStringServiceProvider or XAppConfiguration not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Service Configuration Handler ...
|
|
if (serviceConfiguration.IsNull())
|
|
{
|
|
serviceConfiguration = configuration.GetXTermsAndConditionsServiceConfiguration();
|
|
}
|
|
services.AddXTermsAndConditionsConfiguration(serviceConfiguration);
|
|
|
|
//
|
|
// Register Resource Providers ...
|
|
services.Add(new ServiceDescriptor(typeof(IXTermsAndConditionsProvider), typeof(XTermsAndConditionsProvider), lifeTime));
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Hubs\XTermsHub.cs
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xPushService.Base;
|
|
using xPushService.Constants;
|
|
using xStringService.Models.Dtos;
|
|
|
|
namespace xTermsAndConditionsService.Hubs
|
|
{
|
|
/// <summary>
|
|
/// a Hub for Notifing Terms and Conditions Events to Connected Clients ...
|
|
/// </summary>
|
|
public class XTermsHub : XBaseHub
|
|
{
|
|
public XTermsHub(
|
|
ILogger<XTermsHub> logger
|
|
) : base(logger)
|
|
{
|
|
}
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Add Specified Terms and Conditions ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Add(
|
|
XStringDto entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deleted Specified Terms and Conditions ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Delete(
|
|
XStringDto entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify an Entity Updated ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task Update(
|
|
XStringDto entity,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
var connectionId = Context.ConnectionId;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await Clients
|
|
.AllExcept(connectionId)
|
|
.SendAsync(
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
entity.ToJSON(camelCase: true),
|
|
connectionId,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsController.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xTermsAndConditionsService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface for Describing Terms and Conditions Management Controller Actions ...
|
|
/// </summary>
|
|
public interface IXTermsAndConditionsController : IXBaseResourceProviderController
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Interfaces\IXTermsAndConditionsProvider.cs
|
|
|
|
using xStringService.Interfaces;
|
|
|
|
namespace xTermsAndConditionsService.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// an Interface for Describing Terms and Conditions Management Provided Actions ...
|
|
/// </summary>
|
|
public interface IXTermsAndConditionsProvider : IXResourceProvider
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xTermsAndConditionsService\Providers\XTermsAndConditionsProvider.cs
|
|
|
|
using xStringService.Interfaces.Dtos;
|
|
using xStringService.Providers;
|
|
using xTermsAndConditionsService.Configurations;
|
|
using xTermsAndConditionsService.Interfaces;
|
|
|
|
namespace xTermsAndConditionsService.Providers
|
|
{
|
|
/// <summary>
|
|
/// an Implementation of Terms and Conditions Management Provided Actions ...
|
|
/// </summary>
|
|
public class XTermsAndConditionsProvider : XBaseResourceProvider, IXTermsAndConditionsProvider
|
|
{
|
|
public XTermsAndConditionsProvider(
|
|
IXStringServiceProvider provider,
|
|
XTermsAndConditionsServiceConfiguration configuration
|
|
) : base(
|
|
resource: "NULL",
|
|
provider
|
|
)
|
|
{
|
|
//
|
|
// Since we nee to Set Resource Title of Terms and Conditions
|
|
// during instancing using Provided Configurations ...
|
|
// set this value here ...
|
|
resource = configuration.ResourceTitle;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Configurations\Entities\XWebinarEntityConfiguration.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Configurations.Entities
|
|
{
|
|
public class XWebinarEntityConfiguration : XBaseEntityTypeConfiguration<XWebinar, Guid>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XWebinar> builder)
|
|
{
|
|
builder.ToTable(XWebinarServiceConstants.XWebinarTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Configurations\Entities\XWebinarSubscriberEntityConfiguration.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Configurations.Entities
|
|
{
|
|
public class XWebinarSubscriberEntityConfiguration : XBaseEntityTypeConfiguration<XWebinarSubscriber, int>
|
|
{
|
|
public override void Configure(EntityTypeBuilder<XWebinarSubscriber> builder)
|
|
{
|
|
builder.ToTable(XWebinarServiceConstants.XWebinarSubscriberTable);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Constants\XWebinarServiceConstants.cs
|
|
|
|
namespace xWebinarService.Constants
|
|
{
|
|
public struct XWebinarServiceConstants
|
|
{
|
|
//
|
|
// Service Extensions Log Tag ...
|
|
public const string XWebinarServiceDILogTag = "XWebinarService";
|
|
|
|
//
|
|
// Table Mapping Identifiers ...
|
|
public const string XWebinarTable = "Webinars";
|
|
public const string XWebinarSubscriberTable = "WebinarSubscribers";
|
|
|
|
//
|
|
// GraphQL Collection Mappings ...
|
|
public const string XWebinarSingleName = "webinar";
|
|
public const string XWebinarCollectionName = "webinars";
|
|
|
|
public const string XWebinarSubscriberSingleName = "webinarSubscriber";
|
|
public const string XWebinarSubscriberCollectionName = "webinarSubscribers";
|
|
|
|
//
|
|
// Hubs ...
|
|
public const string XWebinarDtoHub = "webinarDto";
|
|
public const string XWebinarEntityHub = "webinarEntity";
|
|
public const string XWebinarSubscriberDtoHub = "webinarSubscriberDto";
|
|
public const string XWebinarSubscriberEntityHub = "webinarSubscriberEntity";
|
|
|
|
//
|
|
// Custome Constants ...
|
|
|
|
//
|
|
// EF Repositories Helper Extensions ...
|
|
public const string GetXWebinarEFRepositoryDescriptor = "GetXWebinarEFRepositoryDescriptor";
|
|
public const string GetXWebinarSubscriberEFRepositoryDescriptor = "GetXWebinarSubscriberEFRepositoryDescriptor";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Constants\XWebinarType.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xWebinarService.Constants
|
|
{
|
|
/// <summary>
|
|
/// Webinar Type ...
|
|
/// </summary>
|
|
public enum XWebinarType
|
|
{
|
|
[StringValue("Public")]
|
|
Public = 0,
|
|
[StringValue("Private")]
|
|
Private = 1
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\DI\XDIHelperExtension.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xDataService.Constants;
|
|
using xDataService.Db;
|
|
using xDataService.DI;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xPushService.DI;
|
|
using xPushService.Helpers;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Helpers;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Providers.Dtos;
|
|
using xWebinarService.Providers.Entities;
|
|
|
|
namespace xWebinarService.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXWebinarService(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
AddWebinarService(
|
|
contextType: null,
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <typeparam name="TContext"></typeparam>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
public static void AddXWebinarService<TContext>(
|
|
this IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
where TContext : XDbContext
|
|
{
|
|
AddWebinarService(
|
|
services: services,
|
|
lifeTime: lifeTime,
|
|
contextType: typeof(TContext),
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XWebinarService Middleware ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="isDevelopmentEnvironment"></param>
|
|
public static void UsexWebinarService(
|
|
this IApplicationBuilder app,
|
|
bool isDevelopmentEnvironment = false
|
|
)
|
|
{
|
|
//
|
|
#region Using XWebinar Hubs ...
|
|
//
|
|
var pushHelper = new XPushServiceHelper();
|
|
|
|
//
|
|
pushHelper.AddHub<XWebinarDtoHub>(XWebinarServiceConstants.XWebinarDtoHub);
|
|
pushHelper.AddHub<XWebinarEntityHub>(XWebinarServiceConstants.XWebinarEntityHub);
|
|
|
|
//
|
|
pushHelper.AddHub<XWebinarSubscriberDtoHub>(XWebinarServiceConstants.XWebinarSubscriberDtoHub);
|
|
pushHelper.AddHub<XWebinarSubscriberEntityHub>(XWebinarServiceConstants.XWebinarSubscriberEntityHub);
|
|
|
|
//
|
|
app.UseXPushService(pushHelper);
|
|
#endregion
|
|
|
|
//
|
|
// Using XWebinar Repository Descriptor ...
|
|
if (!webinarDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: webinarDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
|
|
//
|
|
// Using XWebinarSubscriber Repository Descriptor ...
|
|
if (!webinarSubscriberDescriptor.IsNull())
|
|
{
|
|
//
|
|
app.UseXRepository(
|
|
descriptor: webinarSubscriberDescriptor,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private static XRepositoryDescriptor webinarDescriptor = null;
|
|
private static XRepositoryDescriptor webinarSubscriberDescriptor = null;
|
|
|
|
/// <summary>
|
|
/// a LogTag for Service ...
|
|
/// </summary>
|
|
private static string XLogTag = XWebinarServiceConstants.XWebinarServiceDILogTag;
|
|
|
|
/// <summary>
|
|
/// print a log in Console ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private static void Log(string message)
|
|
{
|
|
Console.WriteLine($"{XLogTag} => {message}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Service ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="repositoryType"></param>
|
|
/// <param name="contextType"></param>
|
|
/// <param name="lifeTime"></param>
|
|
private static void AddWebinarService(
|
|
IServiceCollection services,
|
|
XRepositoryType repositoryType,
|
|
Type contextType = null,
|
|
ServiceLifetime lifeTime = ServiceLifetime.Scoped
|
|
)
|
|
{
|
|
//
|
|
var exception = XException.InvalidArgs.ToException(); ;
|
|
|
|
//
|
|
// Services ...
|
|
var isServicesExists = !services.IsNull();
|
|
if (!isServicesExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, services not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Lifetime ...
|
|
var isLifetimeExists = !lifeTime.IsNull();
|
|
if (!isLifetimeExists)
|
|
{
|
|
//
|
|
Log("Service Registration failed, lifetime not provided ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Validate Repository Type ...
|
|
var isRepositoryTypeValid =
|
|
(repositoryType == XRepositoryType.EF &&
|
|
!contextType.IsNull()) ||
|
|
((repositoryType == XRepositoryType.Mongo ||
|
|
repositoryType == XRepositoryType.InMemory) &&
|
|
contextType.IsNull());
|
|
if (!isRepositoryTypeValid)
|
|
{
|
|
//
|
|
Log("Service Registration failed, Invalid Repository Type and Context Type ...");
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Maske Instance of Repository Descriptor
|
|
// Based on Provided Type ...
|
|
switch (repositoryType)
|
|
{
|
|
//
|
|
case XRepositoryType.EF:
|
|
//
|
|
webinarDescriptor = typeof(XWebinarServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XWebinarServiceConstants.GetXWebinarEFRepositoryDescriptor
|
|
);
|
|
|
|
//
|
|
webinarSubscriberDescriptor = typeof(XWebinarServiceHelper)
|
|
.InvokeGenericMethod<XRepositoryDescriptor>(
|
|
args: null,
|
|
runtimeType: contextType,
|
|
methodName: XWebinarServiceConstants.GetXWebinarSubscriberEFRepositoryDescriptor
|
|
);
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.Mongo:
|
|
webinarDescriptor = XWebinarServiceHelper.GetXWebinarMongoRepositoryDescriptor();
|
|
webinarSubscriberDescriptor = XWebinarServiceHelper.GetXWebinarSubscriberMongoRepositoryDescriptor();
|
|
break;
|
|
|
|
//
|
|
case XRepositoryType.InMemory:
|
|
webinarDescriptor = XWebinarServiceHelper.GetXWebinarInMemoryRepositoryDescriptor();
|
|
webinarSubscriberDescriptor = XWebinarServiceHelper.GetXWebinarSubscriberInMemoryRepositoryDescriptor();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Register xWebinar Repository Descriptor ...
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: webinarDescriptor
|
|
);
|
|
|
|
services.AddXRepository(
|
|
lifeTime: lifeTime,
|
|
descriptor: webinarSubscriberDescriptor
|
|
);
|
|
|
|
//
|
|
// Register Dto Services ...
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarServiceProvider), typeof(XWebinarServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarRepositoryService), typeof(XWebinarRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarRepositoryProvider), typeof(XWebinarRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarSubscriberServiceProvider), typeof(XWebinarSubscriberServiceProvider), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarSubscriberRepositoryService), typeof(XWebinarSubscriberRepositoryService), lifeTime)
|
|
);
|
|
services.Add(
|
|
new ServiceDescriptor(typeof(IXWebinarSubscriberRepositoryProvider), typeof(XWebinarSubscriberRepositoryProvider), lifeTime)
|
|
);
|
|
|
|
//
|
|
// services.Add(
|
|
// new ServiceDescriptor(typeof(IXWebinarProvider), typeof(XWebinarProvider), lifeTime)
|
|
// );
|
|
|
|
//
|
|
Log("Service Regitration Succeed ...");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Helpers\XWebinarServiceHelper.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Db;
|
|
using xDataService.Models;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
using xWebinarService.Providers.Entities;
|
|
using xWebinarService.Providers.GraphQL;
|
|
|
|
namespace xWebinarService.Helpers
|
|
{
|
|
public static class XWebinarServiceHelper
|
|
{
|
|
//
|
|
#region XWebinar ...
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarEFRepository<TContext>,
|
|
TContext
|
|
> GetXWebinarEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarEFRepository<TContext>,
|
|
TContext,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinar, Guid>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarEFRepository<TContext>,
|
|
TContext,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarMongoRepository
|
|
> GetXWebinarMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarMongoRepository,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinar, Guid>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarMongoRepository,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarInMemoryRepository
|
|
> GetXWebinarInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarInMemoryRepository,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinar, Guid>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XWebinar,
|
|
Guid,
|
|
IXWebinarKeyGenerator,
|
|
XWebinarKeyGenerator,
|
|
IXWebinarRepositoryEvents,
|
|
XWebinarRepositoryEvents,
|
|
XWebinarGraphType,
|
|
GuidGraphType,
|
|
XWebinarGraphQuery,
|
|
IXWebinarGraphQLTypeHelper,
|
|
XWebinarGraphQLTypeHelper,
|
|
XWebinarGraphSchema,
|
|
IXWebinarRepository,
|
|
XWebinarInMemoryRepository,
|
|
IXWebinarSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
//
|
|
#region XWebinarSubscriber ...
|
|
//
|
|
#region EF Repository Descriptor Provider(s) ...
|
|
public static XEFRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberEFRepository<TContext>,
|
|
TContext
|
|
> GetXWebinarSubscriberEFRepositoryDescriptor<TContext>()
|
|
where TContext : XDbContext
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberEFRepository<TContext>,
|
|
TContext
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XEFRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberEFRepository<TContext>,
|
|
TContext,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarSubscriberEFRepositoryDescriptor<TContext, TSeederImplementation>()
|
|
where TContext : XDbContext
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinarSubscriber, int>
|
|
{
|
|
//
|
|
var result = new XEFRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberEFRepository<TContext>,
|
|
TContext,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Mongo Repository Descriptor Provider(s) ...
|
|
public static XMongoRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberMongoRepository
|
|
> GetXWebinarSubscriberMongoRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberMongoRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XMongoRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberMongoRepository,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarSubscriberMongoRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinarSubscriber, int>
|
|
{
|
|
//
|
|
var result = new XMongoRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberMongoRepository,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region InMemory Repository Descriptor Provider(s) ...
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberInMemoryRepository
|
|
> GetXWebinarSubscriberInMemoryRepositoryDescriptor()
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberInMemoryRepository
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public static XInMemoryRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberInMemoryRepository,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
> GetXWebinarSubscriberInMemoryRepositoryDescriptor<TSeederImplementation>()
|
|
where TSeederImplementation : XBaseDbSeeder<XWebinarSubscriber, int>
|
|
{
|
|
//
|
|
var result = new XInMemoryRepositoryDescriptor<
|
|
XWebinarSubscriber,
|
|
int,
|
|
IXWebinarSubscriberKeyGenerator,
|
|
XWebinarSubscriberKeyGenerator,
|
|
IXWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberRepositoryEvents,
|
|
XWebinarSubscriberGraphType,
|
|
IntGraphType,
|
|
XWebinarSubscriberGraphQuery,
|
|
IXWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphQLTypeHelper,
|
|
XWebinarSubscriberGraphSchema,
|
|
IXWebinarSubscriberRepository,
|
|
XWebinarSubscriberInMemoryRepository,
|
|
IXWebinarSubscriberSeeder,
|
|
TSeederImplementation
|
|
>();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarDtoHub.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarDtoHub : IXBaseDtoHub<XWebinar, XWebinarDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarRepositoryService.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarRepositoryService : IXBaseRepositoryService<XWebinar, XWebinarDto, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarServiceProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
using xWebinarService.Providers.Dtos;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarServiceProvider : IXBaseDtoProvider<XWebinar, XWebinarDto, Guid, XWebinarDtoHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarSubscriberDtoHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarSubscriberDtoHub : IXBaseDtoHub<XWebinarSubscriber, XWebinarSubscriberDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarSubscriberRepositoryService.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarSubscriberRepositoryService : IXBaseRepositoryService<XWebinarSubscriber, XWebinarSubscriberDto, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Dtos\IXWebinarSubscriberServiceProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace xWebinarService.Interfaces.Dtos
|
|
{
|
|
public interface IXWebinarSubscriberServiceProvider
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarEntityHub.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarEntityHub : IXBaseEntityHub<XWebinar, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XWebinar, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarKeyGenerator.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarKeyGenerator : IXKeyGenerator<XWebinar, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarRepository : IXBaseRepository<XWebinar, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarRepositoryEvents : IXBaseRepositoryEvents<XWebinar>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarRepositoryProvider.cs
|
|
|
|
using System;
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
using xWebinarService.Providers.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarRepositoryProvider : IXBaseEntityProvider<XWebinar, Guid, XWebinarEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSeeder.cs
|
|
|
|
using System;
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSeeder : IXBaseDbSeeder<XWebinar, Guid>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberEntityHub.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberEntityHub : IXBaseEntityHub<XWebinarSubscriber, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberGraphQLTypeHelper.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XWebinarSubscriber, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberKeyGenerator.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberKeyGenerator : IXKeyGenerator<XWebinarSubscriber, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberRepository.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberRepository : IXBaseRepository<XWebinarSubscriber, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberRepositoryEvents.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberRepositoryEvents : IXBaseRepositoryEvents<XWebinarSubscriber>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberRepositoryProvider.cs
|
|
|
|
using xPushService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
using xWebinarService.Providers.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberRepositoryProvider : IXBaseEntityProvider<XWebinarSubscriber, int, XWebinarSubscriberEntityHub>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Interfaces\Entities\IXWebinarSubscriberSeeder.cs
|
|
|
|
using xDataService.Interfaces;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Interfaces.Entities
|
|
{
|
|
public interface IXWebinarSubscriberSeeder : IXBaseDbSeeder<XWebinarSubscriber, int>
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Models\Dtos\XWebinarDto.cs
|
|
|
|
using System;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
using xWebinarService.Constants;
|
|
|
|
namespace xWebinarService.Models.Dtos
|
|
{
|
|
public class XWebinarDto : XBaseGuidIDEntityDto
|
|
{
|
|
public bool Enabled { get; set; }
|
|
public string OwnerId { get; set; }
|
|
public XPersonDto Owner { get; set; }
|
|
public XWebinarType Type { get; set; }
|
|
public XResourceDto Title { get; set; }
|
|
public DateTime CreatedOn { get; set; }
|
|
public XResourceDto Description { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Models\Dtos\XWebinarSubscriberDto.cs
|
|
|
|
using System;
|
|
using xModels.Base;
|
|
using xModels.Dtos;
|
|
|
|
namespace xWebinarService.Models.Dtos
|
|
{
|
|
public class XWebinarSubscriberDto : XBaseIntIDEntityDto
|
|
{
|
|
public Guid WebinarId { get; set; }
|
|
public string SubscriberId { get; set; }
|
|
public XPersonDto Subscriber { get; set; }
|
|
public DateTime SubscribedOn { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Models\Entities\XWebinar.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
using xWebinarService.Constants;
|
|
|
|
namespace xWebinarService.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Webinar Entity ...
|
|
/// </summary>
|
|
public class XWebinar : XBaseGuidIDEntity
|
|
{
|
|
/// <summary>
|
|
/// Title (Resource ID) ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Title { get; set; }
|
|
|
|
/// <summary>
|
|
/// Description (Resource ID) ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
[StringLength(255)]
|
|
public string Description { get; set; }
|
|
|
|
/// <summary>
|
|
/// User Identifier ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
public string OwnerId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Webinar Type ...
|
|
/// </summary>
|
|
public XWebinarType Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// Creation Time ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
[Required]
|
|
public DateTime CreatedOn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specified Webinar Enabled or not ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool Enabled { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Models\Entities\XWebinarSubscriber.cs
|
|
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using xModels.Base;
|
|
|
|
namespace xWebinarService.Models.Entities
|
|
{
|
|
/// <summary>
|
|
/// Webinar Subscriber ...
|
|
/// </summary>
|
|
public class XWebinarSubscriber : XBaseIntIDEntity
|
|
{
|
|
[Required]
|
|
public string SubscriberId { get; set; }
|
|
|
|
[Required]
|
|
public Guid WebinarId { get; set; }
|
|
|
|
public DateTime SubscribedOn { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarDtoHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarDtoHub : XBaseDtoHub<XWebinar, XWebinarDto, Guid>, IXWebinarDtoHub
|
|
{
|
|
public XWebinarDtoHub(
|
|
ILogger<XWebinarDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarRepositoryService.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarRepositoryService : XBaseRepositoryService<XWebinar, XWebinarDto, Guid>, IXWebinarRepositoryService
|
|
{
|
|
public XWebinarRepositoryService(
|
|
IXWebinarRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarServiceProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarServiceProvider : XBaseDtoProvider<XWebinar, XWebinarDto, Guid, XWebinarDtoHub>, IXWebinarServiceProvider
|
|
{
|
|
public XWebinarServiceProvider(
|
|
IHubContext<XWebinarDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXWebinarRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarSubscriberDtoHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarSubscriberDtoHub : XBaseDtoHub<XWebinarSubscriber, XWebinarSubscriberDto, int>, IXWebinarSubscriberDtoHub
|
|
{
|
|
public XWebinarSubscriberDtoHub(
|
|
ILogger<XWebinarSubscriberDtoHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarSubscriberRepositoryService.cs
|
|
|
|
using System.Collections.Generic;
|
|
using AutoMapper;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarSubscriberRepositoryService : XBaseRepositoryService<XWebinarSubscriber, XWebinarSubscriberDto, int>, IXWebinarSubscriberRepositoryService
|
|
{
|
|
public XWebinarSubscriberRepositoryService(
|
|
IXWebinarSubscriberRepository repository,
|
|
IEnumerable<Profile> mapperProfiles = null
|
|
) : base(
|
|
repository,
|
|
mapperProfiles
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Dtos\XWebinarSubscriberServiceProvider.cs
|
|
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Dtos;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Dtos
|
|
{
|
|
public class XWebinarSubscriberServiceProvider : XBaseDtoProvider<XWebinarSubscriber, XWebinarSubscriberDto, int, XWebinarSubscriberDtoHub>, IXWebinarSubscriberServiceProvider
|
|
{
|
|
public XWebinarSubscriberServiceProvider(
|
|
IHubContext<XWebinarSubscriberDtoHub> hub,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXWebinarSubscriberRepositoryService service,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
dataConfiguration,
|
|
service,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarEFRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarEFRepository<TContext> : XBaseEFRepository<XWebinar, Guid, TContext>, IXWebinarRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XWebinarEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarKeyGenerator keyGenerator = null,
|
|
IXWebinarRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarEntityHub.cs
|
|
|
|
using System;
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarEntityHub : XBaseEntityHub<XWebinar, Guid>, IXWebinarEntityHub
|
|
{
|
|
public XWebinarEntityHub(
|
|
ILogger<XWebinarEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarInMemoryRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarInMemoryRepository : XBaseInMemoryRepository<XWebinar, Guid>, IXWebinarRepository
|
|
{
|
|
public XWebinarInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarKeyGenerator keyGenerator = null,
|
|
IXWebinarRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarKeyGenerator : XGuidKeyGenerator<XWebinar>, IXWebinarKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarMongoRepository.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarMongoRepository : XBaseMongoRepository<XWebinar, Guid>, IXWebinarRepository
|
|
{
|
|
public XWebinarMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXWebinarKeyGenerator keyGenerator = null,
|
|
IXWebinarRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarRepositoryEvents : XBaseRepositoryEvents<XWebinar>, IXWebinarRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarRepositoryProvider : XBaseEntityProvider<XWebinar, Guid, XWebinarEntityHub>, IXWebinarRepositoryProvider
|
|
{
|
|
public XWebinarRepositoryProvider(
|
|
IHubContext<XWebinarEntityHub> hub,
|
|
IXWebinarRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSeederBase.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public abstract class XWebinarSeederBase : XBaseDbSeeder<XWebinar, Guid>, IXWebinarSeeder
|
|
{
|
|
public XWebinarSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXWebinarRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberEFRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberEFRepository<TContext> : XBaseEFRepository<XWebinarSubscriber, int, TContext>, IXWebinarSubscriberRepository
|
|
where TContext : XDbContext
|
|
{
|
|
public XWebinarSubscriberEFRepository(
|
|
IXUnitOfWorks<TContext> unitOfWorks,
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarSubscriberKeyGenerator keyGenerator = null,
|
|
IXWebinarSubscriberRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
unitOfWorks,
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberEntityHub.cs
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberEntityHub : XBaseEntityHub<XWebinarSubscriber, int>, IXWebinarSubscriberEntityHub
|
|
{
|
|
public XWebinarSubscriberEntityHub(
|
|
ILogger<XWebinarSubscriberEntityHub> logger
|
|
) : base(logger)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberInMemoryRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberInMemoryRepository : XBaseInMemoryRepository<XWebinarSubscriber, int>, IXWebinarSubscriberRepository
|
|
{
|
|
public XWebinarSubscriberInMemoryRepository(
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarSubscriberKeyGenerator keyGenerator = null,
|
|
IXWebinarSubscriberRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
configuration,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberKeyGenerator.cs
|
|
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberKeyGenerator : XIntKeyGenerator<XWebinarSubscriber>, IXWebinarSubscriberKeyGenerator
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberMongoRepository.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberMongoRepository : XBaseMongoRepository<XWebinarSubscriber, int>, IXWebinarSubscriberRepository
|
|
{
|
|
public XWebinarSubscriberMongoRepository(
|
|
XDataBaseConfiguration dbConfiguration,
|
|
XDataServiceConfiguration configuration,
|
|
string collectionName = null,
|
|
IXWebinarSubscriberKeyGenerator keyGenerator = null,
|
|
IXWebinarSubscriberRepositoryEvents baseRepositoryEvents = null
|
|
) : base(
|
|
dbConfiguration,
|
|
configuration,
|
|
collectionName,
|
|
keyGenerator,
|
|
baseRepositoryEvents
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberRepositoryEvents.cs
|
|
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberRepositoryEvents : XBaseRepositoryEvents<XWebinarSubscriber>, IXWebinarSubscriberRepositoryEvents
|
|
{ }
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberRepositoryProvider.cs
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xDataService.Configuration;
|
|
using xIdentityService.Interfaces;
|
|
using xPushService.Base;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public class XWebinarSubscriberRepositoryProvider : XBaseEntityProvider<XWebinarSubscriber, int, XWebinarSubscriberEntityHub>, IXWebinarSubscriberRepositoryProvider
|
|
{
|
|
public XWebinarSubscriberRepositoryProvider(
|
|
IHubContext<XWebinarSubscriberEntityHub> hub,
|
|
IXWebinarSubscriberRepository repository,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityProvider identityProvider = null
|
|
) : base(
|
|
hub,
|
|
repository,
|
|
dataConfiguration,
|
|
identityProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\Entities\XWebinarSubscriberSeederBase.cs
|
|
|
|
using xDataService.Configuration;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.Entities
|
|
{
|
|
public abstract class XWebinarSubscriberSeederBase : XBaseDbSeeder<XWebinarSubscriber, int>, IXWebinarSubscriberSeeder
|
|
{
|
|
public XWebinarSubscriberSeederBase(
|
|
string entity,
|
|
string database,
|
|
IXWebinarSubscriberRepository repository,
|
|
XDataServiceConfiguration dataServiceConfiguration
|
|
) : base(
|
|
entity,
|
|
database,
|
|
repository,
|
|
dataServiceConfiguration
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarGraphQLTypeHelper : XBaseGraphQLTypeHelper<XWebinar, Guid>, IXWebinarGraphQLTypeHelper
|
|
{
|
|
public XWebinarGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XWebinarServiceConstants.XWebinarCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XWebinarServiceConstants.XWebinarSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarGraphQuery.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarGraphQuery : XBaseGraphQLQuery<XWebinar, Guid, XWebinarGraphType, GuidGraphType>
|
|
{
|
|
public XWebinarGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarRepository repository,
|
|
IXWebinarGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarGraphSchema : Schema
|
|
{
|
|
public XWebinarGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XWebinarGraphQuery)services.GetService(typeof(XWebinarGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarGraphType.cs
|
|
|
|
using System;
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarGraphType : XBaseGraphObjectType<XWebinar, Guid>
|
|
{
|
|
public XWebinarGraphType() : base()
|
|
{
|
|
Field(x => x.Type);
|
|
Field(x => x.Title);
|
|
Field(x => x.OwnerId);
|
|
Field(x => x.Enabled);
|
|
Field(x => x.CreatedOn);
|
|
Field(x => x.Description);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarSubscriberGraphQLTypeHelper.cs
|
|
|
|
using System;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarSubscriberGraphQLTypeHelper : XBaseGraphQLTypeHelper<XWebinarSubscriber, int>, IXWebinarSubscriberGraphQLTypeHelper
|
|
{
|
|
public XWebinarSubscriberGraphQLTypeHelper(
|
|
XDataServiceConfiguration configuration
|
|
) : base(configuration)
|
|
{ }
|
|
|
|
public override string GetInQueryCollectionName()
|
|
{
|
|
return XWebinarServiceConstants.XWebinarSubscriberCollectionName;
|
|
}
|
|
|
|
public override string GetInQuerySingleName()
|
|
{
|
|
return XWebinarServiceConstants.XWebinarSubscriberSingleName;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarSubscriberGraphQuery.cs
|
|
|
|
using GraphQL.Types;
|
|
using xDataService.Configuration;
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarSubscriberGraphQuery : XBaseGraphQLQuery<XWebinarSubscriber, int, XWebinarSubscriberGraphType, IntGraphType>
|
|
{
|
|
public XWebinarSubscriberGraphQuery(
|
|
XDataServiceConfiguration configuration,
|
|
IXWebinarSubscriberRepository repository,
|
|
IXWebinarSubscriberGraphQLTypeHelper helper
|
|
) : base(
|
|
configuration,
|
|
repository,
|
|
helper
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarSubscriberGraphSchema.cs
|
|
|
|
using System;
|
|
using GraphQL.Types;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarSubscriberGraphSchema : Schema
|
|
{
|
|
public XWebinarSubscriberGraphSchema(IServiceProvider services) : base(services)
|
|
{
|
|
Query = (XWebinarSubscriberGraphQuery)services.GetService(typeof(XWebinarSubscriberGraphQuery));
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\GraphQL\XWebinarSubscriberGraphType.cs
|
|
|
|
using xDataService.GraphQL;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers.GraphQL
|
|
{
|
|
public class XWebinarSubscriberGraphType : XBaseGraphObjectType<XWebinarSubscriber, int>
|
|
{
|
|
public XWebinarSubscriberGraphType() : base()
|
|
{
|
|
Field(x => x.WebinarId);
|
|
Field(x => x.SubscribedOn);
|
|
Field(x => x.SubscriberId);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\XWebinarEntityRegisterar.cs
|
|
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Configurations.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers
|
|
{
|
|
public class XWebinarEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XWebinarEntityRegisterar()
|
|
: base(nameof(XWebinarEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XWebinar, Guid>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XWebinarEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xWebinarService\Providers\XWebinarSubscriberEntityRegisterar.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Providers;
|
|
using xWebinarService.Configurations.Entities;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers
|
|
{
|
|
public class XWebinarSubscriberEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
|
|
{
|
|
public XWebinarSubscriberEntityRegisterar()
|
|
: base(nameof(XWebinarSubscriberEntityRegisterar))
|
|
{
|
|
//
|
|
// Add Entity ...
|
|
AddEntity<XWebinarSubscriber, int>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configure Entities ...
|
|
/// </summary>
|
|
/// <param name="modelBuilder"></param>
|
|
public override void ConfigureEntities(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
// Configure Entity Using Provided ...
|
|
modelBuilder
|
|
.ApplyConfigurationsFromAssembly(typeof(XWebinarSubscriberEntityConfiguration).Assembly);
|
|
|
|
//
|
|
base.ConfigureEntities(modelBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Constants\XAiApiConstants.cs
|
|
|
|
namespace xAiApi.Constants
|
|
{
|
|
public struct XAiApiConstants
|
|
{
|
|
//
|
|
// Database Descriptor ...
|
|
public const string XAiApiDbIdentifier = "xAiApiDb";
|
|
public const string XAiApiMigrationsAssemblyIdentifier = "xAiApi";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Controllers\StartupController.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Controllers;
|
|
using xCommons.Providers;
|
|
|
|
namespace xAiApi.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Runing when application start ...
|
|
/// </summary>
|
|
[Route("")]
|
|
[AllowAnonymous]
|
|
public class StartupController : XBaseController
|
|
{
|
|
|
|
public StartupController(
|
|
ILogger<StartupController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Show Configured Welcome Message
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("")]
|
|
[AllowAnonymous]
|
|
public virtual ActionResult<string> Index()
|
|
{
|
|
//
|
|
var controllerName = GetControllerName();
|
|
var message = $"{AppConfiguration.WelcomeMessage}";
|
|
|
|
//
|
|
return Ok(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Database\XAiApiDatabaseDescriptor.cs
|
|
|
|
using xAiApi.Constants;
|
|
using xDataService.Interfaces;
|
|
using xDataService.Models;
|
|
|
|
namespace xAiApi.Database
|
|
{
|
|
/// <summary>
|
|
/// Ai Api Database Descriptor ...
|
|
/// </summary>
|
|
public class XAiApiDatabaseDescriptor : XDatabaseDescriptor<XAiApiDbContext>, IXDatabaseDescriptor<XAiApiDbContext>
|
|
{
|
|
public XAiApiDatabaseDescriptor() : base(
|
|
name: XAiApiConstants.XAiApiDbIdentifier,
|
|
repositories: []
|
|
)
|
|
{
|
|
OptionsBuilder = b => b.MigrationsAssembly(XAiApiConstants.XAiApiMigrationsAssemblyIdentifier);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Database\XAiApiDbContext.cs
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xAiApi.Constants;
|
|
using xAiModels.Providers;
|
|
using xDataService.Configuration;
|
|
using xDataService.Db;
|
|
using xDataService.Providers;
|
|
using xFileService.Providers;
|
|
using xStringService.Providers;
|
|
using xTagService.Providers;
|
|
|
|
namespace xAiApi.Database
|
|
{
|
|
/// <summary>
|
|
/// Db Context of AiApi ...
|
|
/// </summary>
|
|
public class XAiApiDbContext : XDbContext
|
|
{
|
|
//
|
|
#region DbSets ...
|
|
#endregion
|
|
|
|
//
|
|
#region Navigation Property Entities ...
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XAiApiDbContext(
|
|
DbContextOptions options,
|
|
XDataServiceConfiguration config,
|
|
XEntityRegisterarHandlerService dynamicEntityHandlers
|
|
) : base(
|
|
config: config,
|
|
options: options,
|
|
database: XAiApiConstants.XAiApiDbIdentifier,
|
|
dynamicEntityHandlers: dynamicEntityHandlers,
|
|
dynamicEntityRegisterarsNames: [
|
|
nameof(XTagEntityRegisterar),
|
|
nameof(XFileEntityRegisterar),
|
|
nameof(XStringEntityRegisterar),
|
|
nameof(XAiMessageEntityRegisterar),
|
|
nameof(XAiProjectEntityRegisterar),
|
|
nameof(XAiConversationEntityRegisterar),
|
|
]
|
|
)
|
|
{ }
|
|
#endregion
|
|
|
|
//
|
|
#region Overrides ...
|
|
//
|
|
public override void OnXModelCreating(ModelBuilder modelBuilder)
|
|
{ }
|
|
|
|
//
|
|
public override void OnXConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{ }
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Extensions\XProgramExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Authorization;
|
|
using xCommons.Extensions;
|
|
using xIdentityHelper;
|
|
|
|
namespace xAiApi.Extensions
|
|
{
|
|
public static class XProgramExtensions
|
|
{
|
|
/// <summary>
|
|
/// Register Authorization Policies
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="policies"></param>
|
|
public static void AddXAuthorization(
|
|
this IServiceCollection services,
|
|
IDictionary<string, AuthorizationPolicy> policies = null
|
|
)
|
|
{
|
|
//
|
|
services.AddAuthorization(options =>
|
|
{
|
|
//
|
|
if (!policies.IsNull())
|
|
{
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = policies.GetEnumerator())
|
|
{
|
|
while (policiesEnumerator.MoveNext())
|
|
{
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies();
|
|
if (!xPolicies.IsNull())
|
|
{
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = xPolicies.GetEnumerator())
|
|
{
|
|
while (policiesEnumerator.MoveNext())
|
|
{
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
//
|
|
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Forward Headers Options for resolving behind a proxy issues ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static void UseXForwardOptions(this IApplicationBuilder source)
|
|
{
|
|
//
|
|
var forwardOptions = new ForwardedHeadersOptions
|
|
{
|
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
|
|
RequireHeaderSymmetry = false
|
|
};
|
|
|
|
//
|
|
forwardOptions.KnownNetworks.Clear();
|
|
forwardOptions.KnownProxies.Clear();
|
|
|
|
//
|
|
// ref: https://github.com/aspnet/Docs/issues/2384
|
|
source.UseForwardedHeaders(forwardOptions);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Interfaces\IXAIApiServiceBase.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.AI;
|
|
|
|
namespace xAiApi.Interfaces
|
|
{
|
|
/// <summary>
|
|
/// Describe a Base Service Actions of any Ai Based Services ...
|
|
/// </summary>
|
|
public interface IAIServiceBase : IDisposable
|
|
{
|
|
/// <summary>
|
|
/// Base Method for Communicate with LLM ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
Task<string> AskAsync(
|
|
string prompt,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Base Method for Communicate with LLM ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
IAsyncEnumerable<string> AskAsEnumerable(
|
|
string prompt,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
|
|
/// <summary>
|
|
/// Get LLM Client instance for Communicating with LLM ...
|
|
/// </summary>
|
|
/// <param name="llm"></param>
|
|
/// <returns></returns>
|
|
IChatClient GetClient(string llm = null);
|
|
|
|
/// <summary>
|
|
/// Create Custom HttpClient for Communicating with LLM API ...
|
|
/// </summary>
|
|
/// <param name="url"></param>
|
|
/// <returns></returns>
|
|
HttpClient GetHttpClient(string url = null);
|
|
|
|
/// <summary>
|
|
/// Prepare a Message History List for LLM Communication based on Prompt ...
|
|
/// </summary>
|
|
/// <param name="prompt"></param>
|
|
/// <param name="forcePrompt"></param>
|
|
/// <returns></returns>
|
|
IList<ChatMessage> GetHistory(
|
|
string prompt = null,
|
|
bool forcePrompt = true
|
|
);
|
|
|
|
/// <summary>
|
|
/// Prepare a Message History List for LLM Communication based on Prompt ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="forceMessage"></param>
|
|
/// <returns></returns>
|
|
IList<ChatMessage> GetHistory(
|
|
ChatMessage message = null,
|
|
bool forceMessage = true
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Program.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace xAiApi
|
|
{
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
CreateHostBuilder(args).Build().Run();
|
|
}
|
|
|
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
Host.CreateDefaultBuilder(args)
|
|
.ConfigureWebHostDefaults(webBuilder =>
|
|
{
|
|
webBuilder.UseStartup<Startup>();
|
|
});
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xAiApi\Startup.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using xTagService.DI;
|
|
using System.Net.Http;
|
|
using xAiApi.Database;
|
|
using xHttpService.DI;
|
|
using xPushService.DI;
|
|
using xFileService.DI;
|
|
using xDataService.DI;
|
|
using Newtonsoft.Json;
|
|
using System.Reflection;
|
|
using xAiApi.Extensions;
|
|
using xStringService.DI;
|
|
using xStorageService.DI;
|
|
using xIdentityService.DI;
|
|
using xDataService.Models;
|
|
using xCommons.Extensions;
|
|
using xCommons.Configurations;
|
|
using System.Collections.Generic;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Newtonsoft.Json.Serialization;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using IdentityModel.AspNetCore.OAuth2Introspection;
|
|
using xPushService.Helpers;
|
|
|
|
namespace xAiApi
|
|
{
|
|
public class Startup
|
|
{
|
|
//
|
|
#region Props ...
|
|
public IConfiguration Configuration { get; }
|
|
private readonly List<XDatabaseDescriptor> databases;
|
|
private readonly XAiApiDatabaseDescriptor apiDatabaseDescriptor;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor(s) ...
|
|
public Startup(IConfiguration configuration)
|
|
{
|
|
//
|
|
Configuration = configuration;
|
|
|
|
//
|
|
// Create an Api Descriptor Class Instance ...
|
|
apiDatabaseDescriptor = new XAiApiDatabaseDescriptor();
|
|
databases = new List<XDatabaseDescriptor>
|
|
{
|
|
apiDatabaseDescriptor
|
|
};
|
|
}
|
|
#endregion
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
//
|
|
// Register Validation Provider and all XCommons Module Services ...
|
|
services.AddXCommons();
|
|
|
|
//
|
|
// Register App Configuration ...
|
|
services.AddXAppConfiguration(Configuration);
|
|
var appConfiguration = services.GetRegisteredService<XAppConfiguration>();
|
|
|
|
//
|
|
// Register Allowed Origins ...
|
|
services.AddXCors(appConfiguration.AllowedOrigins);
|
|
|
|
//
|
|
// Register Swagger ...
|
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
|
services.AddXSwagger(Configuration, xmlFilePath: xmlPath);
|
|
|
|
//
|
|
// Register HttpService ...
|
|
services.AddXHttpService(Configuration);
|
|
|
|
//
|
|
// Add Api V1 Versioning ...
|
|
services.AddXApiV1Versioning();
|
|
|
|
//
|
|
// OAuthIntrospectin Http Client Handler ...
|
|
// this is for handling SSLErrors ...
|
|
services.AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName)
|
|
.ConfigurePrimaryHttpMessageHandler(() =>
|
|
{
|
|
return new HttpClientHandler
|
|
{
|
|
ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
|
|
};
|
|
});
|
|
|
|
//
|
|
// Register Authorizations ...
|
|
services.AddXAuthorization();
|
|
|
|
//
|
|
services.AddControllers()
|
|
.AddNewtonsoftJson(x =>
|
|
{
|
|
x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
|
x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
|
});
|
|
|
|
//
|
|
var lifeTime = ServiceLifetime.Scoped;
|
|
var repositoryType = xDataService.Constants.XRepositoryType.EF;
|
|
|
|
//
|
|
// Register XIdentity Service ...
|
|
services.AddXIdentityService(
|
|
lifeTime: lifeTime,
|
|
configuration: Configuration
|
|
);
|
|
|
|
//
|
|
// Storage Service ...
|
|
services.AddXStorageService(Configuration);
|
|
|
|
//
|
|
// Push Service ...
|
|
services.AddXPushService(
|
|
lifeTime: lifeTime,
|
|
config: Configuration
|
|
);
|
|
|
|
//
|
|
// Preparing DataBases ...
|
|
if (databases.HasChild())
|
|
{
|
|
//
|
|
databases
|
|
.ToList()
|
|
.ForEach(database =>
|
|
{
|
|
//
|
|
// Register DataBase ...
|
|
services.AddXDatabase(
|
|
lifeTime: lifeTime,
|
|
descriptor: database,
|
|
configuration: Configuration
|
|
);
|
|
});
|
|
}
|
|
|
|
//
|
|
// Register String Service ...
|
|
services.AddXStringService<XAiApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register Tag Service ...
|
|
services.AddXTagService<XAiApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
|
|
//
|
|
// Register File Service ...
|
|
services.AddXFileService<XAiApiDbContext>(
|
|
lifeTime: lifeTime,
|
|
repositoryType: repositoryType
|
|
);
|
|
}
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
{
|
|
//
|
|
// Configure the HTTP request pipeline.
|
|
var isDevelopmentEnvironment = false;
|
|
if (env.IsDevelopment())
|
|
{
|
|
isDevelopmentEnvironment = true;
|
|
app.UseDeveloperExceptionPage();
|
|
}
|
|
|
|
//
|
|
// Use Swagger Middleware ...
|
|
app.UseXSwagger();
|
|
|
|
//
|
|
// Force Https Redirection ...
|
|
app.UseHttpsRedirection();
|
|
|
|
//
|
|
// Using Cors ...
|
|
app.UseXCors();
|
|
|
|
//
|
|
// Using Routing ...
|
|
app.UseRouting();
|
|
|
|
//
|
|
// Use xIdentityService ...
|
|
app.UseXIdentityService();
|
|
|
|
//
|
|
// Use Authorization ...
|
|
app.UseAuthorization();
|
|
|
|
//
|
|
app.UseEndpoints(endpoints =>
|
|
{
|
|
endpoints.MapControllers();
|
|
});
|
|
|
|
//
|
|
// Use Storage Service ...
|
|
app.UseXStorageService();
|
|
|
|
//
|
|
// Use PushService ...
|
|
var pushHelper = new XPushServiceHelper();
|
|
app.UseXPushService(pushHelper);
|
|
|
|
//
|
|
// Using DataBase ...
|
|
if (databases.HasChild())
|
|
{
|
|
//
|
|
databases
|
|
.ToList()
|
|
.ForEach(database =>
|
|
{
|
|
//
|
|
app.UseXDatabase(
|
|
descriptor: database,
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
});
|
|
}
|
|
|
|
//
|
|
// Using String Service ...
|
|
app.UseXStringService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using XTag Service ...
|
|
app.UseXTagService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
|
|
//
|
|
// Using File Service ...
|
|
app.UseXFileService(
|
|
isDevelopmentEnvironment: isDevelopmentEnvironment
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Admin.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xApi.Controllers {
|
|
public partial class AccountController {
|
|
//
|
|
#region Admin Actions ...
|
|
/// <summary>
|
|
/// Ban Specific Users
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of banned users identifiers</returns>
|
|
[RequireXPowered]
|
|
[HttpPost ("Ban")]
|
|
[Authorize (Policy = XPolicies.EnabledAdmin)]
|
|
public async Task<ActionResult<IEnumerable<string>>> Ban (
|
|
[FromBody] XUserNameIdRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotZeroChilds (model.Ids)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.Ban (
|
|
tokens,
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok (result)
|
|
.ToDynamicObject ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// UnBann Specific Users
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of unbanned users identifiers</returns>
|
|
[RequireXPowered]
|
|
[HttpPost ("UnBan")]
|
|
[Authorize (Policy = XPolicies.EnabledAdmin)]
|
|
public async Task<ActionResult<IEnumerable<string>>> UnBan (
|
|
[FromBody] XUserNameIdRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotZeroChilds (model.Ids)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.UnBan (
|
|
tokens,
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specific User is Banned or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns>a boolean value which represent user banned or not</returns>
|
|
[RequireXPowered]
|
|
[HttpGet ("IsBanned/{userSelectByParam?}")]
|
|
[Authorize (Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize (Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<bool>> IsBanned (
|
|
[FromRoute] string userSelectByParam = null
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty ()) {
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.IsBanned (
|
|
tokens,
|
|
userSelectByParam
|
|
);
|
|
|
|
//
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Authentication.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using static xIdentityHelper.XApiScopeHelper;
|
|
|
|
namespace xApi.Controllers {
|
|
public partial class AccountController {
|
|
//
|
|
#region Authentication Actions ...
|
|
/// <summary>
|
|
/// Retrieve OAuth Discovery Document
|
|
/// </summary>
|
|
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet ("DiscoveryDocument")]
|
|
public async Task<ActionResult<DiscoveryDocumentResponse>> GetDiscoveryDocument () {
|
|
//
|
|
try {
|
|
//
|
|
var result = await identityProvider
|
|
.RequestDiscoveryDocument ();
|
|
|
|
//
|
|
// Ceck Response Result ...
|
|
if (result.IsError) {
|
|
XException.InvalidConfiguration.Throw ();
|
|
}
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request AccessToken for Specific XApiScope
|
|
/// </summary>
|
|
/// <param name="scope">a member of <see>XApiScope</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestScopeAccessToken")]
|
|
public async Task<ActionResult<XTokenResponse>> RequestScopeAccessToken (
|
|
[FromHeader] XApiScope scope
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
var scopeName = string.Empty;
|
|
try {
|
|
scopeName = scope.GetStringValue ();
|
|
} catch { }
|
|
ValidationProvider.NotEmpty (scopeName);
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.RequestScopeAccessToken (scopeName);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate User
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "password": "",
|
|
/// "userSelectBy": "",
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("Authenticate")]
|
|
public async Task<ActionResult<XTokenResponse>> Authenticate (
|
|
[FromBody] XLoginRequest model
|
|
) {
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.Authenticate (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate User
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "language": "fa-IR"
|
|
/// "password": "",
|
|
/// "userSelectBy": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">User Login Required Info, an instance of <see>XLoginRequest</see></param>
|
|
/// <returns>an instance of <see>XLoginResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("Login")]
|
|
public async Task<ActionResult<XLoginResponse>> Login (
|
|
[FromBody] XLoginRequest model
|
|
) {
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
model,
|
|
model.Device)
|
|
.AddNotEmpty (
|
|
model.Language,
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.Login (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logout User
|
|
/// </summary>
|
|
[RequireXPowered]
|
|
[HttpPost ("Logout")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
public async Task<ActionResult> Logout () {
|
|
try {
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
await identityProvider
|
|
.Logout (tokens);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Expired Tokens
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// in addition to AccessToken, you had to pass RefreshToken due to Headers
|
|
/// </remarks>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RefreshTokens")]
|
|
public async Task<ActionResult<XTokenResponse>> RefreshTokens () {
|
|
//
|
|
try {
|
|
//
|
|
// Retrieve Toke Response ...
|
|
var model = await RetrieveTokensAsXTokenResponse ();
|
|
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (
|
|
model.AccessToken,
|
|
model.RefreshToken)
|
|
.ValidateGroup ();
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.RefreshTokens (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Revision Checksum
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <returns></returns>
|
|
[HttpPost ("Validate")]
|
|
[Authorize (Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<bool>> Validate (
|
|
[FromBody] XValidateRevisionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (model)
|
|
.AddNotEmpty (model.Revision)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = tokens.ValidateRevisionChecksum (
|
|
model.Revision,
|
|
identityProvider.RevisionSecretKey
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Password Actions ...
|
|
/// <summary>
|
|
/// Change a User's Password ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - NewPassword: user's new password to change.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": ""
|
|
/// "newPassword": "",
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[RequireXPowered]
|
|
[HttpPost ("ChangePassword")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
[Authorize (Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult> ChangePassword (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotNull (
|
|
model,
|
|
model.Device
|
|
)
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.NewPassword,
|
|
model.ReturnUrl
|
|
)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get User Select By ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
forceNotNull : false
|
|
);
|
|
if (userSelectByParam.IsNullOrEmpty ()) {
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
await identityProvider
|
|
.ChangePassword (tokens, model);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Friendship.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
using System.Linq;
|
|
using xExceptions.Constants;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Friendship Actions ...
|
|
/// <summary>
|
|
/// Follow a User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Friendship/{destUser}/Follow")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Follow(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.Follow(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cancel Following Request
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/Cancel")]
|
|
public async Task<ActionResult<bool>> Cancel(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.Cancel(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow a Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/UnFollowFollower")]
|
|
public async Task<ActionResult> UnFollowFollower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
await identityProvider
|
|
.UnFollowFollower(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow Following
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/UnFollowFollowing")]
|
|
public async Task<ActionResult> UnFollowFollowing(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
await identityProvider
|
|
.UnFollowFollowing(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Block a Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[HttpPost("Friendship/{destUser}/Block")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Block(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.Block(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unblock a Blocked User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[HttpPost("Friendship/{destUser}/UnBlock")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> UnBlock(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.UnBlock(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accept a Following Request
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/AcceptRequest")]
|
|
public async Task<ActionResult<XFriendshipFollower>> AcceptRequest(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.AcceptRequest(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reject a Following Request
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/RejectRequest")]
|
|
public async Task<ActionResult<XFriendshipFollower>> RejectRequest(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.RejectRequest(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship Getters ...
|
|
|
|
/// <summary>
|
|
/// Get Friendship Info Model between Specific User and Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/FriendshipInfo")]
|
|
public async Task<ActionResult<XFriendshipInfoDto>> FriendshipInfo(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFriendshipInfo(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User IsFollower of Requested User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/IsFollower")]
|
|
public async Task<ActionResult<bool>> IsFollower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.IsFollower(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Follower State of a User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/FollowerState")]
|
|
public async Task<ActionResult<XFriendshipState>> FollowerState(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowerState(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/Follower")]
|
|
public async Task<ActionResult<XFriendshipFollower>> Follower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollower(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followers List Of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
[HttpGet("Friendship/Followers")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> Followers()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowers(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followers List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
[HttpGet("Friendship/AllFollowers")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> AllFollowers()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetAllFollowers(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followers List Includes Blocked, Requested and etc
|
|
/// of Current User based On Query Model ...
|
|
/// </summary>
|
|
/// <returns>a Query Result of <see>XFriendDto</see></returns>
|
|
[HttpGet("Friendship/QueryFollowers")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowers(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Normalizing Dest User ...
|
|
var userInfo = await GetUserInfo();
|
|
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
|
|
if (destUser.IsNullOrEmpty())
|
|
{
|
|
destUser = userInfo.UserName;
|
|
}
|
|
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
|
|
if (!isDestUserValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.QueryFollowers(
|
|
query: query,
|
|
tokens: tokens,
|
|
destUser: destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is in Followings of Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/IsFollowing")]
|
|
public async Task<ActionResult<bool>> IsFollowing(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.IsFollowing(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Following State Relation between Specific User
|
|
/// and Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/FollowingState")]
|
|
public async Task<ActionResult<XFriendshipState>> FollowingState(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowingState(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Following Model
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/Following")]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Following(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowing(
|
|
tokens,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followings of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
[HttpGet("Friendship/Followings")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> Followings()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowings(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Following List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
[HttpGet("Friendship/AllFollowings")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> AllFollowings()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetAllFollowings(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Following UserName's List of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[HttpGet("Friendship/FollowingsList")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> FollowingsList()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowingList(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Followers UserName's List of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[HttpGet("Friendship/FollowersList")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> FollowersList()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetFollowersList(tokens);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followings List Includes Blocked, Requested and etc
|
|
/// of Current User based On Query Model ...
|
|
/// </summary>
|
|
/// <returns>a Query Result of <see>XFriendDto</see></returns>
|
|
[HttpGet("Friendship/QueryFollowings")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowings(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Normalizing Dest User ...
|
|
var userInfo = await GetUserInfo();
|
|
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
|
|
if (destUser.IsNullOrEmpty())
|
|
{
|
|
destUser = userInfo.UserName;
|
|
}
|
|
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
|
|
if (!isDestUserValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.QueryFollowings(
|
|
query: query,
|
|
tokens: tokens,
|
|
destUser: destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Open.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xModels.Dtos;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
#region Open Actions ...
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("GetUserInfo")]
|
|
public async Task<ActionResult<string>> GetUserInfo(
|
|
[FromHeader] string token,
|
|
[FromQuery] string request
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(token)
|
|
.AddNotEmpty(request)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await identityProvider.GetUserInfo(
|
|
token: token,
|
|
request: request
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("GetUserInfoByDevice")]
|
|
public async Task<ActionResult<string>> GetUserInfoByDevice(
|
|
[FromQuery] string userSelectByParam,
|
|
[FromBody] XDeviceDto device
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(userSelectByParam)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await identityProvider.GetUserInfo(
|
|
userSelectByParam: userSelectByParam,
|
|
device: device
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Profile.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Retrieve Actions ...
|
|
/// <summary>
|
|
/// Retrieve User Names based on UserIds
|
|
/// </summary>
|
|
/// <param name="ids">a comma seperated list of UserIds</param>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Profile/{ids}/GetNames")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> GetNames(
|
|
[FromRoute] string ids
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(ids);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.GetUserNames(
|
|
tokens,
|
|
ids
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// get user ids and retrieve corresponding user names
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
|
|
/// <returns>a collection of <see>XUserNameIdResponse</see> instance</returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/GetNameIds")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XUserNameIdResponse>>> GetNameIds(
|
|
[FromBody] XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.GetUserNameIds(
|
|
tokens,
|
|
model
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Profile Object of Specific User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[HttpGet("Profile/{userSelectByParam?}")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> GetProfile(
|
|
[FromRoute] string userSelectByParam = ""
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.GetUserProfile(
|
|
tokens,
|
|
userSelectByParam
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Users
|
|
/// for specifiy users role for query user 'role: string' and 'forceRole: boolean' in header
|
|
/// </summary>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Profile/Query")]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize(Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryProfiles(
|
|
[FromQuery] XQuery query, [FromHeader] string role, [FromHeader] bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = new XQueryResult<XUserProfileDto>();
|
|
if (role.IsNullOrEmpty())
|
|
{
|
|
//
|
|
result = await identityProvider.QueryUsers(
|
|
tokens,
|
|
query
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await identityProvider.QueryInRoleUsers(
|
|
tokens,
|
|
role,
|
|
query,
|
|
forceRole
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[HttpGet("Profile/Avatars/Query/{userSelectByParam?}")]
|
|
public async Task<ActionResult<XQueryResult<XProfileImageDto>>> QueryAvatars(
|
|
[FromQuery] XQuery query, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.QueryAvatars(
|
|
tokens,
|
|
userSelectByParam,
|
|
query
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update Actions ...
|
|
/// <summary>
|
|
/// Update User Profile based on <see>XProfileUpdateRequest</see> (FirstName/LastName/DateOfBirth)
|
|
/// </summary>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Profile/Update/{userSelectByParam?}")]
|
|
public async Task<ActionResult<XUserProfileDto>> UpdateProfile(
|
|
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.ProfileUpdateAsync(
|
|
tokens,
|
|
userSelectByParam,
|
|
model
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a User Profile based on <see>XProfileUpdateRequest</see> Full
|
|
/// </summary>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/{userSelectByParam?}")]
|
|
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
|
|
public async Task<ActionResult<XUserProfileDto>> FullUpdateProfile(
|
|
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.FullProfileUpdateAsync(
|
|
tokens,
|
|
userSelectByParam,
|
|
model
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Avatar Actions ...
|
|
/// <summary>
|
|
/// Add a New Profile Image
|
|
/// </summary>
|
|
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatar")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> AddAvatar(
|
|
[FromForm] IFormFile file
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(file);
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.AddAvatar(
|
|
tokens,
|
|
file
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a New Collection of Profile Images
|
|
/// </summary>
|
|
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatars")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> AddAvatars(
|
|
[FromForm] IFormFileCollection files
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotZeroChilds(files);
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.AddAvatars(
|
|
tokens,
|
|
files
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// set Specified Profile Image as Avatar
|
|
/// </summary>
|
|
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatars/{id:int}/Set")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> SetAvatar(
|
|
[FromRoute] int id
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.SetAvatar(
|
|
tokens,
|
|
id
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Profile Images
|
|
/// </summary>
|
|
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[HttpDelete("Profile/Avatars/{ids}")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> RemoveAvatars(
|
|
[FromRoute] string ids
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(ids);
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider
|
|
.RemoveAvatars(
|
|
tokens,
|
|
ids
|
|
);
|
|
|
|
//
|
|
// Prepare Push Message ...
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Registration.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xApi.Controllers {
|
|
public partial class AccountController {
|
|
//
|
|
#region Registration ...
|
|
/// <summary>
|
|
/// Check a UserName is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="userName">an string value which represent desired username</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet ("CanRegisterUserName/{userName?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterUserName (
|
|
[FromRoute] string userName
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty (userName);
|
|
|
|
//
|
|
// Validate Type ...
|
|
var type = userName.GetUserSelectByType ();
|
|
if (type != XUserSelectBy.Username) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.CanRegister (userName);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Mobile Number is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="mobileNumber">an string value which represent desired mobile number</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet ("CanRegisterMobileNumber/{mobileNumber?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterMobileNumber (
|
|
[FromRoute] string mobileNumber
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty (mobileNumber);
|
|
|
|
//
|
|
// Validate Type ...
|
|
var type = mobileNumber.GetUserSelectByType ();
|
|
if (type != XUserSelectBy.MobileNumber) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.CanRegister (mobileNumber);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Email Address is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="email">an string value which represent desired email address</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet ("CanRegisterEmail/{email?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterEmail (
|
|
[FromRoute] string email
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty (email);
|
|
|
|
//
|
|
// Validate Type ...
|
|
var type = email.GetUserSelectByType ();
|
|
if (type != XUserSelectBy.Email) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.CanRegister (email);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invite a User to Register on Dashboard
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Email: which email address is going to invite.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Registration URL.
|
|
/// notice in this step you had to provide all this informations as FormData
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "email": "",
|
|
/// "returnUrl": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost ("InviteUser")]
|
|
[Authorize (Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize (Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<XActionResponse>> InviteUser (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
|
|
//
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Email,
|
|
model.ReturnUrl)
|
|
.AddEmailAddress (model.Email)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.InviteUser (
|
|
tokens,
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recieve some Basic Informations and Start Registration Proccess
|
|
/// if they Valid
|
|
///
|
|
/// Registration Proccess Starts with Invoking this Action
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - FirstName: user's FirstName.
|
|
/// - LastName: user's LastName.
|
|
/// - DateOfBirth: user's dob date.
|
|
/// - MobileNumber: user's MobileNumber optional.
|
|
/// - Email: user's Email optional.
|
|
/// - ActionToken: user's requested action token for this action (if user invited).
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "firstName": "",
|
|
/// "lastName": "",
|
|
/// "dateOfBirth": "",
|
|
/// "email": "",
|
|
/// "mobileNumber": "",
|
|
/// "actionToken": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestRegistration")]
|
|
public async Task<ActionResult<XActionResponse>> RequestRegistration (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.FirstName,
|
|
model.LastName)
|
|
.AddNotNull (
|
|
model.Device,
|
|
model.DateOfBirth)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.RequestRegistration (
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add User Account Informations
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - UserName: user name.
|
|
/// - Password: assigne password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userName": "",
|
|
/// "password": "",
|
|
/// "actionToken": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("AddAccountInfo")]
|
|
public async Task<ActionResult<XActionResponse>> AddAccountInfo (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.UserName,
|
|
model.Password)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.AddAccountInfo (
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload and Attach a Profile Image for User. this is an Optional Step
|
|
/// </summary>
|
|
/// <param name="actionToken">user's requested action token</param>
|
|
/// <param name="file">an instance of <see>IFormFile</see> for user's Avatar</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("AttachProfileImage")]
|
|
public async Task<ActionResult<XActionResponse>> AttachProfileImage (
|
|
[FromForm] string actionToken, [FromForm] IFormFile file
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (actionToken)
|
|
.AddNotNull (file)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var result = await identityProvider
|
|
.AttachProfileImage (
|
|
actionToken,
|
|
file
|
|
);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finish Registrationn Proccess
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - a proper User Identifier such as: (UserId, UserName, Email or MobileNumber).
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Password: assigne password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userName": "",
|
|
/// "password": "",
|
|
/// "returnUrl": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("FinishRegistration")]
|
|
public async Task<ActionResult> FinishRegistration (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
var userSelectByParam = identityProvider
|
|
.GetUserSelectByParam (model);
|
|
ValidationProvider
|
|
.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
// Get Request ...
|
|
await identityProvider
|
|
.FinishRegistration (model);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User is Confirmed Email or not
|
|
/// </summary>
|
|
/// <returns>a boolean value</returns>
|
|
[RequireXPowered]
|
|
[HttpGet ("IsConfirmedEmail")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
public async Task<ActionResult<bool>> IsConfirmedEmail () {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Get Result ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.IsConfirmedEmail (
|
|
tokens,
|
|
User.Identity.Name
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User is Confirmed Mobile or not
|
|
/// </summary>
|
|
/// <returns>a boolean value</returns>
|
|
[RequireXPowered]
|
|
[HttpGet ("IsConfirmedMobile")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
public async Task<ActionResult<bool>> IsConfirmedMobile () {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Get Result ...
|
|
var tokens = await RetrieveTokensAsXTokenResponse ();
|
|
var result = await identityProvider
|
|
.IsConfirmedMobile (
|
|
tokens,
|
|
User.Identity.Name
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok (result);
|
|
} catch (Exception ex) {
|
|
//
|
|
var result = GetExceptionActionResult (ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Registration Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - a UserSelectedBy identifier which represet User.
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Confirm Registration URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userId": ""
|
|
/// "password": "",
|
|
/// "returnUrl": "http://localhost/confirm",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestConfirmRegistration")]
|
|
public async Task<ActionResult> RequestConfirmRegistration (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = model.GetUserSelectByParam ();
|
|
ValidationProvider.NotEmpty (userSelectByParam);
|
|
|
|
//
|
|
await identityProvider
|
|
.RequestConfirmRegistration (model);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Registration
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("ConfirmRegistration")]
|
|
public async Task<ActionResult> ConfirmRegistration (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.ReturnUrl
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
await identityProvider
|
|
.ConfirmRegistration (model);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request For Mobile Number Change/Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - MobileNumber: which phone number is going to confirm.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": "",
|
|
/// "mobileNumber": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestConfirmMobile")]
|
|
public async Task<ActionResult<XActionResponse>> RequestConfirmMobile (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Password,
|
|
model.MobileNumber)
|
|
.AddNotNull (model.Device)
|
|
.AddMobileNumber (model.MobileNumber)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.RequestConfirmMobile (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Mobile Number
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - MobileVerificationCode: a verification code which produced due Request Action.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "mobileVerificationCode": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("ConfirmMobileNumber")]
|
|
public async Task<ActionResult<XActionResponse>> ConfirmMobileNumber (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.MobileVerificationCode,
|
|
model.ActionToken
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.ConfirmMobileNumber (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request For Email Address Change/Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - Email: which email address is going to confirm.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": "",
|
|
/// "email": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestConfirmEmail")]
|
|
public async Task<ActionResult<XActionResponse>> RequestConfirmEmail (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.Email,
|
|
model.Password)
|
|
.AddNotNull (model.Device)
|
|
.AddEmailAddress (model.Email)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.RequestConfirmEmail (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Email Address
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - EmailVerificationCode: a verification code which produced due Request Action.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "emailVerificationCode": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("ConfirmEmailAddress")]
|
|
public async Task<ActionResult<XActionResponse>> ConfirmEmailAddress (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.EmailVerificationCode,
|
|
model.ActionToken
|
|
)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.ConfirmEmailAddress (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Reset Password Action
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application ResetPassword URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "returnUrl": "http://localhost/reset-password",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("RequestResetPassword")]
|
|
public async Task<ActionResult<XActionResponse>> RequestResetPassword (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.AddUrl (model.ReturnUrl)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam (
|
|
model,
|
|
excludes : new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await identityProvider
|
|
.RequestResetPassword (model);
|
|
|
|
//
|
|
return Ok (result
|
|
.ToDynamicObject ());
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset a User's Password
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - NewPassword: user's new password to change.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": "",
|
|
/// "newPassword": "",
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost ("ResetPassword")]
|
|
public async Task<ActionResult> ResetPassword (
|
|
[FromBody] XActionRequest model
|
|
) {
|
|
//
|
|
// Do Action ...
|
|
try {
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid) {
|
|
XException.InvalidArgs.Throw ();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder ()
|
|
.AddNotEmpty (
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.NewPassword,
|
|
model.ReturnUrl)
|
|
.AddNotNull (model.Device)
|
|
.ValidateGroupAsync ();
|
|
|
|
//
|
|
// Get Request ...
|
|
await identityProvider
|
|
.ResetPassword (model);
|
|
|
|
//
|
|
return Ok ();
|
|
} catch (Exception ex) {
|
|
//
|
|
var exResult = GetExceptionActionResult (ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\Account\AccountController+Search.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityHelper;
|
|
using xIdentityModels.Dtos;
|
|
using xModels.Dtos;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Query Open To Search Users Profiles ...
|
|
/// Query all Users Which their Profiles is Open To Search ...
|
|
/// </summary>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpGet("OpenToSearch/Query")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryOpenToSearchProfiles(
|
|
[FromQuery] XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var tokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = await identityProvider.QueryOpenToSearchUsers(
|
|
tokens,
|
|
query
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\AccountController.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Handle all Account Related Actions ...
|
|
/// </summary>
|
|
[AllowAnonymous]
|
|
[RequireXPowered(true)]
|
|
public partial class AccountController : XBaseIdentityController
|
|
{
|
|
//
|
|
#region Props ...
|
|
private readonly IXIdentityProvider identityProvider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public AccountController(
|
|
ILogger<AccountController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
)
|
|
{
|
|
//
|
|
this.identityProvider = identityProvider;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\StartupController.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Controllers;
|
|
using xCommons.Providers;
|
|
|
|
namespace xApi.Controllers {
|
|
/// <summary>
|
|
/// Runing when application start ...
|
|
/// </summary>
|
|
[Route ("")]
|
|
[AllowAnonymous]
|
|
public class StartupController : XBaseController {
|
|
|
|
public StartupController (
|
|
ILogger<StartupController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base (
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
) { }
|
|
|
|
/// <summary>
|
|
/// Show Configured Welcome Message
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet ("")]
|
|
[AllowAnonymous]
|
|
public virtual ActionResult<string> Index () {
|
|
//
|
|
var controllerName = GetControllerName ();
|
|
var message = $"{AppConfiguration.WelcomeMessage}";
|
|
|
|
//
|
|
return Ok (message);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\TestFeaturesController.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCategoryService.Interfaces;
|
|
using xCommons.Configurations;
|
|
using xCommons.Controllers;
|
|
using xCommons.Providers;
|
|
|
|
namespace xApi.Controllers
|
|
{
|
|
[AllowAnonymous]
|
|
public class TestFeaturesController : XBaseApiController
|
|
{
|
|
private readonly IXSubCategoryTitleResourceProvider subCategoryTitleResourceProvider;
|
|
|
|
public TestFeaturesController(
|
|
ILogger<TestFeaturesController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider,
|
|
IXSubCategoryTitleResourceProvider subCategoryTitleResourceProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{
|
|
this.subCategoryTitleResourceProvider = subCategoryTitleResourceProvider;
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<ActionResult> TestFeature()
|
|
{
|
|
//
|
|
var result = await subCategoryTitleResourceProvider.GetLanguages(
|
|
identifier: "SSSSAAALLLAAAM"
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Controllers\TestIdentity.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Attributes;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIdentityHelper;
|
|
using xIdentityService.Controllers;
|
|
using xIdentityService.Interfaces;
|
|
|
|
namespace xApi.Controllers {
|
|
/// <summary>
|
|
/// Test all Authentication Policies ...
|
|
/// </summary>
|
|
[RequireXPowered (false)]
|
|
public class TestIdentity : XBaseIdentityController {
|
|
public TestIdentity (
|
|
ILogger<TestIdentity> logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityProvider identityProvider,
|
|
XValidationProvider validationProvider
|
|
) : base (
|
|
logger,
|
|
appConfiguration,
|
|
identityProvider,
|
|
validationProvider
|
|
) { }
|
|
|
|
//
|
|
#region Test Actions ...
|
|
/// <summary>
|
|
/// API Read Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet ("PassReadAccess")]
|
|
[Authorize (Policy = XPolicies.ReadAccess)]
|
|
public ActionResult<string> PassReadAccess () {
|
|
return Ok ("Read Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Write Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet ("PassWriteAccess")]
|
|
[Authorize (Policy = XPolicies.WriteAccess)]
|
|
public ActionResult<string> PassWriteAccess () {
|
|
return Ok ("Write Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Admin Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet ("PassAdminAccess")]
|
|
[Authorize (Policy = XPolicies.AdminAccess)]
|
|
public ActionResult<string> PassAdminAccess () {
|
|
return Ok ("Admin Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Manage Scop
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[HttpGet ("PassManageAccess")]
|
|
[Authorize (Policy = XPolicies.ManageAccess)]
|
|
public ActionResult<string> PassManageAccess () {
|
|
return Ok ("Manage Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Action which returns a List of Authenticated User Claims
|
|
/// </summary>
|
|
/// <returns>string message which represent current user's claims</returns>
|
|
[HttpGet ("HiClaims")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
public ActionResult<string> HiClaims () {
|
|
//
|
|
var result = new {
|
|
name = User.Identity.Name,
|
|
claims = User.Claims.Select (c => new {
|
|
c.Type, c.Value
|
|
})
|
|
};
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiUser")]
|
|
[Authorize (Policy = XPolicies.User)]
|
|
public ActionResult<string> HiUser () {
|
|
//
|
|
var result = $"Hi User: {User.Identity.Name} ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiEnabledUser")]
|
|
[Authorize (Policy = XPolicies.EnabledUser)]
|
|
public ActionResult<string> HiEnabledUser () {
|
|
//
|
|
var result = $"Hi User: {User.Identity.Name} is Enabled ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiAgent")]
|
|
[Authorize (Policy = XPolicies.Agent)]
|
|
public ActionResult<string> HiAgent () {
|
|
//
|
|
var result = $"Hi Agent: {User.Identity.Name} ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiEnabledAgent")]
|
|
[Authorize (Policy = XPolicies.EnabledAgent)]
|
|
public ActionResult<string> HiEnabledAgent () {
|
|
//
|
|
var result = $"Hi Agent: {User.Identity.Name} is Enabled ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiAdmin")]
|
|
[Authorize (Policy = XPolicies.Admin)]
|
|
public ActionResult<string> HiAdmin () {
|
|
//
|
|
var result = $"Hi Admin: {User.Identity.Name} ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[HttpGet ("HiEnabledAdmin")]
|
|
[Authorize (Policy = XPolicies.EnabledAdmin)]
|
|
public ActionResult<string> HiEnabledAdmin () {
|
|
//
|
|
var result = $"Hi Admin: {User.Identity.Name} is Enabled ...";
|
|
|
|
//
|
|
return Ok (result);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Extensions\XStartupExtensions.cs
|
|
|
|
using System.Collections.Generic;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xIdentityHelper;
|
|
using xCommons.Authorization;
|
|
using xCommons.Extensions;
|
|
|
|
namespace xApi.Extensions {
|
|
public static class XStartupExtensions {
|
|
/// <summary>
|
|
/// Register Authorization Policies
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="policies"></param>
|
|
public static void AddXAuthorization (
|
|
this IServiceCollection services,
|
|
IDictionary<string, AuthorizationPolicy> policies = null
|
|
) {
|
|
//
|
|
services.AddAuthorization (options => {
|
|
//
|
|
if (!policies.IsNull ()) {
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = policies.GetEnumerator ()) {
|
|
while (policiesEnumerator.MoveNext ()) {
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy (policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies ();
|
|
if (!xPolicies.IsNull ()) {
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = xPolicies.GetEnumerator ()) {
|
|
while (policiesEnumerator.MoveNext ()) {
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy (policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
//
|
|
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Forward Headers Options for resolving behind a proxy issues ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static void UseXForwardOptions (this IApplicationBuilder source) {
|
|
//
|
|
var forwardOptions = new ForwardedHeadersOptions {
|
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
|
|
RequireHeaderSymmetry = false
|
|
};
|
|
|
|
//
|
|
forwardOptions.KnownNetworks.Clear ();
|
|
forwardOptions.KnownProxies.Clear ();
|
|
|
|
//
|
|
// ref: https://github.com/aspnet/Docs/issues/2384
|
|
source.UseForwardedHeaders (forwardOptions);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Extensions\XUserClaimsInfoDtoExtensions.cs
|
|
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xApi.Extensions {
|
|
public static class XUserClaimsInfoDtoExtensions {
|
|
public static string GetUserSelectByParam (
|
|
this XUserClaimsInfoDto source,
|
|
XUserSelectBy userSelectBy = XUserSelectBy.Username
|
|
) {
|
|
//
|
|
var result = "";
|
|
|
|
//
|
|
switch (userSelectBy) {
|
|
//
|
|
case XUserSelectBy.ID:
|
|
result = source.UserId;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.Username:
|
|
result = source.UserName;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.Email:
|
|
result = source.Email;
|
|
break;
|
|
|
|
//
|
|
case XUserSelectBy.MobileNumber:
|
|
result = source.PhoneNumber;
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (result.IsNullOrEmpty ()) {
|
|
//
|
|
if (!source.UserId.IsNullOrEmpty ()) {
|
|
result = source.UserId;
|
|
} else if (!source.UserName.IsNullOrEmpty ()) {
|
|
result = source.UserName;
|
|
} else if (!source.Email.IsNullOrEmpty ()) {
|
|
result = source.Email;
|
|
} else if (!source.PhoneNumber.IsNullOrEmpty ()) {
|
|
result = source.PhoneNumber;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Program.cs
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace xApi
|
|
{
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
CreateHostBuilder(args).Build().Run();
|
|
}
|
|
|
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
Host.CreateDefaultBuilder(args)
|
|
.ConfigureWebHostDefaults(webBuilder =>
|
|
{
|
|
webBuilder.UseStartup<Startup>();
|
|
});
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xApi\Startup.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using IdentityModel.AspNetCore.OAuth2Introspection;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Serialization;
|
|
using xApi.Extensions;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xDataService.Models;
|
|
using xHttpService.DI;
|
|
using xIdentityService.DI;
|
|
using xServices.Databases;
|
|
using xServices.DI;
|
|
|
|
namespace xApi
|
|
{
|
|
public class Startup
|
|
{
|
|
//
|
|
public IConfiguration Configuration { get; }
|
|
private readonly XApiDatabaseDescriptor apiDatabaseDescriptor;
|
|
|
|
public Startup(IConfiguration configuration)
|
|
{
|
|
//
|
|
Configuration = configuration;
|
|
|
|
//
|
|
// Create an Api Descriptor Class Instance ...
|
|
apiDatabaseDescriptor = new XApiDatabaseDescriptor();
|
|
}
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
//
|
|
// Register Validation Provider and all XCommons Module Services ...
|
|
services.AddXCommons();
|
|
|
|
//
|
|
// Register App Configuration ...
|
|
services.AddXAppConfiguration(Configuration);
|
|
var appConfiguration = services.GetRegisteredService<XAppConfiguration>();
|
|
|
|
//
|
|
// Register Allowed Origins ...
|
|
services.AddXCors(appConfiguration.AllowedOrigins);
|
|
|
|
//
|
|
// Register Swagger ...
|
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
|
services.AddXSwagger(Configuration, xmlFilePath: xmlPath);
|
|
|
|
//
|
|
// Register HttpService ...
|
|
services.AddXHttpService(Configuration);
|
|
|
|
//
|
|
// Add Api V1 Versioning ...
|
|
services.AddXApiV1Versioning();
|
|
|
|
//
|
|
// OAuthIntrospectin Http Client Handler ...
|
|
// this is for handling SSLErrors ...
|
|
services.AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName)
|
|
.ConfigurePrimaryHttpMessageHandler(() =>
|
|
{
|
|
return new HttpClientHandler
|
|
{
|
|
ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
|
|
};
|
|
});
|
|
|
|
//
|
|
// Register Authorizations ...
|
|
services.AddXAuthorization();
|
|
|
|
//
|
|
services.AddControllers()
|
|
.AddNewtonsoftJson(x =>
|
|
{
|
|
x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
|
x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
|
});
|
|
|
|
//
|
|
// Custom ...
|
|
|
|
//
|
|
services.Configure<IISServerOptions>(options =>
|
|
{
|
|
options.AllowSynchronousIO = true;
|
|
});
|
|
|
|
//
|
|
services.Configure<KestrelServerOptions>(options =>
|
|
{
|
|
options.AllowSynchronousIO = true;
|
|
});
|
|
|
|
//
|
|
// Register Services ...
|
|
services.AddXServices(
|
|
configuration: Configuration,
|
|
databases: new List<XDatabaseDescriptor>
|
|
{
|
|
apiDatabaseDescriptor
|
|
},
|
|
lifeTime: ServiceLifetime.Scoped
|
|
);
|
|
}
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
{
|
|
//
|
|
if (env.IsDevelopment())
|
|
{
|
|
app.UseDeveloperExceptionPage();
|
|
}
|
|
|
|
//
|
|
// Use Swagger Middleware ...
|
|
app.UseXSwagger();
|
|
|
|
//
|
|
app.UseHttpsRedirection();
|
|
|
|
//
|
|
// Using Cors ...
|
|
app.UseXCors();
|
|
|
|
//
|
|
app.UseRouting();
|
|
|
|
//
|
|
// Use xIdentityService ...
|
|
app.UseXIdentityService();
|
|
|
|
//
|
|
app.UseAuthorization();
|
|
|
|
//
|
|
app.UseEndpoints(endpoints =>
|
|
{
|
|
endpoints.MapControllers();
|
|
});
|
|
|
|
//
|
|
// Use xDataService Middleware ...
|
|
app.UseXServices(
|
|
databases: new List<XDatabaseDescriptor>
|
|
{
|
|
apiDatabaseDescriptor
|
|
},
|
|
isDevelopmentEnvironment: env.IsDevelopment()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xClient\plugins\cordova-plugin-splashscreen\src\wp\ResolutionHelper.cs
|
|
|
|
/*
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
using Microsoft.Phone.Info;
|
|
using System;
|
|
using System.Windows;
|
|
|
|
namespace WPCordovaClassLib.Cordova.Commands
|
|
{
|
|
public enum Resolutions { WVGA, WXGA, HD };
|
|
|
|
public static class ResolutionHelper
|
|
{
|
|
public static Resolutions CurrentResolution
|
|
{
|
|
get
|
|
{
|
|
switch (Application.Current.Host.Content.ScaleFactor)
|
|
{
|
|
case 100: return Resolutions.WVGA;
|
|
case 160: return Resolutions.WXGA;
|
|
case 150: return Resolutions.HD;
|
|
}
|
|
throw new InvalidOperationException("Unknown resolution");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xClient\plugins\cordova-plugin-splashscreen\src\wp\SplashScreen.cs
|
|
|
|
/*
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.Net;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Ink;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Animation;
|
|
using System.Windows.Shapes;
|
|
using Microsoft.Phone.Info;
|
|
using System.Windows.Controls.Primitives;
|
|
using System.Diagnostics;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Resources;
|
|
using System.IO;
|
|
using System.Xml.Linq;
|
|
using System.Linq;
|
|
using System.Windows.Threading;
|
|
|
|
namespace WPCordovaClassLib.Cordova.Commands
|
|
{
|
|
/// <summary>
|
|
/// Listens for changes to the state of the battery on the device.
|
|
/// Currently only the "isPlugged" parameter available via native APIs.
|
|
/// </summary>
|
|
public class SplashScreen : BaseCommand
|
|
{
|
|
private Popup popup;
|
|
|
|
// Time until we dismiss the splashscreen
|
|
private int prefDelay = 3000;
|
|
|
|
// Whether we hide it by default
|
|
private bool prefAutoHide = true;
|
|
|
|
// Path to image to use
|
|
private string prefImagePath = "SplashScreenImage.jpg";
|
|
|
|
// static because autodismiss is only ever applied once, at app launch
|
|
// subsequent page loads should not cause the SplashScreen to be shown.
|
|
private static bool WasShown = false;
|
|
|
|
public SplashScreen()
|
|
{
|
|
LoadConfigPrefs();
|
|
|
|
Image SplashScreen = new Image()
|
|
{
|
|
Height = Application.Current.Host.Content.ActualHeight,
|
|
Width = Application.Current.Host.Content.ActualWidth,
|
|
Stretch = Stretch.Fill
|
|
};
|
|
|
|
var imageResource = GetSplashScreenImageResource();
|
|
if (imageResource != null)
|
|
{
|
|
BitmapImage splash_image = new BitmapImage();
|
|
splash_image.SetSource(imageResource.Stream);
|
|
SplashScreen.Source = splash_image;
|
|
}
|
|
|
|
// Instansiate the popup and set the Child property of Popup to SplashScreen
|
|
popup = new Popup() { IsOpen = false,
|
|
Child = SplashScreen,
|
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
|
|
};
|
|
}
|
|
|
|
public override void OnInit()
|
|
{
|
|
// we only want to autoload on the first page load.
|
|
// but OnInit is called for every page load.
|
|
if (!SplashScreen.WasShown)
|
|
{
|
|
SplashScreen.WasShown = true;
|
|
show();
|
|
}
|
|
}
|
|
|
|
private void LoadConfigPrefs()
|
|
{
|
|
StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("config.xml", UriKind.Relative));
|
|
if (streamInfo != null)
|
|
{
|
|
using (StreamReader sr = new StreamReader(streamInfo.Stream))
|
|
{
|
|
//This will Read Keys Collection for the xml file
|
|
XDocument configFile = XDocument.Parse(sr.ReadToEnd());
|
|
|
|
string configAutoHide = configFile.Descendants()
|
|
.Where(x => x.Name.LocalName == "preference")
|
|
.Where(x => (string)x.Attribute("name") == "AutoHideSplashScreen")
|
|
.Select(x => (string)x.Attribute("value"))
|
|
.FirstOrDefault();
|
|
|
|
bool bVal;
|
|
prefAutoHide = bool.TryParse(configAutoHide, out bVal) ? bVal : prefAutoHide;
|
|
|
|
string configDelay = configFile.Descendants()
|
|
.Where(x => x.Name.LocalName == "preference")
|
|
.Where(x => (string)x.Attribute("name") == "SplashScreenDelay")
|
|
.Select(x => (string)x.Attribute("value"))
|
|
.FirstOrDefault();
|
|
int nVal;
|
|
prefDelay = int.TryParse(configDelay, out nVal) ? nVal : prefDelay;
|
|
|
|
string configImage = configFile.Descendants()
|
|
.Where(x => x.Name.LocalName == "preference")
|
|
.Where(x => (string)x.Attribute("name") == "SplashScreen")
|
|
.Select(x => (string)x.Attribute("value"))
|
|
.FirstOrDefault();
|
|
|
|
if (!String.IsNullOrEmpty(configImage))
|
|
{
|
|
prefImagePath = configImage;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private StreamResourceInfo GetSplashScreenImageResource()
|
|
{
|
|
// Get the base filename for the splash screen images
|
|
string imageName = System.IO.Path.GetFileNameWithoutExtension(prefImagePath);
|
|
Uri imageUri = null;
|
|
StreamResourceInfo imageResource = null;
|
|
|
|
// First, try to get a resolution-specific splashscreen
|
|
try
|
|
{
|
|
// Determine the device's resolution
|
|
switch (ResolutionHelper.CurrentResolution)
|
|
{
|
|
case Resolutions.HD:
|
|
imageUri = new Uri(imageName + ".screen-720p.jpg", UriKind.Relative);
|
|
break;
|
|
|
|
case Resolutions.WVGA:
|
|
imageUri = new Uri(imageName + ".screen-WVGA.jpg", UriKind.Relative);
|
|
break;
|
|
|
|
case Resolutions.WXGA:
|
|
default:
|
|
imageUri = new Uri(imageName + ".screen-WXGA.jpg", UriKind.Relative);
|
|
break;
|
|
}
|
|
|
|
imageResource = Application.GetResourceStream(imageUri);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// It's OK if we didn't get a resolution-specific image
|
|
}
|
|
|
|
// Fallback to the default image name without decoration
|
|
if (imageResource == null)
|
|
{
|
|
imageUri = new Uri(prefImagePath, UriKind.Relative);
|
|
imageResource = Application.GetResourceStream(imageUri);
|
|
}
|
|
|
|
if (imageUri != null) Debug.WriteLine("INFO :: SplashScreen: using image {0}", imageUri.OriginalString);
|
|
|
|
return imageResource;
|
|
}
|
|
|
|
public void show(string options = null)
|
|
{
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
if (!popup.IsOpen)
|
|
{
|
|
popup.Child.Opacity = 0;
|
|
|
|
Storyboard story = new Storyboard();
|
|
DoubleAnimation animation = new DoubleAnimation()
|
|
{
|
|
From = 0.0,
|
|
To = 1.0,
|
|
Duration = new Duration(TimeSpan.FromSeconds(0.2))
|
|
};
|
|
|
|
Storyboard.SetTarget(animation, popup.Child);
|
|
Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity"));
|
|
story.Children.Add(animation);
|
|
|
|
story.Begin();
|
|
|
|
popup.IsOpen = true;
|
|
|
|
if (prefAutoHide)
|
|
{
|
|
StartAutoHideTimer();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void hide(string options = null)
|
|
{
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
if (popup.IsOpen)
|
|
{
|
|
popup.Child.Opacity = 1.0;
|
|
|
|
Storyboard story = new Storyboard();
|
|
DoubleAnimation animation = new DoubleAnimation()
|
|
{
|
|
From = 1.0,
|
|
To = 0.0,
|
|
Duration = new Duration(TimeSpan.FromSeconds(0.4))
|
|
};
|
|
|
|
Storyboard.SetTarget(animation, popup.Child);
|
|
Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity"));
|
|
story.Children.Add(animation);
|
|
story.Completed += (object sender, EventArgs e) =>
|
|
{
|
|
popup.IsOpen = false;
|
|
};
|
|
story.Begin();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void StartAutoHideTimer()
|
|
{
|
|
var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(prefDelay) };
|
|
timer.Tick += (object sender, EventArgs e) =>
|
|
{
|
|
hide();
|
|
timer.Stop();
|
|
};
|
|
timer.Start();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xClient\plugins\cordova-plugin-statusbar\src\wp\StatusBar.cs
|
|
|
|
/*
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
|
|
using Microsoft.Phone.Shell;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Threading;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using System.Windows.Threading;
|
|
|
|
|
|
/*
|
|
* http://www.idev101.com/code/User_Interface/StatusBar.html
|
|
* https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/Bars.html
|
|
* https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/c/econst/UIStatusBarStyleDefault
|
|
* */
|
|
|
|
|
|
namespace WPCordovaClassLib.Cordova.Commands
|
|
{
|
|
public class StatusBar : BaseCommand
|
|
{
|
|
|
|
// returns an argb value, if the hex is only rgb, it will be full opacity
|
|
protected Color ColorFromHex(string hexString)
|
|
{
|
|
string cleanHex = hexString.Replace("#", "").Replace("0x", "");
|
|
// turn #FFF into #FFFFFF
|
|
if (cleanHex.Length == 3)
|
|
{
|
|
cleanHex = "" + cleanHex[0] + cleanHex[0] + cleanHex[1] + cleanHex[1] + cleanHex[2] + cleanHex[2];
|
|
}
|
|
// add an alpha 100% if it is missing
|
|
if (cleanHex.Length == 6)
|
|
{
|
|
cleanHex = "FF" + cleanHex;
|
|
}
|
|
int argb = Int32.Parse(cleanHex, NumberStyles.HexNumber);
|
|
Color clr = Color.FromArgb((byte)((argb & 0xff000000) >> 0x18),
|
|
(byte)((argb & 0xff0000) >> 0x10),
|
|
(byte)((argb & 0xff00) >> 8),
|
|
(byte)(argb & 0xff));
|
|
return clr;
|
|
}
|
|
|
|
public void _ready(string options)
|
|
{
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
bool isVis = SystemTray.IsVisible;
|
|
// TODO: pass this to JS
|
|
//Debug.WriteLine("Result::" + res);
|
|
DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isVis));
|
|
});
|
|
}
|
|
|
|
public void overlaysWebView(string options)
|
|
{ //exec(null, null, "StatusBar", "overlaysWebView", [doOverlay]);
|
|
// string arg = JSON.JsonHelper.Deserialize<string[]>(options)[0];
|
|
}
|
|
|
|
public void styleDefault(string options)
|
|
{ //exec(null, null, "StatusBar", "styleDefault", []);
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
SystemTray.ForegroundColor = Colors.Black;
|
|
});
|
|
}
|
|
|
|
public void styleLightContent(string options)
|
|
{ //exec(null, null, "StatusBar", "styleLightContent", []);
|
|
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
SystemTray.ForegroundColor = Colors.White;
|
|
});
|
|
}
|
|
|
|
public void styleBlackTranslucent(string options)
|
|
{ //exec(null, null, "StatusBar", "styleBlackTranslucent", []);
|
|
styleLightContent(options);
|
|
}
|
|
|
|
public void styleBlackOpaque(string options)
|
|
{ //exec(null, null, "StatusBar", "styleBlackOpaque", []);
|
|
styleLightContent(options);
|
|
}
|
|
|
|
public void backgroundColorByName(string options)
|
|
{ //exec(null, null, "StatusBar", "backgroundColorByName", [colorname]);
|
|
// this should NOT be called, js should now be using/converting color names to hex
|
|
}
|
|
|
|
public void backgroundColorByHexString(string options)
|
|
{ //exec(null, null, "StatusBar", "backgroundColorByHexString", [hexString]);
|
|
string argb = JSON.JsonHelper.Deserialize<string[]>(options)[0];
|
|
|
|
Color clr = ColorFromHex(argb);
|
|
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
SystemTray.Opacity = clr.A / 255.0d;
|
|
SystemTray.BackgroundColor = clr;
|
|
|
|
});
|
|
}
|
|
|
|
public void hide(string options)
|
|
{ //exec(null, null, "StatusBar", "hide", []);
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
SystemTray.IsVisible = false;
|
|
});
|
|
|
|
}
|
|
|
|
public void show(string options)
|
|
{ //exec(null, null, "StatusBar", "show", []);
|
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
|
{
|
|
SystemTray.IsVisible = true;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Configurations\CertificatesConfigurations.cs
|
|
|
|
namespace xIds.Configurations
|
|
{
|
|
public class CertificatesConfigurations
|
|
{
|
|
public struct CertificateNames
|
|
{
|
|
public const string IdentityServerSigning = "IdentityServerSigning";
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Configurations\XDataServiceConfiguration.cs
|
|
|
|
using xIds.Constants;
|
|
|
|
namespace xIds.Configurations
|
|
{
|
|
/// <summary>
|
|
/// Represent Configurations of DataService Module ...
|
|
/// </summary>
|
|
public partial class XDataServiceConfiguration
|
|
{
|
|
/// <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; }
|
|
|
|
/// <summary>
|
|
/// Enable Tracking of Entities ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableTracking { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// Enable Logging Details of Errors ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableDetailedErrors { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// Enable Logging Sensitive Data ...
|
|
/// Only Used on EFCore ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public bool EnableSensitiveDataLogging { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// this is a way to provide Default Pagination Data on XQuery based requests ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration();
|
|
}
|
|
|
|
/// <summary>
|
|
/// this is a way to provide Default Pagination Data on XQuery based requests ...
|
|
/// </summary>
|
|
public partial class PagingConfiguration
|
|
{
|
|
/// <summary>
|
|
/// Default Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int DefaultPageSize { get; set; } = XDataServiceConstants.DEFAULT_PAGE_SIZE;
|
|
|
|
/// <summary>
|
|
/// restrict Maximum Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MaxAvailablePageSize { get; set; } = XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE;
|
|
|
|
/// <summary>
|
|
/// restrice Minimum Page Size ...
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int MinAvailablePageSize { get; set; } = XDataServiceConstants.MIN_AVAILABLE_PAGE_SIZE;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Configurations\XIdentityResourceConfiguration.cs
|
|
|
|
namespace xIds.Configurations
|
|
{
|
|
/// <summary>
|
|
/// determines a resource and it's connection info
|
|
/// </summary>
|
|
public partial class XIdentityResourceConfiguration
|
|
{
|
|
public string Authority { get; set; }
|
|
public string ApiName { get; set; }
|
|
public string ApiSecret { get; set; }
|
|
|
|
public string ClientId { get; set; }
|
|
public string ClientSecret { get; set; }
|
|
|
|
public string XPoweredValue { get; set; }
|
|
public string XRevisionSecretKey { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
public struct ConfigurationNodeNames
|
|
{
|
|
public const string DB_SEED_NODE_NAME = "DbSeeder";
|
|
public const string PROVIDER_NODE_NAME = "DbProvider";
|
|
public const string IDENTITY_NODE_NAME = "IdentityConfiguration";
|
|
public const string DATA_SERVICE_NODE_NAME = "DataServiceConfiguration";
|
|
public const string IDENTITY_RESOURCE_NODE_NAME = "IdentityResourceConfiguration";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\ConnectionStringNames.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
public struct ConnectionStringNames
|
|
{
|
|
public const string IDENTITY_CONNECTION_NAME = "IdentityDb";
|
|
public const string CONFIGURATION_CONNECTION_NAME = "ConfigurationDb";
|
|
public const string PRESISTED_GRANTS_CONNECTION_NAME = "PersistedGrantDb";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\IdentityMessagesKeys.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
public struct IdentityMessagesKeys
|
|
{
|
|
public const string Terms = "terms";
|
|
public const string InviteMsg = "user_invite_msg";
|
|
public const string RegistrationApproveMsg = "registration_approve_msg";
|
|
public const string RegisteredMsg = "registered_msg";
|
|
public const string VerificationCodeMsg = "verification_code_msg";
|
|
public const string ChangePasswordMsg = "change_password_msg";
|
|
public const string PasswordChangedMsg = "password_changed_msg";
|
|
public const string NewDeviceLoggedInMsg = "new_device_logged_in_msg";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\XDataServiceConstants.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
/// <summary>
|
|
/// /// Default Pagination Values ...
|
|
/// </summary>
|
|
public partial struct XDataServiceConstants
|
|
{
|
|
public static int DEFAULT_PAGE_SIZE = 50;
|
|
public static int MAX_AVAILABLE_PAGE_SIZE = 500;
|
|
public static int MIN_AVAILABLE_PAGE_SIZE = 20;
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\XDbProviderConfigurations.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
public partial class XDbProviderConfigurations
|
|
{
|
|
/// <summary>
|
|
/// Default ConnectionString Name ...
|
|
/// </summary>
|
|
public const string DEFAULT_CONNECTION_NAME = "DataConnection";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Constants\XDbProviders.cs
|
|
|
|
namespace xIds.Constants
|
|
{
|
|
/// <summary>
|
|
/// /// Represent Supported DBMS for Managing Data ...
|
|
/// </summary>
|
|
public enum XDbProviders
|
|
{
|
|
None,
|
|
MySQL,
|
|
SQLite,
|
|
SQLServer,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represent Supported DBMS for Managing Data ...
|
|
/// </summary>
|
|
public partial struct ProviderType
|
|
{
|
|
public const string MySQL = "MYSQL";
|
|
public const string SQLite = "SQLITE";
|
|
public const string SQLServer = "SQLSERVER";
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Admin.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Admin Actions ...
|
|
/// <summary>
|
|
/// Ban Specific Users
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of banned users identifiers</returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Ban")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
public async Task<ActionResult<IEnumerable<string>>> Ban(
|
|
[FromBody] XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotZeroChilds(model.Ids)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Ban(
|
|
User.Identity.Name,
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// UnBann Specific Users
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a list of unbanned users identifiers</returns>
|
|
[RequireXPowered]
|
|
[HttpPost("UnBan")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
public async Task<ActionResult<IEnumerable<string>>> UnBan(
|
|
[FromBody] XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotZeroChilds(model.Ids)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.UnBan(
|
|
User.Identity.Name,
|
|
model
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specific User is Banned or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns>a boolean value which represent user banned or not</returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[HttpGet("IsBanned/{userSelectByParam?}")]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize(Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<bool>> IsBanned(
|
|
[FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.IsBanned(
|
|
User.Identity.Name,
|
|
userSelectByParam
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Authentication.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
using static xIdentityHelper.XApiScopeHelper;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Authentication Actions ...
|
|
/// <summary>
|
|
/// Retrieve OAuth Discovery Document
|
|
/// </summary>
|
|
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("DiscoveryDocument")]
|
|
public async Task<ActionResult<DiscoveryDocumentResponse>> GetDiscoveryDocument()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.RequestDiscoveryDocument();
|
|
|
|
//
|
|
// Ceck Response Result ...
|
|
if (result.IsError)
|
|
{
|
|
XException.InvalidConfiguration.Throw();
|
|
}
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request AccessToken for Specific XApiScope
|
|
/// </summary>
|
|
/// <param name="scope">a member of <see>XApiScope</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestScopeAccessToken")]
|
|
public async Task<ActionResult<XTokenResponse>> RequestScopeAccessToken(
|
|
[FromHeader] XApiScope scope
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var scopeName = string.Empty;
|
|
try
|
|
{
|
|
scopeName = scope.GetStringValue();
|
|
}
|
|
catch { }
|
|
ValidationProvider.NotEmpty(scopeName);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.RequestScopeAccessToken(scopeName);
|
|
|
|
//
|
|
// Ceck Response Result ...
|
|
if (result.IsError)
|
|
{
|
|
XException.InvalidConfiguration.Throw();
|
|
}
|
|
|
|
//
|
|
return Ok(result
|
|
.CreateXTokenResponse()
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate User
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "password": "",
|
|
/// "userSelectBy": "",
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("Authenticate")]
|
|
public async Task<ActionResult<XTokenResponse>> Authenticate(
|
|
[FromBody] XLoginRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Authenticate(model);
|
|
|
|
//
|
|
// Check Result ...
|
|
if (result.IsError)
|
|
{
|
|
throw result.GetException();
|
|
}
|
|
|
|
//
|
|
// Return Result ...
|
|
return Ok(result
|
|
.CreateXTokenResponse()
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate User
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "language": "fa-IR"
|
|
/// "password": "",
|
|
/// "userSelectBy": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
|
/// <returns>an instance of <see>XLoginResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("Login")]
|
|
public async Task<ActionResult<XLoginResponse>> Login(
|
|
[FromBody] XLoginRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(
|
|
model,
|
|
model.Device)
|
|
.AddNotEmpty(
|
|
model.Language,
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Login(model);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Expired Tokens
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// in addition to AccessToken, you had to pass RefreshToken due to Headers
|
|
/// </remarks>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RefreshTokens")]
|
|
public async Task<ActionResult<XTokenResponse>> RefreshTokens()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Retrieve Toke Response ...
|
|
var model = await RetrieveTokensAsXTokenResponse();
|
|
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(
|
|
model.AccessToken,
|
|
model.RefreshToken)
|
|
.ValidateGroup();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.RefreshTokens(model);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Password Actions ...
|
|
/// <summary>
|
|
/// Change a User's Password ...
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - NewPassword: user's new password to change.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": ""
|
|
/// "newPassword": "",
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("ChangePassword")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
public async Task<ActionResult> ChangePassword(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(
|
|
model,
|
|
model.Device
|
|
)
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Password,
|
|
model.NewPassword,
|
|
model.ReturnUrl
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get User Select By ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
model,
|
|
forceNotNull: false
|
|
);
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Get Request ...
|
|
await IdentityManager
|
|
.ChangePassword(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.Password,
|
|
model.NewPassword,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Friendship.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityHelper;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Friendship Actions ...
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Follow a User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Friendship/{destUser}/Follow")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Follow(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Follow(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cancel Following
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[HttpPost("Friendship/{destUser}/Cancel")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<bool>> Cancel(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Cancel(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow a Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Friendship/{destUser}/UnFollowFollower")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult> UnFollowFollower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
await IdentityManager
|
|
.UnFollowFollower(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unfollow Following
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/UnFollowFollowing")]
|
|
public async Task<ActionResult> UnFollowFollowing(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
await IdentityManager
|
|
.UnFollowFollowing(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Block a Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[HttpPost("Friendship/{destUser}/Block")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Block(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.Block(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unblock a Blocked User
|
|
/// </summary>
|
|
/// <param name="destUser">an instance of <see>XFriendshipFollowing</see></param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[HttpPost("Friendship/{destUser}/UnBlock")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipFollowing>> UnBlock(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.UnBlock(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Request Handlers ...
|
|
/// <summary>
|
|
/// Accept a Following Request
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/AcceptRequest")]
|
|
public async Task<ActionResult<XFriendshipFollower>> AcceptRequest(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.AcceptRequest(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reject a Following Request
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Friendship/{destUser}/RejectRequest")]
|
|
public async Task<ActionResult<XFriendshipFollower>> RejectRequest(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.RejectRequest(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Getters ...
|
|
/// <summary>
|
|
/// Check a User IsFollower of Requested User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/IsFollower")]
|
|
public async Task<ActionResult<bool>> IsFollower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.IsFollower(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Follower State of a User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/FollowerState")]
|
|
public async Task<ActionResult<XFriendshipState>> FollowerState(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowerState(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Follower
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/Follower")]
|
|
public async Task<ActionResult<XFriendshipFollower>> Follower(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollower(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followers List Of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
[HttpGet("Friendship/Followers")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> Followers()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowers(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followers List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see></returns>
|
|
[HttpGet("Friendship/AllFollowers")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollower>>> AllFollowers()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetAllFollowers(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Followers List Includes Blocked, Requested and etc
|
|
/// of Current User based On Query Model ...
|
|
/// </summary>
|
|
/// <returns>a Query Result of <see>XFriendDto</see></returns>
|
|
[HttpGet("Friendship/QueryFollowers")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowers(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Normalizing Dest User ...
|
|
var userInfo = await GetUserInfo();
|
|
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
|
|
if (destUser.IsNullOrEmpty())
|
|
{
|
|
destUser = userInfo.UserName;
|
|
}
|
|
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
|
|
if (!isDestUserValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.QueryFollowers(
|
|
query: query,
|
|
userSelectByParam: destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is in Followings of Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>a boolean value</returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/IsFollowing")]
|
|
public async Task<ActionResult<bool>> IsFollowing(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.IsFollowing(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Following State Relation between Specific User
|
|
/// and Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipState</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/FollowingState")]
|
|
public async Task<ActionResult<XFriendshipState>> FollowingState(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowingState(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specific Following Model
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpGet("Friendship/{destUser}/Following")]
|
|
public async Task<ActionResult<XFriendshipFollowing>> Following(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(destUser);
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowing(
|
|
User.Identity.Name,
|
|
destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Followings of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
[HttpGet("Friendship/Followings")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> Followings()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowings(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Following List Includes Blocked, Requested and etc
|
|
/// of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see></returns>
|
|
[HttpGet("Friendship/AllFollowings")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XFriendshipFollowing>>> AllFollowings()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetAllFollowings(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Following List Includes Blocked, Requested and etc
|
|
/// of Current User based On Query Model ...
|
|
/// </summary>
|
|
/// <returns>a Query Result of <see>XFriendDto</see></returns>
|
|
[HttpGet("Friendship/QueryFollowings")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XFriendDto>>> QueryFollowings(
|
|
[FromQuery] XQuery query,
|
|
[FromQuery] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Normalizing Dest User ...
|
|
var userInfo = await GetUserInfo();
|
|
bool isAdmin = userInfo.Roles.Contains(XUserRoles.ADMIN);
|
|
if (destUser.IsNullOrEmpty())
|
|
{
|
|
destUser = userInfo.UserName;
|
|
}
|
|
bool isDestUserValid = isAdmin || destUser == userInfo.UserId || destUser == userInfo.Email || destUser == userInfo.PhoneNumber || destUser == userInfo.UserName;
|
|
if (!isDestUserValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.QueryFollowings(
|
|
query: query,
|
|
userSelectByParam: destUser
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Others ...
|
|
/// <summary>
|
|
/// Return Following UserName's List of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[HttpGet("Friendship/FollowingsList")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> FollowingsList()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowingList(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return Followers UserName's List of Current User
|
|
/// </summary>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[HttpGet("Friendship/FollowersList")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> FollowersList()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFollowersList(User.Identity.Name);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Friendship Info Model between Specific User and Current User
|
|
/// </summary>
|
|
/// <param name="destUser">a user identifier which represent destination user</param>
|
|
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
|
|
[HttpGet("Friendship/{destUser}/FriendshipInfo")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XFriendshipInfoDto>> FriendshipInfo(
|
|
[FromRoute] string destUser
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.GetFriendshipInfo(User.Identity.Name, destUser);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Open.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Constants;
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
// Implememnt all Open Actions here ...
|
|
|
|
//
|
|
#region Open Actions ...
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("Open")]
|
|
public async Task<ActionResult<string>> Get(
|
|
[FromHeader] string token,
|
|
[FromQuery] string request
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(token)
|
|
.AddNotEmpty(request)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Prepare Inner Dto Model ...
|
|
var dto = new XOpenActionInnerDto
|
|
{
|
|
Token = token,
|
|
Payload = request
|
|
};
|
|
|
|
//
|
|
// Do Action ...
|
|
var resultDto = await IdentityManager.OpenGet(dto);
|
|
Response.Headers.Add(XAuthentication.TOKEN, resultDto.Token);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(resultDto.Payload);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Profile.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Retrieve Actions ...
|
|
/// <summary>
|
|
/// Retrieve User Names based on UserIds
|
|
/// </summary>
|
|
/// <param name="ids">a comma seperated list of UserIds</param>
|
|
/// <returns>a collection of UserNames</returns>
|
|
[HttpGet("Profile/{ids}/GetNames")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<string>>> GetNames(
|
|
[FromRoute] string ids
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(ids);
|
|
|
|
//
|
|
var xIdList = ids.ParseListString<string>();
|
|
var result = await IdentityManager.GetUserNamesAsync(
|
|
xIdList
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// get user ids and retrieve corresponding user names
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
|
|
/// <returns>a collection of <see>XUserNameIdResponse</see> instance</returns>
|
|
[HttpPost("Profile/GetNameIds")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<IEnumerable<XUserNameIdResponse>>> GetNameIds(
|
|
[FromBody] XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var result = await IdentityManager.GetUserNameIdsAsync(
|
|
model
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Profile Object of Specific User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[HttpGet("Profile/{userSelectByParam?}")]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> GetProfile(
|
|
[FromRoute] string userSelectByParam = ""
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.GetUserProfileAsync(
|
|
userSelectByParam,
|
|
User.Identity.Name
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Users
|
|
/// for specifiy users role for query user 'role: string' and 'forceRole: boolean' in header
|
|
/// </summary>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Profile/Query")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize(Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryProfiles(
|
|
[FromQuery] XQuery query, [FromHeader] string role, [FromHeader] bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var userId = User.Identity.Name;
|
|
|
|
//
|
|
var result = new XQueryResult<XUserProfileDto>();
|
|
if (role.IsNullOrEmpty())
|
|
{
|
|
//
|
|
result = await IdentityManager.QueryUsers(
|
|
userId,
|
|
query
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
result = await IdentityManager.QueryInRoleUsers(
|
|
userId,
|
|
role,
|
|
query,
|
|
forceRole
|
|
);
|
|
}
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[HttpGet("Profile/Avatars/Query/{userSelectByParam?}")]
|
|
public async Task<ActionResult<XQueryResult<XProfileImageDto>>> QueryAvatars(
|
|
[FromQuery] XQuery query, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager.QueryAvatars(
|
|
userSelectByParam,
|
|
query
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update Actions ...
|
|
/// <summary>
|
|
/// Update User Profile based on XProfileUpdateRequest (FirstName/LastName/DateOfBirth)
|
|
/// </summary>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
[HttpPost("Profile/Update/{userSelectByParam?}")]
|
|
public async Task<ActionResult<XUserProfileDto>> UpdateProfile(
|
|
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager.ProfileUpdateAsync(
|
|
userSelectByParam,
|
|
User.Identity.Name,
|
|
model
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a User Profile based on XProfileUpdateRequest Full
|
|
/// </summary>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <param name="userSelectByParam">determine's which user profile must be retrieved</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[HttpPost("Profile/{userSelectByParam?}")]
|
|
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
|
|
public async Task<ActionResult<XUserProfileDto>> FullUpdateProfile(
|
|
[FromBody] XProfileUpdateRequest model, [FromRoute] string userSelectByParam = null
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
userSelectByParam = User.Identity.Name;
|
|
}
|
|
|
|
//
|
|
var result = await IdentityManager.FullProfileUpdateAsync(
|
|
userSelectByParam,
|
|
User.Identity.Name,
|
|
model
|
|
);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Avatar Actions ...
|
|
/// <summary>
|
|
/// Add a New Profile Image
|
|
/// </summary>
|
|
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatar")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> AddAvatar(
|
|
[FromForm] IFormFile file
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(file);
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.AddAvatar(
|
|
User.Identity.Name,
|
|
file
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a New Collection of Profile Images
|
|
/// </summary>
|
|
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatars")]
|
|
[RequestSizeLimit(966_367_641)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> AddAvatars(
|
|
[FromForm] IFormFileCollection files
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotZeroChilds(files);
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager.AddAvatars(
|
|
User.Identity.Name,
|
|
files
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Profile Images
|
|
/// </summary>
|
|
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[HttpDelete("Profile/Avatars/{ids}")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> RemoveAvatars(
|
|
[FromRoute] string ids
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(ids);
|
|
var idList = ids.Split(",");
|
|
var idCollection = new Collection<int>();
|
|
|
|
//
|
|
foreach (var s in idList)
|
|
{
|
|
idCollection.Add(int.Parse(s));
|
|
}
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.RemoveAvatar(
|
|
User.Identity.Name,
|
|
idCollection.ToArray()
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// set Specified Profile Image as Avatar
|
|
/// </summary>
|
|
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("Profile/Avatars/{id:int}/Set")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XUserProfileDto>> SetAvatar(
|
|
[FromRoute] int id
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.SetAvatar(
|
|
User.Identity.Name,
|
|
id
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Query.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityHelper;
|
|
using xModels.Dtos;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
/// <summary>
|
|
/// Query Users
|
|
/// for specifiy users role for query user 'role: string' and 'forceRole: boolean' in header
|
|
/// </summary>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Users/Query")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<string>>> QueryUsers(
|
|
[FromQuery] XQuery query,
|
|
[FromHeader] string role,
|
|
[FromHeader] bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Do Actions ...
|
|
try
|
|
{
|
|
//
|
|
// Retrieve User Info ...
|
|
var userInfo = await GetUserInfo();
|
|
|
|
//
|
|
// Retrieve Result Based on Provided Query ...
|
|
var result = await IdentityManager.QueryUsers(
|
|
role: role,
|
|
query: query,
|
|
forceRole: forceRole,
|
|
requestedUserSelectByParam: userInfo.UserId
|
|
);
|
|
|
|
//
|
|
// Return result ...
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Registration.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region CanRegister ...
|
|
/// <summary>
|
|
/// Check a UserName is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="userName">an string value which represent desired username</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("CanRegisterUserName/{userName?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterUserName(
|
|
[FromRoute] string userName
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userName.IsNullOrEmpty())
|
|
{
|
|
return BadRequest(
|
|
XException.InvalidArgs
|
|
.ToXError()
|
|
);
|
|
}
|
|
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.CanRegister(userName);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Mobile Number is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="mobileNumber">an string value which represent desired mobile number</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("CanRegisterMobileNumber/{mobileNumber?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterMobileNumber(
|
|
[FromRoute] string mobileNumber
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (mobileNumber.IsNullOrEmpty())
|
|
{
|
|
return BadRequest(
|
|
XException.InvalidArgs
|
|
.ToXError()
|
|
);
|
|
}
|
|
if (!mobileNumber.IsValidMobileNumber())
|
|
{
|
|
return BadRequest(
|
|
XException.InvalidMobileNumber
|
|
.ToXError()
|
|
);
|
|
}
|
|
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.CanRegister(mobileNumber);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Email Address is Available For Registration or not
|
|
/// </summary>
|
|
/// <param name="email">an string value which represent desired email address</param>
|
|
/// <returns>a boolean value</returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpGet("CanRegisterEmail/{email?}")]
|
|
public async Task<ActionResult<bool>> CanRegisterEmail(
|
|
[FromRoute] string email
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (email.IsNullOrEmpty())
|
|
{
|
|
return BadRequest(
|
|
XException.InvalidArgs
|
|
.ToXError()
|
|
);
|
|
}
|
|
if (!email.IsValidEmail())
|
|
{
|
|
return BadRequest(
|
|
XException.InvalidEmailAddress
|
|
.ToXError()
|
|
);
|
|
}
|
|
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.CanRegister(email);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Confirmations ...
|
|
/// <summary>
|
|
/// Check User is Confirmed Email or not
|
|
/// </summary>
|
|
/// <returns>a boolean value</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("IsConfirmedEmail")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
public async Task<ActionResult<bool>> IsConfirmedEmail()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.IsConfirmedEmail(User.Identity.Name);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User is Confirmed Mobile or not
|
|
/// </summary>
|
|
/// <returns>a boolean value</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("IsConfirmedMobile")]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
public async Task<ActionResult<bool>> IsConfirmedMobile()
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var result = await IdentityManager
|
|
.IsConfirmedMobile(User.Identity.Name);
|
|
|
|
//
|
|
// Return Result
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Registration
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("ConfirmRegistration")]
|
|
public async Task<ActionResult> ConfirmRegistration(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.ReturnUrl
|
|
)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Request ...
|
|
await IdentityManager
|
|
.ConfirmRegistration(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Mobile Number
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - MobileVerificationCode: a verification code which produced due Request Action.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "mobileVerificationCode": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("ConfirmMobileNumber")]
|
|
public async Task<ActionResult<XActionResponse>> ConfirmMobileNumber(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.MobileVerificationCode
|
|
)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.ConfirmMobileNumber(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.MobileVerificationCode
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Requested Email Address
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - EmailVerificationCode: a verification code which produced due Request Action.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": ""
|
|
/// "emailVerificationCode": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("ConfirmEmailAddress")]
|
|
public async Task<ActionResult<XActionResponse>> ConfirmEmailAddress(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.EmailVerificationCode
|
|
)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.ConfirmEmailAddress(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.EmailVerificationCode
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Request for Actions ...
|
|
/// <summary>
|
|
/// Request For Mobile Number Change/Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - MobileNumber: which phone number is going to confirm.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": "",
|
|
/// "mobileNumber": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestConfirmMobile")]
|
|
public async Task<ActionResult<XActionResponse>> RequestConfirmMobile(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Password,
|
|
model.MobileNumber
|
|
)
|
|
.AddNotNull(model.Device)
|
|
.AddMobileNumber(model.MobileNumber)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
model,
|
|
excludes: new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.RequestConfirmMobile(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.Password,
|
|
model.MobileNumber
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request For Email Address Change/Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - Email: which email address is going to confirm.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "password": "",
|
|
/// "email": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestConfirmEmail")]
|
|
public async Task<ActionResult<XActionResponse>> RequestConfirmEmail(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Email,
|
|
model.Password)
|
|
.AddNotNull(model.Device)
|
|
.AddEmailAddress(model.Email)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
model,
|
|
excludes: new List<XUserSelectBy> {
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.RequestConfirmEmail(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.Password,
|
|
model.Email
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Reset Password Action
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application ResetPassword URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "returnUrl": "http://localhost/reset-password",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestResetPassword")]
|
|
public async Task<ActionResult<XActionResponse>> RequestResetPassword(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ReturnUrl)
|
|
.AddNotNull(model.Device)
|
|
.AddUrl(model.ReturnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam(model);
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.RequestResetPassword(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset a User's Password
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - NewPassword: user's new password to change.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "actionToken": "",
|
|
/// "newPassword": "",
|
|
/// "returnUrl": "http://localhost/login",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("ResetPassword")]
|
|
public async Task<ActionResult> ResetPassword(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.NewPassword,
|
|
model.ReturnUrl)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Request ...
|
|
await IdentityManager
|
|
.ResetPassword(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.NewPassword,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Registration Confirm
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - a UserSelectedBy identifier which represet User.
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Password: user's current active password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Confirm Registration URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userId": ""
|
|
/// "password": "",
|
|
/// "returnUrl": "http://localhost/confirm",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestConfirmRegistration")]
|
|
public async Task<ActionResult> RequestConfirmRegistration(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull(model.Device)
|
|
.AddUrl(model.ReturnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get UserSelect By Param ...
|
|
var userSelectByParam = GetUserSelectByParam(model);
|
|
|
|
//
|
|
// Get Request ...
|
|
await IdentityManager
|
|
.RequestConfirmRegistration(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.Password,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Registration ...
|
|
/// <summary>
|
|
/// Invite a User to Register on Dashboard
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - Email: which email address is going to invite.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Registration URL.
|
|
/// notice in this step you had to provide all this informations as FormData
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "email": "",
|
|
/// "returnUrl": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[RequireXPowered]
|
|
[HttpPost("InviteUser")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
[Authorize(Policy = XPolicies.EnabledAgent)]
|
|
public async Task<ActionResult<XActionResponse>> InviteUser(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Email,
|
|
model.ReturnUrl)
|
|
.AddEmailAddress(model.Email)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.InviteUser(
|
|
model.Lang,
|
|
model.Device,
|
|
model.Email,
|
|
model.ReturnUrl);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var result = GetExceptionActionResult(ex);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recieve some Basic Informations and Start Registration Proccess
|
|
/// if they Valid
|
|
///
|
|
/// Registration Proccess Starts with Invoking this Action
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - FirstName: user's FirstName.
|
|
/// - LastName: user's LastName.
|
|
/// - DateOfBirth: user's dob date.
|
|
/// - MobileNumber: user's MobileNumber optional.
|
|
/// - Email: user's Email optional.
|
|
/// - ActionToken: user's requested action token for this action (if user invited).
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "firstName": "",
|
|
/// "lastName": "",
|
|
/// "dateOfBirth": "",
|
|
/// "email": "",
|
|
/// "mobileNumber": "",
|
|
/// "actionToken": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("RequestRegistration")]
|
|
public async Task<ActionResult<XActionResponse>> RequestRegistration(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.FirstName,
|
|
model.LastName)
|
|
.AddNotNull(
|
|
model.Device,
|
|
model.DateOfBirth)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Date Of Birth ...
|
|
if (!model.DateOfBirth.HasValue)
|
|
{
|
|
XException.InvalidArgs.Throw(); ;
|
|
}
|
|
|
|
//
|
|
// Validate Mobile Number if Exists ...
|
|
if (!model.MobileNumber.IsNullOrEmpty())
|
|
{
|
|
ValidationProvider.MobileNumber(model.MobileNumber);
|
|
}
|
|
|
|
//
|
|
// Validate Email Address if Exists ...
|
|
if (!model.Email.IsNullOrEmpty())
|
|
{
|
|
ValidationProvider.EmailAddress(model.Email);
|
|
}
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.RequestRegistration(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.FirstName,
|
|
model.LastName,
|
|
model.DateOfBirth.GetValueOrDefault(),
|
|
model.MobileNumber,
|
|
model.Email
|
|
);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add User Account Informations
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - UserName: user name.
|
|
/// - Password: assigne password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userName": "",
|
|
/// "password": "",
|
|
/// "actionToken": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("AddAccountInfo")]
|
|
public async Task<ActionResult<XActionResponse>> AddAccountInfo(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.ActionToken,
|
|
model.UserName,
|
|
model.Password)
|
|
.AddNotNull(model.Device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Request ...
|
|
var result = await IdentityManager
|
|
.AddAcountInfo(
|
|
model.Lang,
|
|
model.Device,
|
|
model.ActionToken,
|
|
model.UserName,
|
|
model.Password);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload and Attach a Profile Image for User. this is an Optional Step
|
|
/// </summary>
|
|
/// <param name="actionToken">user's requested action token</param>
|
|
/// <param name="file">an instance of <see>IFormFile</see> for user's Avatar</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("AttachProfileImage")]
|
|
public async Task<ActionResult<XActionResponse>> AttachProfileImage(
|
|
[FromForm] string actionToken, [FromForm] IFormFile file
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(actionToken)
|
|
.AddNotNull(file)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var result = await IdentityManager
|
|
.AttachProfileImage(actionToken, file);
|
|
|
|
//
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
return exResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finish Registrationn Proccess
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// for this action you have to provide:
|
|
/// - a proper User Identifier such as: (UserId, UserName, Email or MobileNumber).
|
|
/// - Lang: client device currently used locale, such as: en-US.
|
|
/// - ActionToken: user's requested action token for this action.
|
|
/// - Password: assigne password.
|
|
/// - Device: user's client device which is an instance of XDevice.
|
|
/// - ReturnUrl: client application Login URL.
|
|
///
|
|
/// Sample request:
|
|
///
|
|
/// {
|
|
/// "lang": "fa-IR",
|
|
/// "userName": "",
|
|
/// "password": "",
|
|
/// "returnUrl": "",
|
|
/// "device": {
|
|
/// "os":"Mac",
|
|
/// "browser":"Chrome",
|
|
/// "osVersion":"mac-os-x-15",
|
|
/// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36",
|
|
/// "deviceType":3,
|
|
/// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]",
|
|
/// "token":"96f400dd9aa5c57a8cec9d6f4775bad3"
|
|
/// }
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
|
/// <returns></returns>
|
|
[AllowAnonymous]
|
|
[RequireXPowered]
|
|
[HttpPost("FinishRegistration")]
|
|
public async Task<ActionResult> FinishRegistration(
|
|
[FromBody] XActionRequest model
|
|
)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!ModelState.IsValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
model.Lang,
|
|
model.Password,
|
|
model.ReturnUrl)
|
|
.AddNotNull(model.Device)
|
|
.AddUrl(model.ReturnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
var userSelectByParam = IdentityManager
|
|
.GetUserSelectByParam(model);
|
|
ValidationProvider
|
|
.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Get Request ...
|
|
await IdentityManager
|
|
.FinishRegistration(
|
|
model.Lang,
|
|
model.Device,
|
|
userSelectByParam,
|
|
model.Password,
|
|
model.ReturnUrl
|
|
);
|
|
|
|
//
|
|
return Ok();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exResult = GetExceptionActionResult(ex);
|
|
|
|
//
|
|
return exResult;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Search.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Attributes;
|
|
using xCommons.Extensions;
|
|
using xIdentityHelper;
|
|
using xIdentityModels.Dtos;
|
|
using xModels.Dtos;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Actions which related to Search and Suggest Users for
|
|
/// Friendship or Detecting ...
|
|
/// </summary>
|
|
public partial class AccountController
|
|
{
|
|
//
|
|
#region Actions of Search ...
|
|
/// <summary>
|
|
/// Query Open To Search Users Profiles ...
|
|
/// Query all Users Which their Profiles is Open To Search ...
|
|
/// </summary>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
[RequireXPowered]
|
|
[HttpGet("OpenToSearch/Query")]
|
|
[Authorize(Policy = LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public async Task<ActionResult<XQueryResult<XUserProfileDto>>> QueryOpenToSearchProfiles(
|
|
[FromQuery] XQuery query)
|
|
{
|
|
//
|
|
// Do Action ...
|
|
try
|
|
{
|
|
//
|
|
var userId = User.Identity.Name;
|
|
|
|
//
|
|
var result = await IdentityManager.QueryOpenToSearchUsers(
|
|
userId,
|
|
query
|
|
);
|
|
|
|
return Ok(result
|
|
.ToDynamicObject());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionActionResult(ex);
|
|
return exception;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Account\AccountController+Test.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xIdentityHelper;
|
|
using xCommons.Attributes;
|
|
using static IdentityServer4.IdentityServerConstants;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
public partial class AccountController
|
|
{
|
|
|
|
//
|
|
#region Test Actions ...
|
|
/// <summary>
|
|
/// API Read Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[RequireXPowered]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[HttpGet("Test/PassReadAccess")]
|
|
[Authorize(Policy = XPolicies.ReadAccess)]
|
|
public ActionResult<string> PassReadAccess()
|
|
{
|
|
return Ok("Read Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Write Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[RequireXPowered]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[HttpGet("Test/PassWriteAccess")]
|
|
[Authorize(Policy = XPolicies.WriteAccess)]
|
|
public ActionResult<string> PassWriteAccess()
|
|
{
|
|
return Ok("Write Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Admin Scope
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[RequireXPowered]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[HttpGet("Test/PassAdminAccess")]
|
|
[Authorize(Policy = XPolicies.AdminAccess)]
|
|
public ActionResult<string> PassAdminAccess()
|
|
{
|
|
return Ok("Admin Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// API Manage Scop
|
|
/// </summary>
|
|
/// <returns>string message</returns>
|
|
[RequireXPowered]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[HttpGet("Test/PassManageAccess")]
|
|
[Authorize(Policy = XPolicies.ManageAccess)]
|
|
public ActionResult<string> PassManageAccess()
|
|
{
|
|
return Ok("Manage Access Passed ...");
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Action which returns a List of Authenticated User Claims
|
|
/// </summary>
|
|
/// <returns>string message which represent current user's claims</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Test/HiClaims")]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
public ActionResult<string> HiClaims()
|
|
{
|
|
//
|
|
var result = new
|
|
{
|
|
name = User.Identity.Name,
|
|
claims = User.Claims.Select(c => new
|
|
{
|
|
c.Type,
|
|
c.Value
|
|
})
|
|
};
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Test/HiUser")]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.User)]
|
|
public ActionResult<string> HiUser()
|
|
{
|
|
//
|
|
var result = $"Hi User: {User.Identity.Name} ...";
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Test/HiEnabledUser")]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledUser)]
|
|
public ActionResult<string> HiEnabledUser()
|
|
{
|
|
//
|
|
var result = $"Hi User: {User.Identity.Name} is Enabled ...";
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Test/HiAdmin")]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.Admin)]
|
|
public ActionResult<string> HiAdmin()
|
|
{
|
|
//
|
|
var result = $"Hi Admin: {User.Identity.Name} ...";
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// a simple Hello User for Checking Authentication and Policy
|
|
/// </summary>
|
|
/// <returns>string message which contains authenticated user name</returns>
|
|
[RequireXPowered]
|
|
[HttpGet("Test/HiEnabledAdmin")]
|
|
[Authorize(LocalApi.PolicyName)]
|
|
[Authorize(Policy = XPolicies.EnabledAdmin)]
|
|
public ActionResult<string> HiEnabledAdmin()
|
|
{
|
|
//
|
|
var result = $"Hi Admin: {User.Identity.Name} is Enabled ...";
|
|
|
|
//
|
|
return Ok(result);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\Base\XIBaseController.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Constants;
|
|
using xCommons.Controllers;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Controllers.Base
|
|
{
|
|
public abstract class XIBaseController : XBaseController
|
|
{
|
|
public IXIdentityManager IdentityManager { get; }
|
|
|
|
protected XIBaseController(
|
|
ILogger logger,
|
|
XAppConfiguration appConfiguration,
|
|
IXIdentityManager identityManager,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{
|
|
IdentityManager = identityManager;
|
|
}
|
|
|
|
//
|
|
#region User Handlers NonActions ...
|
|
/// <summary>
|
|
/// Retrieve User Identifier Base on XActionRequest
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var result = IdentityManager.GetUserSelectByParam(
|
|
model,
|
|
forceNotNull,
|
|
excludes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<string> GetAccessToken()
|
|
{
|
|
//
|
|
var accessToken = Request.Headers[XAuthorization.Header].ToString();
|
|
if (accessToken.IsNullOrEmpty())
|
|
{
|
|
accessToken = await HttpContext.GetTokenAsync(XAuthorization.AccessToken);
|
|
}
|
|
|
|
//
|
|
if (accessToken
|
|
.ToNormalString()
|
|
.Contains(XAuthorization.TokenIdentifier.ToNormalString()))
|
|
{
|
|
accessToken = accessToken.Remove(0, XAuthorization.TokenIdentifier.Length);
|
|
}
|
|
|
|
//
|
|
Logger.LogInformation($"Token: {accessToken}");
|
|
return accessToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Refresh Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<string> GetRefreshToken()
|
|
{
|
|
//
|
|
var refreshToken = Request.Headers[XAuthorization.RefreshToken].ToString();
|
|
if (refreshToken.IsNullOrEmpty())
|
|
{
|
|
refreshToken = await HttpContext.GetTokenAsync(XAuthorization.RefreshToken);
|
|
}
|
|
|
|
//
|
|
Logger.LogInformation($"Refresh Token: {refreshToken}");
|
|
return refreshToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Access Token Expiration Date
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<long> GetTokenExpiresAt()
|
|
{
|
|
//
|
|
var expiresAtStr = Request.Headers[XAuthorization.ExpiresAt].ToString();
|
|
if (expiresAtStr.IsNullOrEmpty())
|
|
{
|
|
expiresAtStr = await HttpContext.GetTokenAsync(XAuthorization.ExpiresAt);
|
|
}
|
|
|
|
//
|
|
var expiresAt = expiresAtStr.ConvertTo<long>();
|
|
|
|
//
|
|
Logger.LogInformation($"Token ExpiresAt: {expiresAtStr}");
|
|
return expiresAt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Required Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XLoginResponse> RetrieveTokensAsXLoginResponse()
|
|
{
|
|
//
|
|
var accessToken = await GetAccessToken();
|
|
var refreshToken = await GetRefreshToken();
|
|
var expiresAt = await GetTokenExpiresAt();
|
|
|
|
//
|
|
return new XLoginResponse
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve All Required Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XTokenResponse> RetrieveTokensAsXTokenResponse()
|
|
{
|
|
//
|
|
var accessToken = await GetAccessToken();
|
|
var refreshToken = await GetRefreshToken();
|
|
var expiresAt = await GetTokenExpiresAt();
|
|
|
|
//
|
|
return new XTokenResponse
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrive UserInfo
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XUserClaimsInfoDto> GetUserInfo()
|
|
{
|
|
//
|
|
var claims = User.Claims ?? null;
|
|
if (!claims.HasChild())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var xTokens = await RetrieveTokensAsXTokenResponse();
|
|
var result = new XUserClaimsInfoDto(
|
|
xTokens.AccessToken,
|
|
xTokens.RefreshToken,
|
|
xTokens.ExpiresAt,
|
|
User.Claims
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate User Authenticated and Retrieve User Info
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public async Task<XUserClaimsInfoDto> ValidateAndGetUserInfo()
|
|
{
|
|
//
|
|
if (!User.Identity.IsAuthenticated)
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserInfo();
|
|
if (result.IsNull())
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region NonActions ...
|
|
/// <summary>
|
|
/// Convert an Exception to Propper Error Result
|
|
/// </summary>
|
|
/// <param name="ex"></param>
|
|
/// <returns></returns>
|
|
[NonAction]
|
|
public new ActionResult GetExceptionActionResult(Exception ex)
|
|
{
|
|
//
|
|
var exception = GetExceptionResult(ex);
|
|
var error = ex.Message.ToXError();
|
|
|
|
//
|
|
Logger.LogError($"exception: {exception}, error: {error}");
|
|
|
|
//
|
|
try
|
|
{
|
|
var xError = exception.Message.ToXError();
|
|
var xException = (XException)xError.Id;
|
|
|
|
//
|
|
switch (xException)
|
|
{
|
|
//
|
|
case XException.NotFound:
|
|
return NotFound(error);
|
|
|
|
//
|
|
case XException.NotAuthorized:
|
|
return Unauthorized(error);
|
|
}
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
return BadRequest(error);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\AccountController.cs
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Providers;
|
|
using xIds.Controllers.Base;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Provide all available tools for manipulating users and accounts
|
|
/// </summary>
|
|
[ApiController]
|
|
public partial class AccountController : XIBaseController
|
|
{
|
|
|
|
public AccountController(
|
|
IXIdentityManager identityManager,
|
|
ILogger<AccountController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
identityManager,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Controllers\StartupController.cs
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Configurations;
|
|
using xCommons.Controllers;
|
|
using xCommons.Providers;
|
|
|
|
namespace xIds.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Startup and Running Controller
|
|
/// </summary>
|
|
[Route("")]
|
|
[AllowAnonymous]
|
|
public class StartupController : XBaseController
|
|
{
|
|
public StartupController(
|
|
ILogger<StartupController> logger,
|
|
XAppConfiguration appConfiguration,
|
|
XValidationProvider validationProvider
|
|
) : base(
|
|
logger,
|
|
appConfiguration,
|
|
validationProvider
|
|
)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Show Configured Welcome Message
|
|
/// </summary>
|
|
/// <returns>an string message</returns>
|
|
[HttpGet("")]
|
|
[AllowAnonymous]
|
|
public virtual ActionResult<string> Index()
|
|
{
|
|
//
|
|
var controllerName = GetControllerName();
|
|
var message = $"{AppConfiguration.WelcomeMessage}";
|
|
|
|
//
|
|
return Ok(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\DbContext\XIdentityDbContext.cs
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.DbContext
|
|
{
|
|
public class XIdentityDbContext : IdentityDbContext
|
|
{
|
|
//
|
|
#region Props/DbSets ...
|
|
public DbSet<XToken> Tokens { get; set; }
|
|
public DbSet<XDevice> Devices { get; set; }
|
|
public DbSet<XProfileImage> Avatars { get; set; }
|
|
public DbSet<XBannedDevice> BannedDevices { get; set; }
|
|
public DbSet<XFriendshipFollower> Followers { get; set; }
|
|
public DbSet<XFriendshipFollowing> Followings { get; set; }
|
|
public DbSet<XVerificationRequest> VerificationRequests { get; set; }
|
|
#endregion
|
|
|
|
public XIdentityDbContext(DbContextOptions<XIdentityDbContext> options) : base(options)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
Database.EnsureCreated();
|
|
Database.Migrate();
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
//
|
|
base.OnModelCreating(modelBuilder);
|
|
|
|
//
|
|
// Fix XUser GUID Generator on Add ...
|
|
modelBuilder
|
|
.Entity<IdentityUser>()
|
|
.Property(e => e.Id)
|
|
.ValueGeneratedOnAdd();
|
|
|
|
//
|
|
// Handle Role List ...
|
|
modelBuilder.Entity<XUser>(u =>
|
|
{
|
|
u.HasMany(x => x.Roles)
|
|
.WithOne()
|
|
.HasForeignKey(ur => ur.UserId)
|
|
.IsRequired();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\DI\XDIHelperExtension.cs
|
|
|
|
using System.Collections.Generic;
|
|
using IdentityServer4;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Authorization;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityHelper;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Configurations;
|
|
using xIds.Configurations;
|
|
using xIds.Constants;
|
|
using xIds.DbContext;
|
|
using xIds.Extensions;
|
|
using xIds.Helpers;
|
|
using xIds.Interfaces;
|
|
using xIds.Providers;
|
|
using xIds.Validators;
|
|
using xMessageService.DI;
|
|
using xMessageService.Interfaces;
|
|
using xStorageService.DI;
|
|
using xStorageService.Interfaces;
|
|
|
|
namespace xIds.DI
|
|
{
|
|
public static class XDIHelperExtension
|
|
{
|
|
/// <summary>
|
|
/// Register Application DataProvider
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXDataProvider(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
// Retrieve DbInfo ...
|
|
var dbInfo = configuration.GetXDbInfo();
|
|
var identityDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.IDENTITY_CONNECTION_NAME);
|
|
|
|
//
|
|
// Register Db Context for EF ...
|
|
services.AddDbContext<XIdentityDbContext>(builder =>
|
|
{
|
|
//
|
|
builder.PrepareXDbContextOptionsBuilder(
|
|
dbInfo,
|
|
identityDbConnectionString
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <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>
|
|
/// Retrive XDataService Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="connectionName"></param>
|
|
/// <returns></returns>
|
|
public static XDataServiceConfiguration GetXDataServiceConfiguration(
|
|
this IConfiguration source,
|
|
string connectionName = null
|
|
)
|
|
{
|
|
//
|
|
var xDataServiceConfigSection = source
|
|
.GetSection(Constants.ConfigurationNodeNames.DATA_SERVICE_NODE_NAME);
|
|
var result = xDataServiceConfigSection.Get<XDataServiceConfiguration>();
|
|
if (result.IsNull())
|
|
{
|
|
result = new XDataServiceConfiguration();
|
|
}
|
|
|
|
//
|
|
result.Provider = source.GetXDbProviderType();
|
|
result.ConnectionString = source.GetXConnectionString(connectionName);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XDataService Configuration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="connectionName"></param>
|
|
public static void AddXDataServiceConfiguration(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
string connectionName = null
|
|
)
|
|
{
|
|
//
|
|
var dataServiceConfiguration = configuration
|
|
.GetXDataServiceConfiguration(connectionName);
|
|
|
|
//
|
|
services.AddSingleton<XDataServiceConfiguration>(dataServiceConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register All Requirements For XIdentityServer Usage
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXIdentityServerRequirements(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
services.AddXDataProvider(configuration);
|
|
|
|
//
|
|
// Register XIdentityMessageProvider ...
|
|
services.AddXIdentityMessageProvider();
|
|
|
|
//
|
|
// Register IdentityManager Service ...
|
|
var xIdentityManager = services.GetRegisteredService<IXIdentityManager>();
|
|
if (xIdentityManager.IsNull())
|
|
{
|
|
services.AddXIdentityManager();
|
|
}
|
|
|
|
//
|
|
// Check XMessage Service Registered or not and Register it if not ...
|
|
var xMessageProvider = services.GetRegisteredService<IXMessageProvider>();
|
|
if (xMessageProvider.IsNull())
|
|
{
|
|
services.AddXMessageService(configuration);
|
|
}
|
|
|
|
//
|
|
// Check Storage Service Registered or not and Register it if not ...
|
|
var xStorageProvider = services.GetRegisteredService<IXStorageProvider>();
|
|
if (xStorageProvider.IsNull())
|
|
{
|
|
services.AddXStorageService(configuration);
|
|
}
|
|
|
|
//
|
|
// Register XIdentityConfiguration ...
|
|
var xIdentityConfiguration = configuration.GetXIdentityConfiguration();
|
|
services.AddSingleton<XIdentityConfiguration>(xIdentityConfiguration);
|
|
|
|
//
|
|
// Register XIdentityHelper ...
|
|
services.AddSingleton<IXIdentityHelper, XIdentityHelper>();
|
|
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
|
|
|
|
//
|
|
// Register Asp.net Identity ...
|
|
services.AddXIdentity();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add IdentityServer with Support of Ef
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddEfSupportXIdentityServer(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
// Register All Requirements ...
|
|
services.AddXIdentityServerRequirements(configuration);
|
|
|
|
//
|
|
// add DbSeeder Config ...
|
|
services.AddXDebSeederDescriptor(configuration);
|
|
|
|
//
|
|
// Retrieve Certificate ...
|
|
var identityServerSigningCertificate = configuration.GetCertificate(CertificatesConfigurations.CertificateNames.IdentityServerSigning);
|
|
|
|
//
|
|
// Retrieve DbInfo ...
|
|
var dbInfo = configuration.GetXDbInfo();
|
|
|
|
//
|
|
// Retrieve Connection String Names ...
|
|
var configDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.CONFIGURATION_CONNECTION_NAME);
|
|
var persistedGrantDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.PRESISTED_GRANTS_CONNECTION_NAME);
|
|
|
|
//
|
|
// Register IdentityServer ...
|
|
services.AddIdentityServer(options =>
|
|
{
|
|
//
|
|
options.Discovery.CustomEntries.Add("account_api", "~/account");
|
|
|
|
//
|
|
// options.Events.RaiseErrorEvents = true;
|
|
// options.Events.RaiseFailureEvents = true;
|
|
// options.Events.RaiseSuccessEvents = true;
|
|
// options.Events.RaiseInformationEvents = true;
|
|
})
|
|
.LoadSigningCredentialFrom(identityServerSigningCertificate)
|
|
.AddXDbProvider(configuration)
|
|
.AddAspNetIdentity<XUser>()
|
|
.AddProfileService<XIdentityProfileService>()
|
|
.AddResourceOwnerValidator<XResourceOwnerPasswordValidator>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// force app to use IdentityServer
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="logger"></param>
|
|
public static void UseXIdentityServer(
|
|
this IApplicationBuilder app,
|
|
ILogger logger
|
|
)
|
|
{
|
|
//
|
|
// Update XIdentityServer Configurations before Use Identity Server ...
|
|
app.SeedData(logger)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
//
|
|
// Use Identity Server ...
|
|
app.UseIdentityServer();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Asp.net Identity as User Store
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
public static void AddXIdentity(this IServiceCollection services)
|
|
{
|
|
//
|
|
var xIdentityConfiguration = services.GetRegisteredService<XIdentityConfiguration>();
|
|
if (xIdentityConfiguration.IsNull())
|
|
{
|
|
XException.InvalidConfiguration.Throw();
|
|
}
|
|
|
|
//
|
|
var xIdentityHelper = services.GetRegisteredService<IXIdentityHelper>();
|
|
if (xIdentityHelper.IsNull())
|
|
{
|
|
XException.InvalidConfiguration.Throw();
|
|
}
|
|
|
|
//
|
|
// Add Identity for User Persists ...
|
|
services.AddIdentity<XUser, IdentityRole>(options =>
|
|
{
|
|
//
|
|
var mLockoutSpan = xIdentityHelper.GetLockoutTimeSpan();
|
|
|
|
//
|
|
// Lockout Setting ...
|
|
options.Lockout.DefaultLockoutTimeSpan = mLockoutSpan;
|
|
options.Lockout.MaxFailedAccessAttempts = xIdentityConfiguration.Policy.Lockout.MaxFailedAccessAttempts;
|
|
options.Lockout.AllowedForNewUsers = xIdentityConfiguration.Policy.Lockout.AllowedForNewUsers;
|
|
|
|
//
|
|
// Password settings ...
|
|
options.Password.RequireDigit = xIdentityConfiguration.Policy.Password.RequireDigit;
|
|
options.Password.RequireLowercase = xIdentityConfiguration.Policy.Password.RequireLowercase;
|
|
options.Password.RequireNonAlphanumeric = xIdentityConfiguration.Policy.Password.RequireNonAlphanumeric;
|
|
options.Password.RequireUppercase = xIdentityConfiguration.Policy.Password.RequireUppercase;
|
|
options.Password.RequiredLength = xIdentityConfiguration.Policy.Password.RequiredLength;
|
|
options.Password.RequiredUniqueChars = xIdentityConfiguration.Policy.Password.RequiredUniqueChars;
|
|
|
|
//
|
|
// SignIn settings ...
|
|
options.SignIn.RequireConfirmedEmail = xIdentityConfiguration.Policy.SignIn.RequireConfirmedEmail;
|
|
options.SignIn.RequireConfirmedPhoneNumber = xIdentityConfiguration.Policy.SignIn.RequireConfirmedPhoneNumber;
|
|
|
|
//
|
|
// User settings ...
|
|
options.User.AllowedUserNameCharacters = xIdentityConfiguration.Policy.User.AllowedUserNameCharacters;
|
|
options.User.RequireUniqueEmail = xIdentityConfiguration.Policy.User.RequireUniqueEmail;
|
|
})
|
|
.AddEntityFrameworkStores<XIdentityDbContext>()
|
|
.AddDefaultTokenProviders();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register IdentityServer Based Authentication
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXIdentityServerAuthentication(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
services.AddXIdentityResourceConfiguration(configuration);
|
|
services.AddAuthentication()
|
|
.AddJwtBearer(options =>
|
|
{
|
|
//
|
|
options.SaveToken = true;
|
|
options.RequireHttpsMetadata = false;
|
|
|
|
//
|
|
options.ForwardDefault = XAuthentication.IDENTITY_SERVER_LOCAL_API;
|
|
})
|
|
.AddLocalApi();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register Authorization Policies
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="policies"></param>
|
|
public static void AddXAuthorization(
|
|
this IServiceCollection services,
|
|
IDictionary<string, AuthorizationPolicy> policies = null
|
|
)
|
|
{
|
|
//
|
|
services.AddAuthorization(options =>
|
|
{
|
|
//
|
|
if (!policies.IsNull())
|
|
{
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = policies.GetEnumerator())
|
|
{
|
|
while (policiesEnumerator.MoveNext())
|
|
{
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies();
|
|
if (!xPolicies.IsNull())
|
|
{
|
|
//
|
|
// Fill Policies ...
|
|
using (var policiesEnumerator = xPolicies.GetEnumerator())
|
|
{
|
|
while (policiesEnumerator.MoveNext())
|
|
{
|
|
var policyDescriptor = policiesEnumerator.Current;
|
|
options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add Local APi Policy ...
|
|
options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>
|
|
{
|
|
//
|
|
policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);
|
|
policy.RequireAuthenticatedUser();
|
|
});
|
|
});
|
|
|
|
//
|
|
services.AddSingleton<IAuthorizationHandler, RequiredRolesHandler>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use Forward Headers Options for resolving behind a proxy issues ...
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static void UseXForwardOptions(this IApplicationBuilder source)
|
|
{
|
|
//
|
|
var forwardOptions = new ForwardedHeadersOptions
|
|
{
|
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
|
|
RequireHeaderSymmetry = false
|
|
};
|
|
|
|
//
|
|
forwardOptions.KnownNetworks.Clear();
|
|
forwardOptions.KnownProxies.Clear();
|
|
|
|
//
|
|
// ref: https://github.com/aspnet/Docs/issues/2384
|
|
source.UseForwardedHeaders(forwardOptions);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\DbExtensions.cs
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using MySql.EntityFrameworkCore.Infrastructure;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Configurations;
|
|
using xIds.Configurations;
|
|
using xIds.Constants;
|
|
using xIds.Models;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class DbExtensions
|
|
{
|
|
/// <summary>
|
|
/// Retrieve Data Provider Type from Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XDbProviders GetXDbProviderType(this IConfiguration source)
|
|
{
|
|
//
|
|
var dbProvider = (source[$"{ConfigurationNodeNames.PROVIDER_NODE_NAME}"])
|
|
.ToNormalString();
|
|
|
|
//
|
|
return dbProvider == ProviderType.SQLServer.ToNormalString() ?
|
|
XDbProviders.SQLServer :
|
|
dbProvider == ProviderType.SQLite.ToNormalString() ?
|
|
XDbProviders.SQLite :
|
|
dbProvider == ProviderType.MySQL.ToNormalString() ?
|
|
XDbProviders.MySQL :
|
|
XDbProviders.None;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve AspNet Identity Configurations
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static XIdentityConfiguration GetXIdentityConfiguration(this IConfiguration source)
|
|
{
|
|
//
|
|
var xIdentityConfigSection = source
|
|
.GetSection(ConfigurationNodeNames.IDENTITY_NODE_NAME);
|
|
return xIdentityConfigSection.Get<XIdentityConfiguration>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve XIdentityResource Configuration from AppSettings
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XIdentityResourceConfiguration GetXIdentityResourceConfiguration(this IConfiguration configuration)
|
|
{
|
|
//
|
|
var xIdentityResourceSection = configuration.GetSection(ConfigurationNodeNames.IDENTITY_RESOURCE_NODE_NAME);
|
|
return xIdentityResourceSection.Get<XIdentityResourceConfiguration>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XIdentityResourceConfiguration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXIdentityResourceConfiguration(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
var xIdentityResourceConfiguration = configuration.GetXIdentityResourceConfiguration();
|
|
if (!xIdentityResourceConfiguration.IsNull())
|
|
{
|
|
services.AddSingleton<XIdentityResourceConfiguration>(xIdentityResourceConfiguration);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts DbInfo Options Builder for MySql Usage
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<MySQLDbContextOptionsBuilder> GetMySqlOptionsBuilder(this XDbInfo source)
|
|
{
|
|
return ((Action<MySQLDbContextOptionsBuilder>)source.OptionsBuilder);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts DbInfo Options Builder for SQLite Usage
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<SqliteDbContextOptionsBuilder> GetSQLiteOptionsBuilder(this XDbInfo source)
|
|
{
|
|
return ((Action<SqliteDbContextOptionsBuilder>)source.OptionsBuilder);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts DbInfo Options Builder for SQLServer Usage
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <returns></returns>
|
|
public static Action<SqlServerDbContextOptionsBuilder> GetSQLServerOptionsBuilder(this XDbInfo source)
|
|
{
|
|
return ((Action<SqlServerDbContextOptionsBuilder>)source.OptionsBuilder);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Required Informations to Register DbContexts into Di as XDbInfo instance
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XDbInfo GetXDbInfo(this IConfiguration configuration)
|
|
{
|
|
return new XDbInfo
|
|
{
|
|
ProviderType = configuration.GetXDbProviderType(),
|
|
MigrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare DbContextOptionsBuilder with Propper data to Support Configured DbProvider
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="dbInfo"></param>
|
|
/// <param name="connectionString"></param>
|
|
public static void PrepareXDbContextOptionsBuilder(
|
|
this DbContextOptionsBuilder source,
|
|
XDbInfo dbInfo,
|
|
string connectionString
|
|
)
|
|
{
|
|
//
|
|
if (dbInfo.ProviderType == XDbProviders.MySQL)
|
|
{
|
|
//
|
|
// Add Support for MySql ...
|
|
source.UseMySQL(
|
|
connectionString,
|
|
dbInfo.GetMySqlOptionsBuilder()
|
|
);
|
|
}
|
|
else if (dbInfo.ProviderType == XDbProviders.SQLite)
|
|
{
|
|
//
|
|
// Add Support for SQLite ...
|
|
source.UseSqlite(
|
|
connectionString,
|
|
dbInfo.GetSQLiteOptionsBuilder()
|
|
);
|
|
}
|
|
else if (dbInfo.ProviderType == XDbProviders.SQLServer)
|
|
{
|
|
//
|
|
// Add Support for SQLServer ...
|
|
source.UseSqlServer(
|
|
connectionString,
|
|
dbInfo.GetSQLServerOptionsBuilder()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\IdentityExtensions.cs
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xIds.Interfaces;
|
|
using xIds.Providers;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class IdentityExtensions
|
|
{
|
|
/// <summary>
|
|
/// Register IdentityManager
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
public static void AddXIdentityManager(this IServiceCollection source)
|
|
{
|
|
source.AddScoped<IXIdentityManager, XIdentityManager>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register IdentityMessage Provider
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
public static void AddXIdentityMessageProvider(
|
|
this IServiceCollection source
|
|
)
|
|
{
|
|
source.AddScoped<IXIdentityMessageProvider, XIdentityMessageProvider>();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\IIdentityServerBuilderExtensions.cs
|
|
|
|
using System.Reflection;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using xCommons.Extensions;
|
|
using xCommons.Models;
|
|
using xIds.Constants;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class IIdentityServerBuilderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Add Support for Configured XDbProvider to IdentityServer
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static IIdentityServerBuilder AddXDbProvider(
|
|
this IIdentityServerBuilder source,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
// Retrieve DB Info ...
|
|
var dbInfo = configuration.GetXDbInfo();
|
|
dbInfo.OptionsBuilder = (optionsBuilder) =>
|
|
{
|
|
optionsBuilder.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
|
|
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
|
|
};
|
|
|
|
//
|
|
// Retrieve Connection String Names ...
|
|
var identityDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.IDENTITY_CONNECTION_NAME);
|
|
var configDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.CONFIGURATION_CONNECTION_NAME);
|
|
var persistedGrantDbConnectionString = configuration.GetConnectionString(ConnectionStringNames.PRESISTED_GRANTS_CONNECTION_NAME);
|
|
|
|
//
|
|
// Add Operational Store ...
|
|
source.AddOperationalStore(opt =>
|
|
{
|
|
opt.ConfigureDbContext =
|
|
builder =>
|
|
{
|
|
//
|
|
builder.PrepareXDbContextOptionsBuilder(
|
|
dbInfo,
|
|
persistedGrantDbConnectionString
|
|
);
|
|
|
|
//
|
|
builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
|
};
|
|
|
|
//
|
|
// this enables automatic token cleanup. this is optional.
|
|
opt.EnableTokenCleanup = true;
|
|
opt.TokenCleanupInterval = 3600;
|
|
});
|
|
|
|
//
|
|
// Add Configuration Store ...
|
|
source.AddConfigurationStore(opt =>
|
|
{
|
|
opt.ConfigureDbContext =
|
|
builder =>
|
|
{
|
|
//
|
|
builder.PrepareXDbContextOptionsBuilder(
|
|
dbInfo,
|
|
configDbConnectionString
|
|
);
|
|
};
|
|
});
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Configured Certificate File to IdentityServer
|
|
/// </summary>
|
|
/// <param name="builder"></param>
|
|
/// <param name="certificate"></param>
|
|
/// <returns></returns>
|
|
public static IIdentityServerBuilder LoadSigningCredentialFrom(
|
|
this IIdentityServerBuilder builder,
|
|
XCertificate certificate
|
|
)
|
|
{
|
|
//
|
|
if (!certificate.IsNull() &&
|
|
!certificate.Path.IsNullOrEmpty() &&
|
|
!certificate.Secret.IsNullOrEmpty()
|
|
)
|
|
{
|
|
try
|
|
{
|
|
builder.AddSigningCredential(new X509Certificate2(certificate.Path, certificate.Secret));
|
|
}
|
|
catch
|
|
{
|
|
builder.AddDeveloperSigningCredential();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
builder.AddDeveloperSigningCredential();
|
|
}
|
|
|
|
//
|
|
return builder;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\IQueryableExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Base;
|
|
using xIds.Constants;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class IQueryableExtensions
|
|
{
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\XDbSeederExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using IdentityServer4.EntityFramework.DbContexts;
|
|
using IdentityServer4.EntityFramework.Mappers;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Descriptors;
|
|
using xIdentityModels.Extensions;
|
|
using xIds.Constants;
|
|
using xIds.Interfaces;
|
|
using xIds.Models;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class XDbSeeder
|
|
{
|
|
/// <summary>
|
|
/// Retrieve DbSeedDescriptor from appSetting Configuration
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XDbSeedDescriptor GetXDbSeedDescriptor(this IConfiguration configuration)
|
|
{
|
|
//
|
|
var dbSeedSection = configuration.GetSection(ConfigurationNodeNames.DB_SEED_NODE_NAME);
|
|
return dbSeedSection.Get<XDbSeedDescriptor>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XDbSeedDescriptor as Singleton Service
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXDebSeederDescriptor(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
var dbSeedDescriptor = configuration.GetXDbSeedDescriptor();
|
|
if (!dbSeedDescriptor.IsNull())
|
|
{
|
|
services.AddSingleton<XDbSeedDescriptor>(dbSeedDescriptor);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Error: DbSeeder Configuration not found in AppSetting ...");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Base Required Data to XIdentitySer DbContexts
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
/// <param name="logger"></param>
|
|
/// <returns></returns>
|
|
public static async Task SeedData(
|
|
this IApplicationBuilder app,
|
|
ILogger logger
|
|
)
|
|
{
|
|
//
|
|
logger.LogInformation($"Start Add/Update XIdentityServer Descriptors ...");
|
|
|
|
//
|
|
// Create Scope ...
|
|
using (var scope = app.ApplicationServices.CreateScope())
|
|
{
|
|
//
|
|
// Retrieve Required Configurations ...
|
|
var dbSeedDescriptor = scope.ServiceProvider.GetService<XDbSeedDescriptor>();
|
|
if (dbSeedDescriptor.IsNull())
|
|
{
|
|
//
|
|
Console.WriteLine("DbSeeder is Null ...");
|
|
return;
|
|
}
|
|
logger.LogInformation($"Update Exists Descriptors: {dbSeedDescriptor.UpdateExists.ToString()}");
|
|
|
|
//
|
|
// Retrieve Required Services ...
|
|
var identityProvider = scope.ServiceProvider.GetService<IXIdentityManager>();
|
|
|
|
//
|
|
// Retrieve DbContexts ...
|
|
var grantDbContext = scope.ServiceProvider.GetService<PersistedGrantDbContext>();
|
|
var configDbContext = scope.ServiceProvider.GetService<ConfigurationDbContext>();
|
|
|
|
//
|
|
#region Clients ...
|
|
//
|
|
logger.LogInformation($"Start Seeding Clients ...");
|
|
|
|
//
|
|
var dClients = dbSeedDescriptor.Clients;
|
|
var hasClient = configDbContext.Clients.Any();
|
|
if ((!hasClient ||
|
|
(hasClient && dbSeedDescriptor.UpdateExists)) &&
|
|
dClients.HasChild())
|
|
{
|
|
//
|
|
var clientEntities = dClients.Select(dc => dc.ToEntity());
|
|
|
|
//
|
|
foreach (var client in clientEntities)
|
|
{
|
|
//
|
|
logger.LogInformation($"Add/Update: {client.ClientId}");
|
|
|
|
//
|
|
// Retrieve Exists Client ...
|
|
var existsClient = configDbContext.Clients
|
|
.Include(c => c.AllowedCorsOrigins)
|
|
.Include(c => c.AllowedGrantTypes)
|
|
.Include(c => c.AllowedScopes)
|
|
.Include(c => c.Claims)
|
|
.Include(c => c.ClientSecrets)
|
|
.FirstOrDefault(cl => cl.ClientId == client.ClientId);
|
|
|
|
//
|
|
var isExistsClient = !existsClient.IsNull();
|
|
var isSameContent = isExistsClient &&
|
|
existsClient.IsSameContent(client, propertyBlackList: new[] { nameof(existsClient.Id) });
|
|
|
|
//
|
|
if (isExistsClient)
|
|
{
|
|
//
|
|
if (!isSameContent)
|
|
{
|
|
//
|
|
logger.LogInformation($"Update Client: {existsClient.ClientId}");
|
|
|
|
//
|
|
existsClient = existsClient.UpdateData(client, propertyBlackList: new[] { nameof(existsClient.Id) });
|
|
configDbContext.Clients.Update(existsClient);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation($"Add Client: {client.ClientId}");
|
|
|
|
//
|
|
await configDbContext.Clients.AddAsync(client);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save Changes on Config Db Context ...
|
|
await configDbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Seeding Clients ...");
|
|
#endregion
|
|
|
|
//
|
|
#region IdentityResources ...
|
|
//
|
|
logger.LogInformation($"Start Seeding Identity Resources ...");
|
|
|
|
//
|
|
var dIdentityResources = dbSeedDescriptor.IdentityResources;
|
|
var hasIdentityResources = configDbContext.IdentityResources.Any();
|
|
if ((!hasIdentityResources ||
|
|
(hasIdentityResources && dbSeedDescriptor.UpdateExists)) &&
|
|
dIdentityResources.HasChild())
|
|
{
|
|
//
|
|
var identityResourceEntities = dIdentityResources.Select(di => di.ToEntity());
|
|
|
|
//
|
|
foreach (var identityResource in identityResourceEntities)
|
|
{
|
|
//
|
|
logger.LogInformation($"Add/Update: {identityResource.DisplayName}");
|
|
|
|
//
|
|
// Retrieve Exists IdentityResource ...
|
|
var existsIdentityResource = configDbContext.IdentityResources
|
|
.AsNoTracking()
|
|
.FirstOrDefault(ir => ir.Name == identityResource.Name);
|
|
|
|
//
|
|
var isExistsResource = !existsIdentityResource.IsNull();
|
|
var isSameContent = isExistsResource &&
|
|
existsIdentityResource.IsSameContent(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
|
|
|
|
//
|
|
if (isExistsResource &&
|
|
dbSeedDescriptor.UpdateExists)
|
|
{
|
|
//
|
|
if (!isSameContent)
|
|
{
|
|
//
|
|
logger.LogInformation($"Update IdentityResource: {identityResource.DisplayName}");
|
|
|
|
//
|
|
existsIdentityResource = existsIdentityResource.UpdateData(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
|
|
configDbContext.IdentityResources.Update(existsIdentityResource);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation($"Add IdentityResource: {identityResource.DisplayName}");
|
|
|
|
//
|
|
await configDbContext.IdentityResources.AddAsync(identityResource);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save Changes on Config Db Context ...
|
|
// await configDbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Seeding Identity Resources ...");
|
|
#endregion
|
|
|
|
//
|
|
#region Api Resources ...
|
|
//
|
|
logger.LogInformation($"Start Seeding Api Resources ...");
|
|
|
|
//
|
|
var dApiResources = dbSeedDescriptor.ApiResources;
|
|
var hasApiResources = configDbContext.ApiResources.Any();
|
|
if ((!hasApiResources ||
|
|
(hasApiResources && dbSeedDescriptor.UpdateExists)) &&
|
|
dApiResources.HasChild())
|
|
{
|
|
//
|
|
var apiResourceEntities = dApiResources.Select(da => da.ToEntity());
|
|
|
|
//
|
|
foreach (var apiResource in apiResourceEntities)
|
|
{
|
|
//
|
|
logger.LogInformation($"Add/Update: {apiResource.DisplayName}");
|
|
|
|
//
|
|
// Retrieve Exists ApiResource ...
|
|
var existsApiResource = configDbContext.ApiResources
|
|
.Include(r => r.Secrets)
|
|
.Include(r => r.Scopes)
|
|
.FirstOrDefault(ar => ar.Name == apiResource.Name);
|
|
|
|
//
|
|
var isExistsResource = !existsApiResource.IsNull();
|
|
var isSameContent = isExistsResource &&
|
|
existsApiResource.IsSameContent(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
|
|
|
|
//
|
|
if (isExistsResource &&
|
|
dbSeedDescriptor.UpdateExists)
|
|
{
|
|
//
|
|
if (!isSameContent)
|
|
{
|
|
//
|
|
logger.LogInformation($"Update ApiResource: {existsApiResource.DisplayName}");
|
|
|
|
//
|
|
existsApiResource = existsApiResource.UpdateData(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
|
|
configDbContext.ApiResources.Update(existsApiResource);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation($"Add ApiResource: {apiResource.DisplayName}");
|
|
|
|
//
|
|
await configDbContext.ApiResources.AddAsync(apiResource);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save Changes on Config Db Context ...
|
|
// await configDbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Seeding Api Resources ...");
|
|
#endregion
|
|
|
|
//
|
|
#region Api Scopes ...
|
|
//
|
|
logger.LogInformation($"Start Seeding Scopes ...");
|
|
|
|
//
|
|
var dScopes = dbSeedDescriptor.ApiScopes;
|
|
var hasScope = configDbContext.ApiScopes.Any();
|
|
if ((!hasScope ||
|
|
(hasScope && dbSeedDescriptor.UpdateExists)) &&
|
|
dScopes.HasChild())
|
|
{
|
|
//
|
|
var apiScopeEntities = dScopes.Select(dc => dc.ToEntity());
|
|
|
|
//
|
|
foreach (var apiScope in apiScopeEntities)
|
|
{
|
|
//
|
|
logger.LogInformation($"Add/Update: {apiScope.DisplayName}");
|
|
|
|
//
|
|
// Retrieve Exists Client ...
|
|
var existsScope = configDbContext.ApiScopes
|
|
.FirstOrDefault(sc => sc.Name == apiScope.Name);
|
|
|
|
//
|
|
var isExistsScope = !existsScope.IsNull();
|
|
var isSameContent = isExistsScope &&
|
|
existsScope.IsSameContent(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
|
|
|
|
//
|
|
if (isExistsScope &&
|
|
dbSeedDescriptor.UpdateExists)
|
|
{
|
|
//
|
|
if (!isSameContent)
|
|
{
|
|
//
|
|
logger.LogInformation($"Update ApiScope: {existsScope.Name}");
|
|
|
|
//
|
|
existsScope = existsScope.UpdateData(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
|
|
configDbContext.ApiScopes.Update(existsScope);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation($"Add ApiScope: {apiScope.Name}");
|
|
|
|
//
|
|
await configDbContext.ApiScopes.AddAsync(apiScope);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save Changes on Config Db Context ...
|
|
await configDbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Seeding Scopes ...");
|
|
#endregion
|
|
|
|
//
|
|
#region Users ...
|
|
//
|
|
logger.LogInformation($"Start Seeding Users ...");
|
|
|
|
//
|
|
var configUsers = dbSeedDescriptor.Users;
|
|
var hasUser = identityProvider.GetUsersDbSet().Any();
|
|
if ((!hasUser ||
|
|
(hasUser && dbSeedDescriptor.UpdateExists)) &&
|
|
configUsers.HasChild())
|
|
{
|
|
foreach (var user in configUsers)
|
|
{
|
|
//
|
|
logger.LogInformation($"Add/Update User: {user.UserName}");
|
|
|
|
//
|
|
var isUserExists = await identityProvider.IsUserExistsAsync(user.UserName);
|
|
if (isUserExists &&
|
|
dbSeedDescriptor.UpdateExists)
|
|
{
|
|
//
|
|
var existsUser = await identityProvider.GetUserAsync(user.UserName);
|
|
var isSame = existsUser.IsSameAs(user);
|
|
if (!isSame)
|
|
{
|
|
//
|
|
// Update Entity ...
|
|
existsUser = existsUser.UpdateData(user, propertyWhiteList: new[] {
|
|
nameof (XIdentityUserDescriptor.FirstName),
|
|
nameof (XIdentityUserDescriptor.LastName),
|
|
nameof (XIdentityUserDescriptor.UserName),
|
|
nameof (XIdentityUserDescriptor.Email),
|
|
nameof (XIdentityUserDescriptor.EmailConfirmed),
|
|
nameof (XIdentityUserDescriptor.PhoneNumber),
|
|
nameof (XIdentityUserDescriptor.PhoneNumberConfirmed),
|
|
nameof (XIdentityUserDescriptor.IsEnable),
|
|
nameof (XIdentityUserDescriptor.IsBanned),
|
|
nameof (XIdentityUserDescriptor.DateOfBirth)
|
|
}, propertyValueProviders: new[] {
|
|
new KeyValuePair<string, Func<XIdentityUserDescriptor, object>> (
|
|
nameof (XIdentityUserDescriptor.DateOfBirth),
|
|
(user) => DateTime.Parse (user.DateOfBirth))
|
|
});
|
|
|
|
//
|
|
await identityProvider.UpdateUserAsync(existsUser, false, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await identityProvider.CreateUserAsync(user);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Seeding Users ...");
|
|
#endregion
|
|
}
|
|
|
|
//
|
|
logger.LogInformation($"Finish Add/Update XIdentityServer Descriptors ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Extensions\XModelExtensions.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIds.Extensions
|
|
{
|
|
public static class XModelExtensions
|
|
{
|
|
/// <summary>
|
|
/// Determine a banned time is passed or not
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="delaySeconds"></param>
|
|
/// <returns></returns>
|
|
public static bool IsDelayTimePassed(
|
|
this XBannedDevice source,
|
|
int delaySeconds
|
|
)
|
|
{
|
|
//
|
|
var passedTime = source.BannedOn.AddSeconds(delaySeconds);
|
|
|
|
//
|
|
var result = DateTime.UtcNow >= passedTime;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applying Filter to IQueryable
|
|
/// /// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public static async Task<IQueryable<T>> ApplyFilterAsync<T>(
|
|
this IQueryable<T> source,
|
|
string filter
|
|
) where T : class
|
|
{
|
|
//
|
|
// Apply Filter ...
|
|
if (!filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var items = source.AsAsyncEnumerable();
|
|
var filteredItems = new List<T>();
|
|
await
|
|
foreach (var item in items)
|
|
{
|
|
//
|
|
if (item.GetPropValues()
|
|
.ToNormalString()
|
|
.Contains(filter
|
|
.ToNormalString()))
|
|
{
|
|
//
|
|
filteredItems.Add(item);
|
|
}
|
|
}
|
|
|
|
//
|
|
return filteredItems.AsQueryable();
|
|
}
|
|
|
|
//
|
|
return source;
|
|
}
|
|
|
|
public static XDataServiceConfiguration ToXDataServiceConfig(this Configurations.XDataServiceConfiguration config)
|
|
{
|
|
//
|
|
var result = new XDataServiceConfiguration();
|
|
|
|
//
|
|
if (!config.IsNullOrDefault())
|
|
{
|
|
//
|
|
result.PagingConfiguration.DefaultPageSize = config.PagingConfiguration.DefaultPageSize;
|
|
result.PagingConfiguration.MaxAvailablePageSize = config.PagingConfiguration.MaxAvailablePageSize;
|
|
result.PagingConfiguration.MinAvailablePageSize = config.PagingConfiguration.MinAvailablePageSize;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Helpers\XIdentityHelper.cs
|
|
|
|
using System;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Configurations;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Helpers
|
|
{
|
|
public class XIdentityHelper : IXIdentityHelper
|
|
{
|
|
private readonly XIdentityConfiguration configurations;
|
|
private readonly JwtSecurityTokenHandler tokenHandler;
|
|
private readonly XValidationProvider dataValidationHelper;
|
|
|
|
public XIdentityHelper(
|
|
XIdentityConfiguration configurations,
|
|
XValidationProvider dataValidationHelper
|
|
)
|
|
{
|
|
//
|
|
this.configurations = configurations;
|
|
this.tokenHandler = new JwtSecurityTokenHandler();
|
|
this.dataValidationHelper = dataValidationHelper;
|
|
}
|
|
|
|
//
|
|
#region Configuration Parser ...
|
|
/// <summary>
|
|
/// Generate a Key for Signing JWT Tokens
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SymmetricSecurityKey GetTokenSecretKey()
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotEmpty(configurations.IdentitySecretKey);
|
|
|
|
//
|
|
var result = new SymmetricSecurityKey(configurations
|
|
.IdentitySecretKey.ToBytes());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Security Token Signing Key
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SigningCredentials GetTokenSigningCredentials()
|
|
{
|
|
//
|
|
var key = GetTokenSecretKey();
|
|
dataValidationHelper
|
|
.NotNull(key);
|
|
|
|
//
|
|
var result = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Token Validation Parameters
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public TokenValidationParameters GetTokenValidationParams()
|
|
{
|
|
//
|
|
var key = GetTokenSecretKey();
|
|
var issuer = configurations.IdentityIssuer;
|
|
var audience = configurations.IdentityAudience;
|
|
|
|
//
|
|
dataValidationHelper
|
|
.NotNull(key);
|
|
dataValidationHelper
|
|
.NotEmpty(issuer, audience);
|
|
|
|
//
|
|
var result = new TokenValidationParameters
|
|
{
|
|
ValidIssuer = issuer,
|
|
ValidAudience = audience,
|
|
ValidateLifetime = true,
|
|
IssuerSigningKey = key
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Account Lockout Time Span after Max Fail Reached
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public TimeSpan GetLockoutTimeSpan()
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotNull(configurations.Policy, configurations.Policy.Lockout);
|
|
|
|
//
|
|
var timeSpanString = configurations.Policy.Lockout.LockoutTimeSpanProvider;
|
|
dataValidationHelper
|
|
.NotEmpty(timeSpanString);
|
|
|
|
//
|
|
var mExpireValue = 0;
|
|
var mExpireValueStr = timeSpanString.GetDigits();
|
|
var mExpireUnit = timeSpanString.Replace(mExpireValueStr, "");
|
|
dataValidationHelper
|
|
.NotEmpty(mExpireUnit);
|
|
dataValidationHelper
|
|
.NotEmpty(mExpireValueStr);
|
|
|
|
//
|
|
var isParsed = int.TryParse(mExpireValueStr, out mExpireValue);
|
|
|
|
//
|
|
switch (mExpireUnit)
|
|
{
|
|
case "d":
|
|
return TimeSpan.FromDays(mExpireValue);
|
|
|
|
case "h":
|
|
return TimeSpan.FromHours(mExpireValue);
|
|
|
|
case "m":
|
|
return TimeSpan.FromMinutes(mExpireValue);
|
|
|
|
case "s":
|
|
return TimeSpan.FromSeconds(mExpireValue);
|
|
|
|
case "ms":
|
|
default:
|
|
return TimeSpan.FromMilliseconds(mExpireValue);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Security Token Descriptor for Tokenize another
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SecurityTokenDescriptor GetActionTokenDescriptor()
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotNull(configurations);
|
|
|
|
//
|
|
var issuer = configurations.IdentityIssuer;
|
|
var audience = configurations.IdentityAudience;
|
|
dataValidationHelper
|
|
.NotEmpty(issuer, audience);
|
|
|
|
//
|
|
var expDate = GetActionTokenExpirationDate();
|
|
var signingCreds = GetTokenSigningCredentials();
|
|
dataValidationHelper
|
|
.NotNull(expDate, signingCreds);
|
|
|
|
//
|
|
var descriptor = new SecurityTokenDescriptor
|
|
{
|
|
Issuer = issuer,
|
|
Audience = audience,
|
|
Expires = expDate,
|
|
SigningCredentials = signingCreds
|
|
};
|
|
|
|
//
|
|
return descriptor;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Action Token Expiration Date
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public DateTime GetActionTokenExpirationDate()
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotNull(configurations);
|
|
|
|
//
|
|
var expDateProvider = configurations
|
|
.ActionTokenExpirationDateProvider;
|
|
dataValidationHelper
|
|
.NotEmpty(expDateProvider);
|
|
|
|
//
|
|
var result = GetExpirationTime(expDateProvider);
|
|
dataValidationHelper
|
|
.NotNull(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Action Token Handlers ...
|
|
public bool ValidateToken(string token)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
dataValidationHelper
|
|
.NotEmpty(token);
|
|
dataValidationHelper
|
|
.NotNull(tokenHandler);
|
|
|
|
//
|
|
// Prepare Requirements ...
|
|
var tokenValidationParams = GetTokenValidationParams();
|
|
dataValidationHelper
|
|
.NotNull(tokenValidationParams);
|
|
|
|
//
|
|
var result = token
|
|
.ValidateToken(tokenHandler, tokenValidationParams);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a Token string to SecurityToken instance
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public SecurityToken ToSecurityToken(string token)
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotEmpty(token);
|
|
|
|
//
|
|
// Validate token ...
|
|
var isTokenValid = ValidateToken(token);
|
|
if (!isTokenValid)
|
|
{
|
|
XException.InvalidToken.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare and Validate Requirements ...
|
|
var tokenValidationParams = GetTokenValidationParams();
|
|
dataValidationHelper
|
|
.NotNull(tokenHandler, tokenValidationParams);
|
|
|
|
//
|
|
var result = token
|
|
.ToSecurityToken(tokenHandler, tokenValidationParams);
|
|
dataValidationHelper
|
|
.NotNull(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an ActionRequest to Token Object
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
public SecurityToken ToSecurityToken(XActionRequestToken request)
|
|
{
|
|
//
|
|
var tokenDescriptor = GetActionTokenDescriptor();
|
|
|
|
//
|
|
dataValidationHelper.NotNull(request, tokenHandler, tokenDescriptor);
|
|
|
|
//
|
|
var result = request.ToJwtToken(tokenHandler, tokenDescriptor);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Token Exiration Date
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public DateTime GetTokenExpirationDate(string token)
|
|
{
|
|
//
|
|
var tokenObj = ToSecurityToken(token);
|
|
dataValidationHelper.NotNull(tokenObj);
|
|
|
|
//
|
|
var result = tokenObj.ValidTo;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public XActionRequestToken ParseActionRequestToken(string token)
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotEmpty(token);
|
|
|
|
//
|
|
// Validate token ...
|
|
var isTokenValid = ValidateToken(token);
|
|
if (!isTokenValid)
|
|
{
|
|
XException.InvalidToken.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare and Validate Requirements ...
|
|
var tokenValidationParams = GetTokenValidationParams();
|
|
dataValidationHelper
|
|
.NotNull(tokenHandler, tokenValidationParams);
|
|
|
|
//
|
|
var result = token
|
|
.ParseActionRequestToken(tokenHandler, tokenValidationParams);
|
|
dataValidationHelper
|
|
.NotNull(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a JWT Security Token Object to
|
|
/// it's String Representation
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public string ToTokenString(JwtSecurityToken token)
|
|
{
|
|
//
|
|
dataValidationHelper.NotNull(token);
|
|
|
|
//
|
|
var result = tokenHandler
|
|
.WriteToken(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an Action Token Object to it's String Representation
|
|
/// </summary>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public string ToTokenString(SecurityToken token)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
dataValidationHelper
|
|
.NotNull(token, tokenHandler);
|
|
|
|
//
|
|
// Generate and return Result ...
|
|
var result = token.ToTokenString(tokenHandler);
|
|
dataValidationHelper
|
|
.NotEmpty(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private Actions ...
|
|
/// <summary>
|
|
/// Calculating Date Difference Provider String
|
|
/// and Generate Date based on UTC Time
|
|
/// </summary>
|
|
/// <param name="expirationProvider"></param>
|
|
/// <returns></returns>
|
|
private DateTime GetExpirationTime(string expirationProvider)
|
|
{
|
|
//
|
|
dataValidationHelper
|
|
.NotEmpty(expirationProvider);
|
|
|
|
//
|
|
var mExpireValue = 0;
|
|
var mExpireValueStr = expirationProvider.GetDigits();
|
|
var mExpireUnit = expirationProvider.Replace(mExpireValueStr, "");
|
|
dataValidationHelper
|
|
.NotEmpty(mExpireUnit);
|
|
dataValidationHelper
|
|
.NotEmpty(mExpireValueStr);
|
|
|
|
//
|
|
var isParsed = int.TryParse(mExpireValueStr, out mExpireValue);
|
|
|
|
//
|
|
switch (mExpireUnit)
|
|
{
|
|
case "d":
|
|
return DateTime.UtcNow.AddDays(mExpireValue);
|
|
|
|
case "h":
|
|
return DateTime.UtcNow.AddHours(mExpireValue);
|
|
|
|
case "m":
|
|
return DateTime.UtcNow.AddMinutes(mExpireValue);
|
|
|
|
case "s":
|
|
return DateTime.UtcNow.AddSeconds(mExpireValue);
|
|
|
|
case "ms":
|
|
default:
|
|
return DateTime.UtcNow.AddMilliseconds(mExpireValue);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityHelper.cs
|
|
|
|
using System;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using xIdentityModels.Models;
|
|
|
|
namespace xIds.Interfaces
|
|
{
|
|
public interface IXIdentityHelper
|
|
{
|
|
//
|
|
#region Configuration Parser ...
|
|
SymmetricSecurityKey GetTokenSecretKey();
|
|
SigningCredentials GetTokenSigningCredentials();
|
|
TokenValidationParameters GetTokenValidationParams();
|
|
TimeSpan GetLockoutTimeSpan();
|
|
#endregion
|
|
|
|
//
|
|
#region Action Token Handlers ...
|
|
bool ValidateToken(string token);
|
|
SecurityToken ToSecurityToken(string token);
|
|
SecurityToken ToSecurityToken(XActionRequestToken request);
|
|
string ToTokenString(SecurityToken token);
|
|
string ToTokenString(JwtSecurityToken token);
|
|
DateTime GetTokenExpirationDate(string token);
|
|
XActionRequestToken ParseActionRequestToken(string token);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityManager.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Providers;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Descriptors;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xIds.DbContext;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIds.Interfaces
|
|
{
|
|
public interface IXIdentityManager
|
|
{
|
|
XIdentityDbContext DbContext { get; }
|
|
UserManager<XUser> UserManager { get; }
|
|
ILogger<IXIdentityManager> Logger { get; }
|
|
SignInManager<XUser> SignInManager { get; }
|
|
IXSecurityProvider SecurityProvider { get; }
|
|
RoleManager<IdentityRole> RoleManager { get; }
|
|
XValidationProvider ValidationProvider { get; }
|
|
|
|
//
|
|
#region Class Getter (s) Methods ...
|
|
IQueryable<XUser> GetUsersDbSet(
|
|
bool containsDetail = false
|
|
);
|
|
IQueryable<XUser> GetUsersFullDbSet(bool enableTracking = false);
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
);
|
|
|
|
Task<XUser> ValidateUserExistsAndRetrieve(
|
|
string userSelectByParam,
|
|
bool containsDetail = false,
|
|
bool checkCanLoginPolicies = false,
|
|
bool checkIsBanned = true,
|
|
bool ignoreDisabledUser = false,
|
|
bool forceAdmin = false,
|
|
Exception exception = null
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Default Identity Preparation Actions ...
|
|
Task CreateIdentityRoles();
|
|
Task CreateUserAsync(XIdentityUserDescriptor user);
|
|
#endregion
|
|
|
|
//
|
|
#region Identity Actions ...
|
|
HttpClient GetHttpClient();
|
|
Task<IdentityModel.Client.TokenResponse> RequestScopeAccessToken(string scope);
|
|
Task<DiscoveryDocumentResponse> RequestDiscoveryDocument();
|
|
Task<IdentityModel.Client.TokenResponse> Authenticate(XLoginRequest model);
|
|
Task<XLoginResponse> Login(XLoginRequest model);
|
|
Task<XTokenResponse> RefreshTokens(XTokenResponse model);
|
|
#endregion
|
|
|
|
//
|
|
#region Role Handlers ...
|
|
Task<bool> IsRoleExistsAsync(string roleName);
|
|
Task<IdentityResult> CreateRoleAsync(string roleName);
|
|
Task<IdentityRole> GetRoleAsync(string roleName);
|
|
Task<IdentityResult> AddUserToRoleAsync(XUser user, string roleName);
|
|
Task<string> GetRoleNameAsync(string roleId);
|
|
Task<IEnumerable<string>> GetRoleNamesAsync(
|
|
string userSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
Task<IdentityResult> RemoveFromRoleAsync(XUser user, string roleName);
|
|
Task<IdentityResult> RemoveFromRolesAsync(XUser user, IEnumerable<string> roleNames);
|
|
#endregion
|
|
|
|
//
|
|
#region User Handlers ...
|
|
Task<bool> CanRegister(string userSelectByParam);
|
|
Task<bool> IsUserExistsAsync(string userSelectByParam);
|
|
Task<XUser> GetUserAsync(
|
|
string userSelectByParam,
|
|
bool containsDetail = false);
|
|
|
|
Task<IdentityResult> CreateUserAsync(
|
|
XUser user,
|
|
string password,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
|
|
Task<IdentityResult> UpdateUserAsync(
|
|
XUser user,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
|
|
Task<IEnumerable<string>> GetUserNamesAsync(
|
|
IEnumerable<string> userIds
|
|
);
|
|
|
|
Task<IEnumerable<XUserNameIdResponse>> GetUserNameIdsAsync(
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<Claim[]> ToJwtClaims(
|
|
XUser user,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
|
|
Task<SignInResult> CheckPasswordSignInAsync(
|
|
XUser user,
|
|
string password,
|
|
XDevice device,
|
|
string language,
|
|
bool lockoutOnFailure,
|
|
bool isForced = true
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region User Profile Handlers ...
|
|
Task<XUserProfileDto> GetUserProfileAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
|
|
Task<XQueryResult<XUserProfileDto>> QueryUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query
|
|
);
|
|
|
|
Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
|
|
string requestedUserSelectByParam,
|
|
string role,
|
|
XQuery query,
|
|
bool forceRole = false
|
|
);
|
|
|
|
Task<IEnumerable<XUserProfileDto>> GetUserProfilesAsync(
|
|
ICollection<string> ids,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
|
|
Task<XQueryResult<XProfileImage>> QueryAvatars(
|
|
string userSelectByParam,
|
|
XQuery query
|
|
);
|
|
|
|
Task<XUserProfileDto> ProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest request
|
|
);
|
|
|
|
Task<XUserProfileDto> FullProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest request
|
|
);
|
|
|
|
Task<XActionResponse> RequestConfirmMobile(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string mobileNumber = null
|
|
);
|
|
|
|
Task<XActionResponse> RequestConfirmEmail(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string emailAddress = null
|
|
);
|
|
|
|
Task<XActionResponse> RequestResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string returnUrl
|
|
);
|
|
|
|
Task RequestConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string returnUrl
|
|
);
|
|
|
|
Task ChangePassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string newPassword,
|
|
string returnUrl
|
|
);
|
|
|
|
Task ResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string actionHash,
|
|
string newPassword,
|
|
string returnUrl
|
|
);
|
|
|
|
Task<XUserProfileDto> AddAvatar(
|
|
string userSelectByParam,
|
|
IFormFile file
|
|
);
|
|
|
|
Task<XUserProfileDto> AddAvatars(
|
|
string userSelectByParam,
|
|
IFormFileCollection files
|
|
);
|
|
|
|
Task<XUserProfileDto> SetAvatar(
|
|
string userSelectByParam,
|
|
int profileImageId
|
|
);
|
|
|
|
Task<XUserProfileDto> RemoveAvatar(
|
|
string userSelectByParam,
|
|
ICollection<int> profileImageIds
|
|
);
|
|
|
|
Task ConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string actionHash,
|
|
string returnUrl
|
|
);
|
|
|
|
Task<XActionResponse> ConfirmMobileNumber(
|
|
string lang,
|
|
XDevice device,
|
|
string registrationHash,
|
|
string verificationCode
|
|
);
|
|
|
|
Task<XActionResponse> ConfirmEmailAddress(
|
|
string lang,
|
|
XDevice device,
|
|
string registrationHash,
|
|
string verificationCode
|
|
);
|
|
|
|
Task<bool> IsConfirmedEmail(string userSelectByParam);
|
|
|
|
Task<bool> IsConfirmedMobile(string userSelectByParam);
|
|
#endregion
|
|
|
|
//
|
|
#region Registration Handlers ...
|
|
Task<XActionResponse> InviteUser(
|
|
string lang,
|
|
XDevice device,
|
|
string email,
|
|
string handlerUrl
|
|
);
|
|
|
|
Task<XActionResponse> RequestRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string invitationHash,
|
|
string firstName,
|
|
string lastName,
|
|
DateTime dateOfBirth,
|
|
string mobileNumber = null,
|
|
string emailAddress = null
|
|
);
|
|
|
|
Task<XActionResponse> AddAcountInfo(
|
|
string lang,
|
|
XDevice device,
|
|
string registrationHash,
|
|
string userName,
|
|
string password
|
|
);
|
|
|
|
Task<XActionResponse> AttachProfileImage(
|
|
string tokenHash,
|
|
IFormFile file
|
|
);
|
|
|
|
Task FinishRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string returnUrl
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship Handlers ...
|
|
//
|
|
#region Actions ...
|
|
Task<XFriendshipFollowing> Follow(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<bool> Cancel(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task UnFollowFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task UnFollowFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<XFriendshipFollowing> Block(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<XFriendshipFollowing> UnBlock(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Request Handlers ...
|
|
Task<XFriendshipFollower> AcceptRequest(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<XFriendshipFollower> RejectRequest(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Getters ...
|
|
Task<bool> IsFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
);
|
|
|
|
Task<XFriendshipState> GetFollowerState(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
);
|
|
|
|
Task<XFriendshipFollower> GetFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<IEnumerable<XFriendshipFollower>> GetFollowers(string userSelectByParam);
|
|
Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(string userSelectByParam);
|
|
Task<ICollection<string>> GetFollowersList(string userSelectByParam);
|
|
Task<XQueryResult<XFriendDto>> QueryFollowers(
|
|
XQuery query,
|
|
string userSelectByParam
|
|
);
|
|
|
|
Task<bool> IsFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
);
|
|
|
|
Task<XFriendshipState> GetFollowingState(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
);
|
|
|
|
Task<XFriendshipFollowing> GetFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
|
|
Task<IEnumerable<XFriendshipFollowing>> GetFollowings(string userSelectByParam);
|
|
Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(string userSelectByParam);
|
|
Task<ICollection<string>> GetFollowingList(string userSelectByParam);
|
|
Task<XQueryResult<XFriendDto>> QueryFollowings(
|
|
XQuery query,
|
|
string userSelectByParam
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
Task<XFriendshipInfoDto> GetFriendshipInfo(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Admin Actions ...
|
|
Task<ICollection<string>> Ban(
|
|
string userSelectByParam,
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<ICollection<string>> UnBan(
|
|
string userSelectByParam,
|
|
XUserNameIdRequest model
|
|
);
|
|
|
|
Task<bool> IsBanned(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Open Actions ...
|
|
//
|
|
#region OpenGet ...
|
|
Task<XOpenActionInnerDto> OpenGet(
|
|
XOpenActionInnerDto model
|
|
);
|
|
Task<XOpenActionInnerDto> OpenGet(
|
|
string token,
|
|
string actionRequest
|
|
);
|
|
#endregion
|
|
|
|
Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XOpenActionRequestDto dto
|
|
);
|
|
|
|
Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XOpenActionRequestDto dto
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Search ...
|
|
/// <summary>
|
|
/// Query Open To Search User Profiles ...
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query
|
|
);
|
|
#endregion
|
|
|
|
//
|
|
#region Query Service ...
|
|
/// <summary>
|
|
/// Retrieve Users as Query Model for Query Service ...
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam"></param>
|
|
/// <param name="query"></param>
|
|
/// <param name="role"></param>
|
|
/// <param name="forceRole"></param>
|
|
/// <returns></returns>
|
|
public Task<XQueryResult<string>> QueryUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query,
|
|
string role = null,
|
|
bool forceRole = false
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Interfaces\IXIdentityMessageProvider.cs
|
|
|
|
namespace xIds.Interfaces
|
|
{
|
|
public interface IXIdentityMessageProvider
|
|
{
|
|
string InviteMsg { get; }
|
|
string RegistrationApproveMsg { get; }
|
|
string RegisteredMsg { get; }
|
|
string VerificationCodeMsg { get; }
|
|
string ChangePasswordMsg { get; }
|
|
string PasswordChangedMsg { get; }
|
|
string NewDeviceLoggedInMsg { get; }
|
|
|
|
bool IsReady();
|
|
void PrepareMessages(string lang);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Interfaces\IXSecurityProvider.cs
|
|
|
|
namespace xIds.Interfaces
|
|
{
|
|
public interface IXSecurityProvider
|
|
{
|
|
string Encrypt(string plainText);
|
|
string Decrypt(string cipherText);
|
|
string EncryptFromBytes(byte[] textBytes);
|
|
string DecryptFromBytes(byte[] cipherBytes);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Models\XDbInfo.cs
|
|
|
|
using System;
|
|
using xIds.Constants;
|
|
|
|
namespace xIds.Models
|
|
{
|
|
public class XDbInfo
|
|
{
|
|
private string _migrationAssembly;
|
|
public XDbProviders ProviderType { get; set; }
|
|
public string MigrationsAssembly
|
|
{
|
|
get
|
|
{
|
|
return _migrationAssembly;
|
|
}
|
|
|
|
set
|
|
{
|
|
//
|
|
_migrationAssembly = value;
|
|
|
|
//
|
|
OptionsBuilder = b =>
|
|
{
|
|
b.MigrationsAssembly(value);
|
|
};
|
|
}
|
|
}
|
|
public Action<dynamic> OptionsBuilder { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Models\XDbSeedDescriptor.cs
|
|
|
|
using System.Collections.Generic;
|
|
using IdentityServer4.Models;
|
|
using xIdentityModels.Descriptors;
|
|
|
|
namespace xIds.Models
|
|
{
|
|
/// <summary>
|
|
/// the resource Descriptors for Using on DbSeed
|
|
/// </summary>
|
|
public class XDbSeedDescriptor
|
|
{
|
|
public bool UpdateExists { get; set; }
|
|
public ICollection<ApiScope> ApiScopes { get; set; }
|
|
public ICollection<ApiResource> ApiResources { get; set; }
|
|
public ICollection<IdentityResource> IdentityResources { get; set; }
|
|
public ICollection<Client> Clients { get; set; }
|
|
public ICollection<XIdentityUserDescriptor> Users { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Admin.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
#region Admin Actions ...
|
|
/// <summary>
|
|
/// Retrieve All UnBanned Users Identifiers
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> GetAllUnbanned(
|
|
ICollection<string> userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
var result = new List<string>();
|
|
if (!userSelectByParam.HasChild())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
foreach (var uParam in userSelectByParam)
|
|
{
|
|
//
|
|
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
|
|
if (!destUser.IsBanned)
|
|
{
|
|
result.Add(uParam);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get All Banned Users Identifiers
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> GetAllBanned(
|
|
ICollection<string> userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
var result = new List<string>();
|
|
if (!userSelectByParam.HasChild())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
foreach (var uParam in userSelectByParam)
|
|
{
|
|
//
|
|
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
|
|
if (destUser.IsBanned)
|
|
{
|
|
result.Add(uParam);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ban a Collection of Users
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> Ban(
|
|
string userSelectByParam,
|
|
XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
ValidationProvider.NotZeroChilds(model.Ids);
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: true,
|
|
checkIsBanned: true,
|
|
containDetails: false,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = new List<string>();
|
|
foreach (var uParam in model.Ids)
|
|
{
|
|
//
|
|
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
|
|
|
|
//
|
|
var isBanned = destUser.IsBanned;
|
|
if (!isBanned)
|
|
{
|
|
//
|
|
destUser.IsBanned = true;
|
|
|
|
//
|
|
await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
result.Add(destUser.Id);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// UnBan a Collection of Users
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represents user identifier list to Ban</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> UnBan(
|
|
string userSelectByParam,
|
|
XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
ValidationProvider.NotZeroChilds(model.Ids);
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: true,
|
|
checkIsBanned: true,
|
|
containDetails: false,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = new List<string>();
|
|
foreach (var uParam in model.Ids)
|
|
{
|
|
//
|
|
var destUser = await ValidateUserExistsAndRetrieve(uParam, checkIsBanned: false);
|
|
|
|
//
|
|
var isBanned = destUser.IsBanned;
|
|
if (isBanned)
|
|
{
|
|
//
|
|
destUser.IsBanned = false;
|
|
|
|
//
|
|
await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
result.Add(destUser.Id);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detrmines a User is Banned or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">destination user identifier which checked is banned or not</param>
|
|
/// <returns>a boolean value which represent user banned or not</returns>
|
|
public async Task<bool> IsBanned(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: false,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
var destUser = await ValidateUserExistsAndRetrieve(destUserSelectByParam, checkIsBanned: false);
|
|
|
|
//
|
|
var result = destUser.IsBanned;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Device.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xIds.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Device Actions ...
|
|
/// <summary>
|
|
/// Check a Device Exists or Not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsDeviceExistsAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
return await DbContext.Devices
|
|
.AnyAsync(d => d.IsSameAs(device));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add new Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public async Task<XDevice> AddDeviceAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isDeviceExists = await IsDeviceExistsAsync(device);
|
|
if (isDeviceExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
await DbContext.Devices
|
|
.AddAsync(device);
|
|
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
return device;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public Task<XDevice> GetDeviceAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
return DbContext.Devices
|
|
.FirstOrDefaultAsync(d =>
|
|
d.IsSameAs(device));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of User Related Devices
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a collection of <see>XDevice</see> instances which related to user</returns>
|
|
public async Task<ICollection<XDevice>> GetUserDevices(
|
|
string userSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate ARgs ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate And Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
// Check User Devices ...
|
|
if (!user.Devices.HasChild())
|
|
{
|
|
return new List<XDevice>();
|
|
}
|
|
|
|
//
|
|
return user.Devices;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Device is Exists in User's Devices or not
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public bool IsDeviceRelateDToUser(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
if (!user.Devices.HasChild())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = user.Devices.Any(d => d.IsSameAs(device));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Device is Exists in User's Devices or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsDeviceRelateDToUser(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
var userDevices = await GetUserDevices(
|
|
userSelectByParam,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
if (!userDevices.HasChild())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = userDevices.Any(d => d.IsSameAs(device));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Device to a User Related Devices
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> AddUserRelatedDevice(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isExists = user.Devices.Any(d =>
|
|
d.IsSameAs(device));
|
|
if (isExists)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//
|
|
user.Devices.Add(device);
|
|
try
|
|
{
|
|
var result = await UpdateUserAsync(user);
|
|
return result.Succeeded;
|
|
}
|
|
catch
|
|
{
|
|
throw XException.ActionFailed.ToException();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Device to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> AddUserRelatedDevice(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Check Device Related ...
|
|
var isDeviceRelatedToUser = await IsDeviceRelateDToUser(
|
|
userSelectByParam,
|
|
device,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned);
|
|
if (isDeviceRelatedToUser)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
// Add User Device ...
|
|
user.Devices.Add(device);
|
|
|
|
//
|
|
var result = await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
return result.Succeeded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Device from a User Related Devices List
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> RemoveUserRelatedDevice(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isRelated = IsDeviceRelateDToUser(user, device);
|
|
if (!isRelated)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var instanse = user.Devices
|
|
.FirstOrDefault(d =>
|
|
d.IsSameAs(device));
|
|
|
|
//
|
|
user.Devices.Remove(instanse);
|
|
|
|
//
|
|
var result = await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
return result.Succeeded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Device from a User Devices
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> RemoveUserRelatedDevice(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Validate user exists and Retrieve it based on userselectbyparam ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
return await RemoveUserRelatedDevice(
|
|
user,
|
|
device
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Banned Device Actions ...
|
|
/// <summary>
|
|
/// Check a Device is exists in Banned Devices or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsBannedDeviceExists(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var bannedDeviceEnumerable = DbContext.BannedDevices.AsAsyncEnumerable();
|
|
await
|
|
foreach (var bannedDevice in bannedDeviceEnumerable)
|
|
{
|
|
//
|
|
if (bannedDevice.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find First Banned Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public async Task<XBannedDevice> BannedDeviceFindOne(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await DbContext.BannedDevices
|
|
.FirstOrDefaultAsync(bd =>
|
|
bd.Device.IsSameAs(device)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Banned Device
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns></returns>
|
|
public async Task BannedDeviceRemove(
|
|
XBannedDevice model
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsBannedDeviceExists(model.Device);
|
|
if (!isExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var item = await BannedDeviceFindOne(model.Device);
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DbContext.BannedDevices.Remove(item);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Device is Banned or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsDeviceBanned(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await IsBannedDeviceExists(device);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specific Banned Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XBannedDevice</see></returns>
|
|
private async Task<XBannedDevice> GetBannedDevice(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await BannedDeviceFindOne(device);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Is a Banned Device passed Banning Time
|
|
/// </summary>
|
|
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsDelayTimePassed(
|
|
XBannedDevice bannedDevice
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (bannedDevice == null ||
|
|
Configuration == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var isPassed = bannedDevice
|
|
.IsDelayTimePassed(Configuration.BannedDeviceTimeout);
|
|
|
|
//
|
|
return isPassed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Passed Time from Banning Time of specific Device
|
|
/// </summary>
|
|
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns>an instance of <see>DateTime</see> which represent Passed Time</returns>
|
|
private DateTime GetPassedTime(
|
|
XBannedDevice bannedDevice
|
|
)
|
|
{
|
|
//
|
|
var result = bannedDevice.BannedOn
|
|
.AddSeconds(Configuration.BannedDeviceTimeout);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Friendship.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Friendship Actions ...
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Send a Follow Request for userSelectByParam to
|
|
/// destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> Follow(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
XFriendshipFollowing following = null;
|
|
XFriendshipFollower follower = null;
|
|
var isRequested = IsFollowRequested(xUser, xDestUser);
|
|
//
|
|
// Check Request Happens Or not ...
|
|
if (!isRequested)
|
|
{
|
|
//
|
|
following = new XFriendshipFollowing
|
|
{
|
|
UserId = xUser.Id,
|
|
DestId = xDestUser.Id,
|
|
State = XFriendshipState.Pending
|
|
};
|
|
|
|
//
|
|
follower = new XFriendshipFollower
|
|
{
|
|
UserId = xDestUser.Id,
|
|
DestId = xUser.Id,
|
|
State = XFriendshipState.Pending
|
|
};
|
|
|
|
//
|
|
xUser.Followings.Add(following);
|
|
xDestUser.Followers.Add(follower);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// if Request Done Before Must Check State ...
|
|
following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
follower = xDestUser.Followers.FirstOrDefault(f => f.DestId == xUser.Id);
|
|
if (following.IsNull() ||
|
|
follower.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
switch (following.State)
|
|
{
|
|
case XFriendshipState.Accepted:
|
|
case XFriendshipState.Blocked:
|
|
throw XException.NotAllowed.ToException();
|
|
|
|
case XFriendshipState.Rejected:
|
|
following.State = XFriendshipState.Pending;
|
|
follower.State = XFriendshipState.Pending;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
var canContinue = !following.IsNull() && !follower.IsNull();
|
|
if (!canContinue)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
await UpdateUserAsync(xUser);
|
|
await UpdateUserAsync(xDestUser);
|
|
|
|
//
|
|
var result = following;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cancel Following
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> Cancel(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
XFriendshipFollowing following = null;
|
|
XFriendshipFollower follower = null;
|
|
var isRequested = IsFollowRequested(xUser, xDestUser);
|
|
//
|
|
// Check Request Happens Or not ...
|
|
if (!isRequested)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// if Request Done Before Must Check State ...
|
|
following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
follower = xDestUser.Followers.FirstOrDefault(f => f.DestId == xUser.Id);
|
|
if (following.IsNull() ||
|
|
follower.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
switch (following.State)
|
|
{
|
|
case XFriendshipState.Accepted:
|
|
case XFriendshipState.Blocked:
|
|
throw XException.NotAllowed.ToException();
|
|
|
|
case XFriendshipState.Rejected:
|
|
case XFriendshipState.Pending:
|
|
DbContext.Followers.Remove(follower);
|
|
DbContext.Followings.Remove(following);
|
|
break;
|
|
}
|
|
|
|
//
|
|
var canContinue = !following.IsNull() && !follower.IsNull();
|
|
if (!canContinue)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// userSelectByParam remove friendship by it's Follower
|
|
/// destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns></returns>
|
|
public async Task UnFollowFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
ValidateIsFollowers(xUser, xDestUser);
|
|
|
|
//
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
f.State == XFriendshipState.Accepted);
|
|
var following = xDestUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
f.State == XFriendshipState.Accepted);
|
|
if (follower.IsNull() ||
|
|
following.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
DbContext.Followers.Remove(follower);
|
|
DbContext.Followings.Remove(following);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// userSelectByParam remove friendship by it's Followings
|
|
/// destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns></returns>
|
|
public async Task UnFollowFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
ValidateIsFollowings(xUser, xDestUser);
|
|
|
|
//
|
|
var following = xUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
f.State == XFriendshipState.Accepted);
|
|
var follower = xDestUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
f.State == XFriendshipState.Accepted);
|
|
if (follower.IsNull() ||
|
|
following.IsNull())
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
DbContext.Followers.Remove(follower);
|
|
DbContext.Followings.Remove(following);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// userSelectByParam Block it's follower destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> Block(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
// Validate XDestUser is Accepted Follower of XUser ...
|
|
ValidateIsFollowers(xUser, xDestUser);
|
|
|
|
//
|
|
// Retrieve FriendShip Models ...
|
|
var following = xDestUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Accepted
|
|
)
|
|
);
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Accepted
|
|
)
|
|
);
|
|
if (following.IsNull() ||
|
|
follower.IsNull())
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
follower.State = XFriendshipState.Blocked;
|
|
following.State = XFriendshipState.Blocked;
|
|
|
|
//
|
|
DbContext.Followers.Update(follower);
|
|
DbContext.Followings.Update(following);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
//
|
|
var result = following;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// userSelectByParam UnBlock it's follower destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> UnBlock(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
// Validate XDestUser is Accepted Follower of XUser ...
|
|
ValidateIsBlock(xUser, xDestUser);
|
|
|
|
//
|
|
// Retrieve FriendShip Models ...
|
|
var following = xDestUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Blocked
|
|
)
|
|
);
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Blocked
|
|
)
|
|
);
|
|
if (
|
|
following.IsNull() ||
|
|
follower.IsNull()
|
|
)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
follower.State = XFriendshipState.Accepted;
|
|
following.State = XFriendshipState.Accepted;
|
|
|
|
//
|
|
DbContext.Followers.Update(follower);
|
|
DbContext.Followings.Update(following);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
//
|
|
var result = following;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Request Handlers ...
|
|
/// <summary>
|
|
/// userSelectByParam Accept Follow Request of
|
|
/// destUserSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> AcceptRequest(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
// Validate Request Sent and in Pending State ...
|
|
ValidateFollowingRequestForAccept(xUser, xDestUser);
|
|
|
|
//
|
|
// Retrieve FriendShip Models ...
|
|
var following = xDestUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Pending ||
|
|
f.State == XFriendshipState.Rejected
|
|
)
|
|
);
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
(
|
|
f.State == XFriendshipState.Pending ||
|
|
f.State == XFriendshipState.Rejected
|
|
)
|
|
);
|
|
if (following.IsNull() ||
|
|
follower.IsNull())
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
follower.State = XFriendshipState.Accepted;
|
|
following.State = XFriendshipState.Accepted;
|
|
|
|
//
|
|
await UpdateUserAsync(xUser);
|
|
await UpdateUserAsync(xDestUser);
|
|
|
|
//
|
|
var result = follower;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reject a Follow Request of destUserSelectByParam
|
|
/// with userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> RejectRequest(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
// Validate Request Sent and in Pending State ...
|
|
ValidateFollowingRequest(xUser, xDestUser);
|
|
|
|
//
|
|
// Retrieve Pending Specified User Request Friendship models ...
|
|
var following = xDestUser.Followings
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xUser.Id &&
|
|
f.State == XFriendshipState.Pending);
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f =>
|
|
f.DestId == xDestUser.Id &&
|
|
f.State == XFriendshipState.Pending);
|
|
if (following.IsNull() ||
|
|
follower.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
follower.State = XFriendshipState.Rejected;
|
|
following.State = XFriendshipState.Rejected;
|
|
|
|
//
|
|
DbContext.Followers.Update(follower);
|
|
DbContext.Followings.Update(following);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
//
|
|
var result = follower;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Getters ...
|
|
/// <summary>
|
|
/// determines destUserSelectByParam is in followers of
|
|
/// userSelectByParam or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var result = IsFollowRequested(xDestUser, xUser, XFriendshipState.Accepted);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Friendship state of destUserSelectByParam
|
|
/// in Followers of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <returns>a member of <see>XFriendshipState</see></returns>
|
|
public async Task<XFriendshipState> GetFollowerState(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var isFollow = IsFollowRequested(xDestUser, xUser);
|
|
if (!isFollow)
|
|
{
|
|
return XFriendshipState.None;
|
|
}
|
|
|
|
//
|
|
var follower = xUser.Followers.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
if (follower.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return follower.State;
|
|
}
|
|
|
|
/// <summary>
|
|
/// get follower friendship model of destUserSelectByParam
|
|
/// in followers of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollower</see></returns>
|
|
public async Task<XFriendshipFollower> GetFollower(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var isFollow = IsFollowRequested(xDestUser, xUser);
|
|
if (!isFollow)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var follower = xUser.Followers
|
|
.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
if (follower.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = follower;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Accepted Followers list of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see> instances</returns>
|
|
public async Task<IEnumerable<XFriendshipFollower>> GetFollowers(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = xUser.Followers
|
|
.Where(f => f.State == XFriendshipState.Accepted);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Followers list of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of <see>XFriendshipFollower</see> instances</returns>
|
|
public async Task<IEnumerable<XFriendshipFollower>> GetAllFollowers(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = xUser.Followers;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read Specified User's Follower's List based on Query Model ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="userSelectByParam"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XFriendDto>> QueryFollowers(
|
|
XQuery query,
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(query);
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: false,
|
|
containDetails: false,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
|
|
//
|
|
// Prepare Query ...
|
|
|
|
//
|
|
if (query.PageSize < DataConfiguration
|
|
.PagingConfiguration
|
|
.MinAvailablePageSize)
|
|
{
|
|
//
|
|
query.PageSize = DataConfiguration
|
|
.PagingConfiguration
|
|
.DefaultPageSize;
|
|
}
|
|
|
|
//
|
|
if (query.PageSize > DataConfiguration
|
|
.PagingConfiguration
|
|
.MaxAvailablePageSize)
|
|
{
|
|
//
|
|
query.PageSize = DataConfiguration
|
|
.PagingConfiguration
|
|
.MaxAvailablePageSize;
|
|
}
|
|
|
|
//
|
|
// Prepare Enumerator ...
|
|
Expression<Func<XFriendshipFollower, bool>> whereClause = x => x.UserId == xUser.Id;
|
|
var enumerator = DbContext.Followers.AsAsyncEnumerable();
|
|
var resultItems = new List<XFriendDto>();
|
|
await foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
var isApproved = whereClause.Compile()(entity);
|
|
if (isApproved)
|
|
{
|
|
//
|
|
// Convert Approved Entity to Dto ...
|
|
// then Validate it and Add it to Results ...
|
|
var dto = await ToDto(entity);
|
|
if (!dto.IsNull())
|
|
{
|
|
resultItems.Add(dto);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enumerable ...
|
|
var result = resultItems.AsEnumerable();
|
|
|
|
//
|
|
// Count Total Items ...
|
|
var totalItemsCount = result.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
result = result.ApplyFilter(query.Filter);
|
|
}
|
|
|
|
//
|
|
// Count Filtered Items ...
|
|
var totalFilteredItemsCount = result.Count();
|
|
|
|
//
|
|
// Apply Paging ...
|
|
if (totalItemsCount > 0 &&
|
|
totalFilteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
if (!query.SortBy.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Since Sorting Based on Date is Very Important ...
|
|
// we have to do Sorting at first Time then
|
|
// try to apply Paging ...
|
|
result = result
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending)
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
// Apply Paging ...
|
|
result = result
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize)
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
// Calculating Page Count ...
|
|
int pagesCount = totalItemsCount / query.PageSize;
|
|
if (totalItemsCount % query.PageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
var queryResult = new XQueryResult<XFriendDto>
|
|
{
|
|
Page = query.Page,
|
|
TotalPages = pagesCount,
|
|
PageSize = query.PageSize,
|
|
TotalItems = totalItemsCount,
|
|
Items = result.AsEnumerable(),
|
|
TotalFilteredItems = totalFilteredItemsCount
|
|
};
|
|
|
|
//
|
|
return queryResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// determines destUserSelectByParam is in followings of
|
|
/// userSelectByParam or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var result = IsFollowRequested(xUser, xDestUser, XFriendshipState.Accepted);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Frindship State of destUserSelectByParam
|
|
/// in Followings of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <returns>a member of <see>XFriendshipState</see></returns>
|
|
public async Task<XFriendshipState> GetFollowingState(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkIsBanned = true,
|
|
bool checkCanLoginPolicies = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var isFollow = IsFollowRequested(xUser, xDestUser);
|
|
if (!isFollow)
|
|
{
|
|
return XFriendshipState.None;
|
|
}
|
|
|
|
//
|
|
var following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
if (following.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
return following.State;
|
|
}
|
|
|
|
/// <summary>
|
|
/// get following friendship model of destUserSelectByParam
|
|
/// in followings of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <returns>an instance of <see>XFriendshipFollowing</see></returns>
|
|
public async Task<XFriendshipFollowing> GetFollowing(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
// Validate Not Same Source and Dest Users ...
|
|
ValidateNotSameUsers(xUser, xDestUser);
|
|
|
|
//
|
|
var isFollow = IsFollowRequested(xUser, xDestUser);
|
|
if (!isFollow)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var following = xUser.Followings.FirstOrDefault(f => f.DestId == xDestUser.Id);
|
|
if (following.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = following;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve accepted Followings List of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see> instances</returns>
|
|
public async Task<IEnumerable<XFriendshipFollowing>> GetFollowings(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = xUser.Followings
|
|
.Where(f => f.State == XFriendshipState.Accepted);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Followings List of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of <see>XFriendshipFollowing</see> instances</returns>
|
|
public async Task<IEnumerable<XFriendshipFollowing>> GetAllFollowings(string userSelectByParam)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: true,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: true
|
|
);
|
|
|
|
//
|
|
var result = xUser.Followings;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read Specified User's Following's List based on Query Model ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <param name="userSelectByParam"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XFriendDto>> QueryFollowings(
|
|
XQuery query,
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(query);
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
checkIsBanned: false,
|
|
containDetails: false,
|
|
ignoreDisabledUser: false,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
|
|
//
|
|
// Prepare Query ...
|
|
|
|
//
|
|
if (query.PageSize < DataConfiguration
|
|
.PagingConfiguration
|
|
.MinAvailablePageSize)
|
|
{
|
|
//
|
|
query.PageSize = DataConfiguration
|
|
.PagingConfiguration
|
|
.DefaultPageSize;
|
|
}
|
|
|
|
//
|
|
if (query.PageSize > DataConfiguration
|
|
.PagingConfiguration
|
|
.MaxAvailablePageSize)
|
|
{
|
|
//
|
|
query.PageSize = DataConfiguration
|
|
.PagingConfiguration
|
|
.MaxAvailablePageSize;
|
|
}
|
|
|
|
//
|
|
// Prepare Enumerator ...
|
|
Expression<Func<XFriendshipFollowing, bool>> whereClause = x => x.UserId == xUser.Id;
|
|
var enumerator = DbContext.Followings.AsAsyncEnumerable();
|
|
var resultItems = new List<XFriendDto>();
|
|
await foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
var isApproved = whereClause.Compile()(entity);
|
|
if (isApproved)
|
|
{
|
|
//
|
|
// Convert Approved Entity to Dto ...
|
|
// then Validate it and Add it to Results ...
|
|
var dto = await ToDto(entity);
|
|
if (!dto.IsNull())
|
|
{
|
|
resultItems.Add(dto);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enumerable ...
|
|
var result = resultItems.AsEnumerable();
|
|
|
|
//
|
|
// Count Total Items ...
|
|
var totalItemsCount = result.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
result = result.ApplyFilter(query.Filter);
|
|
}
|
|
|
|
//
|
|
// Count Filtered Items ...
|
|
var totalFilteredItemsCount = result.Count();
|
|
|
|
//
|
|
// Apply Paging ...
|
|
if (totalItemsCount > 0 &&
|
|
totalFilteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
if (!query.SortBy.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Since Sorting Based on Date is Very Important ...
|
|
// we have to do Sorting at first Time then
|
|
// try to apply Paging ...
|
|
result = result
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending)
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
// Apply Paging ...
|
|
result = result
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize)
|
|
.ToList();
|
|
}
|
|
|
|
//
|
|
// Calculating Page Count ...
|
|
int pagesCount = totalItemsCount / query.PageSize;
|
|
if (totalItemsCount % query.PageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
var queryResult = new XQueryResult<XFriendDto>
|
|
{
|
|
Page = query.Page,
|
|
TotalPages = pagesCount,
|
|
PageSize = query.PageSize,
|
|
TotalItems = totalItemsCount,
|
|
Items = result.AsEnumerable(),
|
|
TotalFilteredItems = totalFilteredItemsCount
|
|
};
|
|
|
|
//
|
|
return queryResult;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Others ...
|
|
/// <summary>
|
|
/// Retrieve List Of All Followings User Id's
|
|
/// of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> GetFollowingList(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve followings List ...
|
|
var followings = await GetFollowings(userSelectByParam);
|
|
|
|
//
|
|
var result = followings.Select(f => f.DestId);
|
|
|
|
//
|
|
return result.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve List Of All Followers User Id's
|
|
/// of userSelectByParam
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <returns>a collection of user identifiers</returns>
|
|
public async Task<ICollection<string>> GetFollowersList(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate and Retrieve followings List ...
|
|
var followers = await GetFollowers(userSelectByParam);
|
|
|
|
//
|
|
var result = followers.Select(f => f.DestId);
|
|
|
|
//
|
|
return result.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// retrieve Friendship Info Model for Specific User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">caller user identifier</param>
|
|
/// <param name="destUserSelectByParam">dest user identifier</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an instance of <see>XFriendshipInfoDto</see></returns>
|
|
public async Task<XFriendshipInfoDto> GetFriendshipInfo(
|
|
string userSelectByParam,
|
|
string destUserSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
destUserSelectByParam
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xSourceUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
// Validate and Retrieve Dest User ...
|
|
var xDestUser = await ValidateUserExistsAndRetrieve(
|
|
destUserSelectByParam,
|
|
forceAdmin: false,
|
|
containDetails: true,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
var isSame = xSourceUser.Id == xDestUser.Id;
|
|
var isFollower = false;
|
|
var isFollowing = false;
|
|
var followerState = XFriendshipState.None;
|
|
var followingState = XFriendshipState.None;
|
|
|
|
//
|
|
if (!isSame)
|
|
{
|
|
//
|
|
isFollower = await IsFollower(
|
|
userSelectByParam,
|
|
destUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
isFollowing = await IsFollowing(
|
|
userSelectByParam,
|
|
destUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
followerState = await GetFollowerState(
|
|
userSelectByParam,
|
|
destUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
followingState = await GetFollowingState(
|
|
userSelectByParam,
|
|
destUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
}
|
|
|
|
//
|
|
var result = new XFriendshipInfoDto
|
|
{
|
|
UserId = xDestUser.Id,
|
|
IsFollower = isFollower,
|
|
IsFollowing = isFollowing,
|
|
FollowerState = followerState,
|
|
FollowingState = followingState,
|
|
Followers = xDestUser.Followers
|
|
.Count(f => f.State == XFriendshipState.Accepted),
|
|
Followings = xDestUser.Followings
|
|
.Count(f => f.State == XFriendshipState.Accepted)
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Identity.cs
|
|
|
|
using System;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel.Client;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xExceptions.Models;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIds.Extensions;
|
|
using static IdentityModel.OidcConstants;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Identity Actions ...
|
|
/// <summary>
|
|
/// Request for Discovery Document
|
|
/// </summary>
|
|
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
|
|
public async Task<DiscoveryDocumentResponse> RequestDiscoveryDocument()
|
|
{
|
|
//
|
|
var httpClient = GetHttpClient();
|
|
var result = httpClient
|
|
.GetDiscoveryDocumentAsync(IdentityResourceConfiguration.Authority)
|
|
.ContinueWith(docTask =>
|
|
{
|
|
//
|
|
httpClient.Dispose();
|
|
return docTask.Result;
|
|
});
|
|
|
|
//
|
|
return await result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request AccessToken for Specific XApiScope
|
|
/// </summary>
|
|
/// <param name="scope">a member of <see>XApiScope</see></param>
|
|
/// <returns>an instance of <see>TokenResponse</see></returns>
|
|
public async Task<IdentityModel.Client.TokenResponse> RequestScopeAccessToken(
|
|
string scope
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (scope.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Disco Doc ...
|
|
var discoDoc = await RequestDiscoveryDocument();
|
|
if (discoDoc.IsError)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var request = new ClientCredentialsTokenRequest
|
|
{
|
|
Address = discoDoc.TokenEndpoint,
|
|
GrantType = GrantTypes.ClientCredentials,
|
|
ClientId = IdentityResourceConfiguration.ClientId,
|
|
ClientSecret = IdentityResourceConfiguration.ClientSecret,
|
|
Scope = scope
|
|
};
|
|
|
|
//
|
|
var httpClient = GetHttpClient();
|
|
var result = await httpClient
|
|
.RequestClientCredentialsTokenAsync(request)
|
|
.ContinueWith(response =>
|
|
{
|
|
//
|
|
httpClient.Dispose();
|
|
return response.Result;
|
|
});
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticate a User
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
|
/// <returns>an instance of <see>TokenResponse</see></returns>
|
|
public async Task<IdentityModel.Client.TokenResponse> Authenticate(
|
|
XLoginRequest model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroup();
|
|
|
|
//
|
|
// Retrieve Disco Doc ...
|
|
var discoDoc = await RequestDiscoveryDocument();
|
|
if (discoDoc.IsError)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Create Request ...
|
|
var request = new PasswordTokenRequest
|
|
{
|
|
//
|
|
Address = discoDoc.TokenEndpoint,
|
|
|
|
//
|
|
GrantType = GrantTypes.ClientCredentials,
|
|
ClientId = IdentityResourceConfiguration.ClientId,
|
|
ClientSecret = IdentityResourceConfiguration.ClientSecret,
|
|
|
|
//
|
|
UserName = model.UserSelectBy,
|
|
Password = model.Password,
|
|
|
|
//
|
|
// Pass Device to Request ...
|
|
Parameters = { { "force", false.ToJSON () }
|
|
}
|
|
};
|
|
|
|
//
|
|
var httpClient = GetHttpClient();
|
|
var result = await httpClient
|
|
.RequestPasswordTokenAsync(request)
|
|
.ContinueWith(response =>
|
|
{
|
|
//
|
|
httpClient.Dispose();
|
|
return response.Result;
|
|
});
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Do Login based on XLoginRequest
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
|
/// <returns>an instance of <see>XLoginResponse</see></returns>
|
|
public async Task<XLoginResponse> Login(
|
|
XLoginRequest model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model, model.Device)
|
|
.AddNotEmpty(
|
|
model.UserSelectBy,
|
|
model.Password
|
|
)
|
|
.ValidateGroup();
|
|
|
|
//
|
|
// Get Token Response ...
|
|
//
|
|
// Retrieve Disco Doc ...
|
|
var discoDoc = await RequestDiscoveryDocument();
|
|
Logger.LogInformation($"discoDoc: {discoDoc.ToJSON()}");
|
|
|
|
if (discoDoc.IsError)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Create Request ...
|
|
var request = new PasswordTokenRequest
|
|
{
|
|
//
|
|
Address = discoDoc.TokenEndpoint,
|
|
|
|
//
|
|
GrantType = GrantTypes.ClientCredentials,
|
|
ClientId = IdentityResourceConfiguration.ClientId,
|
|
ClientSecret = IdentityResourceConfiguration.ClientSecret,
|
|
|
|
//
|
|
UserName = model.UserSelectBy,
|
|
Password = model.Password,
|
|
|
|
//
|
|
// Pass Device to Request ...
|
|
Parameters = { { "force", false.ToJSON () },
|
|
{ "device", model.Device.ToJSON () },
|
|
{ "language", model.Language }
|
|
}
|
|
};
|
|
|
|
//
|
|
var httpClient = GetHttpClient();
|
|
var authResponse = await httpClient
|
|
.RequestPasswordTokenAsync(request)
|
|
.ContinueWith(response =>
|
|
{
|
|
//
|
|
httpClient.Dispose();
|
|
return response.Result;
|
|
});
|
|
|
|
//
|
|
// Check If Response Has Error ...
|
|
Logger.LogInformation($"AuthResponse: {authResponse.ToJSON()}");
|
|
|
|
//
|
|
if (authResponse.IsError)
|
|
{
|
|
throw authResponse.GetException();
|
|
}
|
|
|
|
//
|
|
// Create XLoginResponse Model ...
|
|
var result = authResponse.CreateXLoginResponse();
|
|
|
|
//
|
|
// Get ans Set User Profile ...
|
|
result.Profile = await GetUserProfileAsync(model.UserSelectBy, model.UserSelectBy);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Tokens
|
|
/// </summary>
|
|
/// <param name="model">Authentication Tokens, instance of <see>XTokenResponse</see></param>
|
|
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
|
public async Task<XTokenResponse> RefreshTokens(
|
|
XTokenResponse model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(
|
|
model.AccessToken,
|
|
model.RefreshToken
|
|
)
|
|
.ValidateGroup();
|
|
|
|
//
|
|
var authResponse = await RequestDiscoveryDocument()
|
|
.ContinueWith((discoTask) =>
|
|
{
|
|
//
|
|
var discoDoc = discoTask.Result;
|
|
if (discoDoc.IsError)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
using (var httpClient = GetHttpClient())
|
|
{
|
|
return httpClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
|
{
|
|
//
|
|
Address = discoDoc.TokenEndpoint,
|
|
GrantType = GrantTypes.RefreshToken,
|
|
ClientId = IdentityResourceConfiguration.ClientId,
|
|
ClientSecret = IdentityResourceConfiguration.ClientSecret,
|
|
RefreshToken = model.RefreshToken
|
|
}).Result;
|
|
}
|
|
});
|
|
|
|
//
|
|
// Check If Response Has Error ...
|
|
if (authResponse.IsError)
|
|
{
|
|
//
|
|
XError error = authResponse.ErrorDescription.FromJSON<XError>();
|
|
throw error.ToException();
|
|
}
|
|
|
|
//
|
|
// Create XLoginResponse Model ...
|
|
var result = authResponse.CreateXTokenResponse();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Requirements ...
|
|
/// <summary>
|
|
/// Get an Instance of Http Client
|
|
/// </summary>
|
|
/// <returns>an instance of <see>HttpClient</see></returns>
|
|
public HttpClient GetHttpClient()
|
|
{
|
|
//
|
|
HttpClient httpClient = null;
|
|
httpClient = new HttpClient();
|
|
var httpClientHandler = new HttpClientHandler()
|
|
{
|
|
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
|
|
{
|
|
//
|
|
Logger.LogInformation(
|
|
$"SSL Handler: {Environment.NewLine} sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}"
|
|
);
|
|
|
|
//
|
|
return true;
|
|
},
|
|
ClientCertificateOptions = ClientCertificateOption.Manual,
|
|
};
|
|
|
|
//
|
|
httpClient = new HttpClient(httpClientHandler);
|
|
|
|
//
|
|
return httpClient;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+MessageProvider.cs
|
|
|
|
using System;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Navigations;
|
|
using xMessageService.Models;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Message Provider ...
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// User Invite Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="inviteToken">invitation token</param>
|
|
/// <param name="returnUrl">return url for invitation user to redirect</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetUserInviteMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
string inviteToken,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress, inviteToken, returnUrl);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.Url(returnUrl);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
var msgStr = IdentityMessageProvider.InviteMsg +
|
|
Environment.NewLine +
|
|
returnUrl +
|
|
"?t=" +
|
|
inviteToken;
|
|
|
|
//
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// New Device LoggedIn Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="device">an instance of <see>XDevice</see> which represent user new Device</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetUserNewDeviceLoggedInMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.NotNull(device);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
// Generate Specific Message ...
|
|
var msgStr = IdentityMessageProvider.NewDeviceLoggedInMsg +
|
|
Environment.NewLine +
|
|
nameof(XDevice.Os) + ": " + device.Os +
|
|
Environment.NewLine +
|
|
nameof(XDevice.OsVersion) + ": " + device.OsVersion +
|
|
Environment.NewLine +
|
|
nameof(XDevice.Browser) + ": " + device.Browser +
|
|
Environment.NewLine +
|
|
nameof(XDevice.UserAgent) + ": " + device.UserAgent;
|
|
|
|
//
|
|
// Create XMessage Instance ...
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// Verification Code Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="mobileNumberOrEmail">an string which points to a user email address or mobile number</param>
|
|
/// <param name="verificationCode">user verification code</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetVerificationCodeMessage(
|
|
string lang,
|
|
string mobileNumberOrEmail,
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, mobileNumberOrEmail, verificationCode);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
mobileNumberOrEmail = mobileNumberOrEmail.ToNormalString();
|
|
|
|
//
|
|
// Validate Mobile or Email ...
|
|
var isValidEmail = mobileNumberOrEmail.IsValidEmail();
|
|
var isValidMobileNumber = mobileNumberOrEmail.IsValidMobileNumber();
|
|
if (!isValidEmail &&
|
|
!isValidMobileNumber)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Message String ...
|
|
var msgStr = IdentityMessageProvider.VerificationCodeMsg +
|
|
Environment.NewLine +
|
|
verificationCode;
|
|
|
|
//
|
|
// Create XMessage Instance ...
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(mobileNumberOrEmail);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// Registration Approve Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="returnUrl">return url for redirect</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetRegistrationConfirmMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
string actionToken,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress, actionToken, returnUrl);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.Url(returnUrl);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
// Prepare Message Str ...
|
|
var msgStr = IdentityMessageProvider.RegistrationApproveMsg +
|
|
Environment.NewLine +
|
|
returnUrl +
|
|
"?t=" +
|
|
actionToken;
|
|
|
|
//
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// Registration Finished Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="returnUrl">return url for redirect</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetRegistrationFinishedMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress, returnUrl);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.Url(returnUrl);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
var msgStr = IdentityMessageProvider.RegisteredMsg +
|
|
Environment.NewLine +
|
|
returnUrl;
|
|
|
|
//
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// Password Changed Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="returnUrl">return url for redirect</param>
|
|
/// <param name="throwException">specify throw exceptions on failure or not, default is true</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetPasswordChangedMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
string returnUrl,
|
|
bool throwException = true
|
|
)
|
|
{
|
|
//
|
|
if (throwException)
|
|
{
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress, returnUrl);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.Url(returnUrl);
|
|
}
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
var msgStr = IdentityMessageProvider.PasswordChangedMsg +
|
|
(returnUrl.IsNullOrEmpty() ?
|
|
"" :
|
|
Environment.NewLine +
|
|
returnUrl);
|
|
|
|
//
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate and Prepare an XMessage Instance for
|
|
/// Reset Password Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="emailAddress">reciever email address</param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="returnUrl">return url for redirect</param>
|
|
/// <returns>an instance of <see>XMessage</see></returns>
|
|
private XMessage GetResetPasswordMessage(
|
|
string lang,
|
|
string emailAddress,
|
|
string actionToken,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang, emailAddress, actionToken, returnUrl);
|
|
ValidationProvider
|
|
.EmailAddress(emailAddress);
|
|
ValidationProvider
|
|
.Url(returnUrl);
|
|
|
|
//
|
|
HandleMessageProviderPreperation(lang);
|
|
|
|
//
|
|
// Prepare Message Str ...
|
|
var msgStr = IdentityMessageProvider.ChangePasswordMsg +
|
|
Environment.NewLine +
|
|
returnUrl +
|
|
"?t=" +
|
|
actionToken;
|
|
|
|
//
|
|
var message = new XMessage
|
|
{
|
|
Message = msgStr,
|
|
};
|
|
message.Recievers.Add(emailAddress);
|
|
|
|
//
|
|
return message;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Open.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Dtos;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region OpenGet ...
|
|
public async Task<XOpenActionInnerDto> OpenGet(
|
|
XOpenActionInnerDto model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(model)
|
|
.AddNotEmpty(model.Token)
|
|
.AddNotEmpty(model.Payload)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
return await OpenGet(
|
|
token: model.Token,
|
|
actionRequest: model.Payload
|
|
);
|
|
}
|
|
|
|
//
|
|
public async Task<XOpenActionInnerDto> OpenGet(
|
|
string token,
|
|
string actionRequest
|
|
)
|
|
{
|
|
//
|
|
// Validatr Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(token)
|
|
.AddNotEmpty(actionRequest)
|
|
.ValidateGroupAsync();
|
|
//
|
|
// Try to Decrypt Request ...
|
|
var requestModel = ParseModel(
|
|
token: token,
|
|
request: actionRequest
|
|
);
|
|
if (requestModel.IsNull() ||
|
|
requestModel.Action.IsNullOrEmpty())
|
|
{
|
|
XException.BadRequest.Throw();
|
|
}
|
|
|
|
//
|
|
var responseJson = string.Empty;
|
|
switch (requestModel.Action)
|
|
{
|
|
//
|
|
case XOpenActions.GetUserInfo:
|
|
//
|
|
ValidationProvider.NotEmpty(requestModel.Payload);
|
|
var userInfo = await GetUserInfo(requestModel);
|
|
if (userInfo.IsNull())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
responseJson = userInfo.ToJSON();
|
|
break;
|
|
|
|
//
|
|
case XOpenActions.GetUserInfos:
|
|
ValidationProvider.NotEmpty(requestModel.Payload);
|
|
var userInfos = await GetUserInfos(requestModel);
|
|
if (userInfos.IsNull())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
responseJson = userInfos.ToJSON();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Encrypt Json Str ...
|
|
var responseStr = SecurityProvider.Encrypt(responseJson);
|
|
requestModel.Payload = responseStr;
|
|
requestModel.Timestamp = DateTime.UtcNow
|
|
.AddMinutes(5)
|
|
.ToTimestamp()
|
|
.ToString();
|
|
|
|
//
|
|
token = requestModel.ToOpenActionToken();
|
|
requestModel.Checksum = token;
|
|
var result = new XOpenActionInnerDto
|
|
{
|
|
Token = token,
|
|
Payload = requestModel.ToJSON()
|
|
};
|
|
|
|
//
|
|
// Check Result ...
|
|
if (result.IsNull())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
public async Task<XOpenActionUserInfoDto> GetUserInfo(
|
|
XOpenActionRequestDto model
|
|
)
|
|
{
|
|
//
|
|
// Retrieve User Profile ...
|
|
var userProfile = await GetUserProfileAsync(
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
requestedUserSelectByParam: "",
|
|
forceCheckRequestedUser: false,
|
|
userSelectByParam: model.Payload
|
|
);
|
|
|
|
//
|
|
// Generate a Dynamic Object ...
|
|
var result = new XOpenActionUserInfoDto
|
|
{
|
|
Username = userProfile.UserName,
|
|
Firstname = userProfile.FirstName,
|
|
Lastname = userProfile.LastName,
|
|
Avatar = userProfile.Avatar
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public async Task<IEnumerable<XOpenActionUserInfoDto>> GetUserInfos(
|
|
XOpenActionRequestDto model
|
|
)
|
|
{
|
|
//
|
|
var ids = model.Payload.ParseListString<string>().ToList();
|
|
var profiles = await GetUserProfilesAsync(
|
|
ids: ids,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
requestedUserSelectByParam: "",
|
|
forceCheckRequestedUser: false
|
|
);
|
|
var result = profiles.Select(x => new XOpenActionUserInfoDto
|
|
{
|
|
Avatar = x.Avatar,
|
|
Username = x.UserName,
|
|
Lastname = x.LastName,
|
|
Firstname = x.FirstName,
|
|
});
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
#region Private ...
|
|
private XOpenActionRequestDto ParseModel(
|
|
string token,
|
|
string request
|
|
)
|
|
{
|
|
//
|
|
// Decript request to get Json string of request object ...
|
|
var result = new XOpenActionRequestDto();
|
|
|
|
//
|
|
var jsonStr = SecurityProvider.Decrypt(request);
|
|
result = jsonStr.FromJSON<XOpenActionRequestDto>();
|
|
if (result.IsNull() ||
|
|
!result.Validate() ||
|
|
token != result.Checksum
|
|
)
|
|
{
|
|
//
|
|
result = null;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
var modelChecksum = result.ToOpenActionToken();
|
|
result =
|
|
token == modelChecksum
|
|
? result
|
|
: null;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Private.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Generators ...
|
|
/// <summary>
|
|
/// Generate a Random Number ...
|
|
/// </summary>
|
|
/// <returns>a long value</returns>
|
|
private long GenerateRandom()
|
|
{
|
|
return new Random().Next(100000, 999999);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region UserSelectBy Actions ...
|
|
/// <summary>
|
|
/// Retrieve UserSelectByType based on Given Info
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="forceUserSelectByParamNotEmpty">a boolean value which specify the identifier
|
|
/// must be specific and not empty, default is true</param>
|
|
/// <param name="forceUserSelectByTypeMustSpecified">a boolean value which specify the type
|
|
/// must be specific, default is false</param>
|
|
/// <returns>a member of <see>XUserSelectBy</see></returns>
|
|
private XUserSelectBy GetUserSelectByType(
|
|
string userSelectByParam,
|
|
bool forceUserSelectByParamNotEmpty = true,
|
|
bool forceUserSelectByTypeMustSpecified = false
|
|
)
|
|
{
|
|
//
|
|
if (forceUserSelectByParamNotEmpty)
|
|
{
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
}
|
|
|
|
//
|
|
var result = XUserSelectBy.NotSpecified;
|
|
var normalizedString = userSelectByParam.ToNormalString();
|
|
if (userSelectByParam.IsValidEmail())
|
|
{
|
|
//
|
|
// Find User by Email ...
|
|
result = XUserSelectBy.Email;
|
|
}
|
|
else if (userSelectByParam.IsValidMobileNumber())
|
|
{
|
|
//
|
|
// Find User by Mobile Number ...
|
|
result = XUserSelectBy.MobileNumber;
|
|
}
|
|
else if (userSelectByParam.IsGuid())
|
|
{
|
|
//
|
|
// Find User By it's ID ...
|
|
result = XUserSelectBy.ID;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// UserName ...
|
|
result = XUserSelectBy.Username;
|
|
}
|
|
|
|
//
|
|
if (forceUserSelectByTypeMustSpecified &&
|
|
result == XUserSelectBy.NotSpecified)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on XUser Object
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XUser user,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(user);
|
|
|
|
//
|
|
var id = user.Id;
|
|
var userName = user.UserName;
|
|
var email = user.Email;
|
|
var phoneNumber = user.PhoneNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on <see>XActionRequestContext</see> instance
|
|
/// </summary>
|
|
/// <param name="context">an instance of <see>XActionRequestContext</see></param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XActionRequestContext context,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(context);
|
|
|
|
//
|
|
// Generate User SelectBy ...
|
|
var id = context.UserId;
|
|
var userName = context.UserName;
|
|
var email = context.Email;
|
|
var phoneNumber = context.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
//
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check param ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on <see>XActionRequestToken</see> instance
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see> which
|
|
/// provides required informations</param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XActionRequestToken request,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(request);
|
|
|
|
//
|
|
// Generate User SelectBy ...
|
|
return GetUserSelectByParam(
|
|
context: request.Context,
|
|
forceNotNull: forceNotNull,
|
|
excludes: excludes
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Available UserSelectByParams from given XUser
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <returns></returns>
|
|
private ICollection<string> GenerateUserSelectByParams(
|
|
XUser user
|
|
)
|
|
{
|
|
//
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new List<string> {
|
|
user.Id,
|
|
user.UserName,
|
|
user.PhoneNumber,
|
|
user.Email,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Required XUserSelectByTypes
|
|
/// </summary>
|
|
/// <param name="ignores">a collection of <see>XUserSelectBy</see> members which
|
|
/// ignored in result</param>
|
|
/// <returns>a collection of available <see>XUserSelectBy</see> members</returns>
|
|
private ICollection<XUserSelectBy> GenerateUserSelectByExcludes(
|
|
ICollection<XUserSelectBy> ignores
|
|
)
|
|
{
|
|
//
|
|
var result = ObjectHelper
|
|
.ToEnumerableValues<XUserSelectBy>()
|
|
.Except(ignores);
|
|
|
|
//
|
|
return result.ToList();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XAction Actions ...
|
|
/// <summary>
|
|
/// Retrieve Action Result Response based on XToken
|
|
/// </summary>
|
|
/// <param name="xToken">an instance of <see>XToken</see></param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
private XActionResponse GetActionResultResponse(
|
|
XToken xToken
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(xToken);
|
|
ValidationProvider.NotEmpty(xToken.Hash, xToken.Token);
|
|
|
|
//
|
|
ValidateToken(xToken.Token);
|
|
|
|
//
|
|
var expDate = GetTokenExpirationDate(xToken.Token);
|
|
ValidationProvider.NotNull(expDate);
|
|
|
|
//
|
|
// Generate Result class ...
|
|
var result = new XActionResponse
|
|
{
|
|
Token = xToken.Hash,
|
|
Expiration = expDate
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XIdentityMessage Actions ...
|
|
/// <summary>
|
|
/// Prepare Message Provider and Check it's State
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
private void HandleMessageProviderPreperation(
|
|
string lang
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang);
|
|
|
|
//
|
|
// Prepare Identity Messages ...
|
|
// the PrepareMessageMethod check IsReady of Helper automatically ...
|
|
IdentityMessageProvider.PrepareMessages(lang);
|
|
|
|
//
|
|
// Check Message Provider ...
|
|
var isMessageProviderReady = MessageProvider.IsReady(true);
|
|
if (!isMessageProviderReady)
|
|
{
|
|
XException.MessageServiceInitialFailed.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship Actions ...
|
|
/// <summary>
|
|
/// Check Follow Request Sent Before
|
|
/// from dest to source
|
|
/// </summary>
|
|
/// <param name="source">an instance of <see>XUser</see></param>
|
|
/// <param name="dest">an instance of <see>XUser</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsFollowRequested(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var result = source.Followings.Any(f => f.DestId == dest.Id);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Follow Request Sent Before
|
|
/// from dest to source
|
|
/// </summary>
|
|
/// <param name="source">an instance of <see>XUser</see></param>
|
|
/// <param name="dest">an instance of <see>XUser</see></param>
|
|
/// <param name="state">a member of <see>XFriendshipState</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsFollowRequested(
|
|
XUser source,
|
|
XUser dest,
|
|
XFriendshipState state
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var result = source.Followings
|
|
.Any(f =>
|
|
f.DestId == dest.Id &&
|
|
f.State == state);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to XFriendDto ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <returns></returns>
|
|
private async Task<XFriendDto> ToDto(XFriendshipFollower entity)
|
|
{
|
|
//
|
|
XFriendDto result = null;
|
|
|
|
//
|
|
if (entity.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Dest User Profile ...
|
|
var profile = await GetUserProfileAsync(
|
|
userSelectByParam: entity.DestId,
|
|
requestedUserSelectByParam: entity.UserId,
|
|
forceCheckRequestedUser: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
// Preparing Result ...
|
|
result = new XFriendDto
|
|
{
|
|
UserId = profile.UserId,
|
|
Avatar = profile.Avatar,
|
|
Username = profile.UserName,
|
|
Lastname = profile.LastName,
|
|
Firstname = profile.FirstName,
|
|
Type = XFriendshipType.Follower,
|
|
State = profile.FriendshipInfo.FollowerState,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to XFriendDto ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <returns></returns>
|
|
private async Task<XFriendDto> ToDto(XFriendshipFollowing entity)
|
|
{
|
|
//
|
|
XFriendDto result = null;
|
|
|
|
//
|
|
if (entity.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Dest User Profile ...
|
|
var profile = await GetUserProfileAsync(
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false,
|
|
userSelectByParam: entity.DestId,
|
|
requestedUserSelectByParam: entity.UserId
|
|
);
|
|
|
|
//
|
|
// Preparing Result ...
|
|
result = new XFriendDto
|
|
{
|
|
UserId = profile.UserId,
|
|
Avatar = profile.Avatar,
|
|
Username = profile.UserName,
|
|
Lastname = profile.LastName,
|
|
Firstname = profile.FirstName,
|
|
Type = XFriendshipType.Following,
|
|
State = profile.FriendshipInfo.FollowingState,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region User Profile ...
|
|
/// <summary>
|
|
/// Count User's Page
|
|
/// </summary>
|
|
/// <param name="pageSize">an integer value which represent page size</param>
|
|
/// <returns>an inetger value which represent pages count</returns>
|
|
public async Task<int> UserPagesCount(
|
|
int pageSize
|
|
)
|
|
{
|
|
//
|
|
int count = await UserManager.Users.CountAsync();
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count Avatar's Page
|
|
/// </summary>
|
|
/// <param name="pageSize">an integer value which represent page size</param>
|
|
/// <returns>an inetger value which represent pages count</returns>
|
|
public async Task<int> ProfileImagePagesCount(
|
|
int pageSize
|
|
)
|
|
{
|
|
//
|
|
int count = await DbContext.Avatars.CountAsync();
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Profile.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
using xIds.Extensions;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityHelper;
|
|
using xIdentityHelper.Extensions;
|
|
using xDataService.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Retrieve Actions ...
|
|
/// <summary>
|
|
/// Retrieve User Profile
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
|
|
/// and throw exception if it is, default true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> GetUserProfileAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
if (forceCheckRequestedUser)
|
|
{
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
}
|
|
else
|
|
{
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
}
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var isAdmin = false;
|
|
var isSameUser = false;
|
|
if (forceCheckRequestedUser &&
|
|
!requestedUserSelectByParam.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
isSameUser = xUser.Id == xRequestedUser.Id;
|
|
|
|
//
|
|
var xRequestUserRoleNames = await GetRoleNamesAsync(
|
|
userSelectByParam: requestedUserSelectByParam,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
isAdmin = xRequestUserRoleNames.Contains(XUserRole.Admin.GetStringValue());
|
|
}
|
|
|
|
//
|
|
var roleNames = await GetRoleNamesAsync(
|
|
userSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
var xFriendshipInfo =
|
|
requestedUserSelectByParam.IsNullOrEmpty()
|
|
? null
|
|
: await GetFriendshipInfo(
|
|
requestedUserSelectByParam,
|
|
userSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
var result = xUser.ToXProfileDto(
|
|
isAdmin: isAdmin,
|
|
roles: roleNames,
|
|
isSameUser: isSameUser,
|
|
friendship: xFriendshipInfo,
|
|
profileConfig: Configuration.Policy.Profile
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Collection of User Profiles
|
|
/// </summary>
|
|
/// <param name="ids">a collection of user identifiers</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
|
|
/// and throw exception if it is, default true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an collection of <see>XUserProfileDto</see> instances</returns>
|
|
public async Task<IEnumerable<XUserProfileDto>> GetUserProfilesAsync(
|
|
ICollection<string> ids,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
if (forceCheckRequestedUser)
|
|
{
|
|
ValidationProvider.NotEmpty(requestedUserSelectByParam);
|
|
}
|
|
ValidationProvider.NotZeroChilds(ids);
|
|
|
|
//
|
|
var result = new List<XUserProfileDto>();
|
|
foreach (var id in ids)
|
|
{
|
|
//
|
|
var xProfile = await GetUserProfileAsync(
|
|
id,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
forceCheckRequestedUser: forceCheckRequestedUser
|
|
);
|
|
result.Add(xProfile);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query User Profiles
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var totalEntities = GetUsersDbSet()
|
|
.ToList()
|
|
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
.Select(u => u.Id)
|
|
.ToList();
|
|
|
|
//
|
|
var items = await GetUserProfilesAsync(
|
|
totalEntities,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false
|
|
);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XUserProfileDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query In Roles User Profiles
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed, default is false</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
|
|
string requestedUserSelectByParam,
|
|
string role,
|
|
XQuery query,
|
|
bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull() || role.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Role Exists ...
|
|
var isExistsRole = await IsRoleExistsAsync(role);
|
|
if (!isExistsRole)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
#region Select Users Based on Specific Roles ...
|
|
var selectedUsers = new List<string>();
|
|
var usersEnumerator = GetUsersDbSet(query.ContainsDetail).AsAsyncEnumerable();
|
|
await
|
|
foreach (var user in usersEnumerator)
|
|
{
|
|
//
|
|
if (user.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Set Default Value is True ...
|
|
var isInRole = false;
|
|
|
|
//
|
|
// if Force Role ...
|
|
if (forceRole)
|
|
{
|
|
isInRole = await UserManager.IsInRoleAsync(user, role);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Select User Top Role ...
|
|
var userRoles = await GetRoleNamesAsync(
|
|
checkIsBanned: false,
|
|
userSelectByParam: user.Id,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
isInRole = userRoles.HasRolePermissions(role);
|
|
}
|
|
|
|
//
|
|
if (isInRole)
|
|
{
|
|
selectedUsers.Add(user.Id);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
var items = await GetUserProfilesAsync(
|
|
selectedUsers,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false
|
|
);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XUserProfileDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
|
|
public async Task<XQueryResult<XProfileImage>> QueryAvatars(
|
|
string userSelectByParam,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true
|
|
);
|
|
|
|
//
|
|
var items = query.ContainsDetail ?
|
|
DbContext.Avatars
|
|
.Include(pf => pf.User)
|
|
.AsEnumerable() :
|
|
DbContext.Avatars
|
|
.AsEnumerable();
|
|
items = items
|
|
.Where(pfi => pfi.UserId == xUser.Id);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XProfileImage>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check specific user Confirmed Email or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedEmail(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
return xUser.EmailConfirmed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ceck specific user Confirmed Mobile or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedMobile(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
return xUser.PhoneNumberConfirmed;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update Actions ...
|
|
/// <summary>
|
|
/// Update User Profile (FirstName/LastName/DateOfBirth) ...
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> ProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest model
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
await ValidateUserForDangerousAction(xUser, xRequestedUser);
|
|
|
|
//
|
|
// FirstName ...
|
|
if (!model.FirstName.IsNullOrEmpty())
|
|
{
|
|
xUser.FirstName = model.FirstName;
|
|
}
|
|
|
|
//
|
|
// Last Name ...
|
|
if (!model.LastName.IsNullOrEmpty())
|
|
{
|
|
xUser.LastName = model.LastName;
|
|
}
|
|
|
|
//
|
|
// Date of Birth ...
|
|
if (model.DateOfBirth.HasValue)
|
|
{
|
|
xUser.DateOfBirth = model.DateOfBirth.Value;
|
|
}
|
|
|
|
//
|
|
// Bio ...
|
|
xUser.Bio = model.Bio;
|
|
|
|
//
|
|
// Cover Image ...
|
|
xUser.CoverImage = model.CoverImage;
|
|
|
|
//
|
|
// Open To Search ...
|
|
xUser.OpenToSearch = model.OpenToSearch;
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(xUser);
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, requestedUserSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update User Profile
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> FullProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest model
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
await ValidateUserForDangerousAction(xUser, xRequestedUser);
|
|
|
|
//
|
|
#region Fill User with Models Value ...
|
|
//
|
|
// FirstName ...
|
|
xUser.FirstName = !model.FirstName.IsNullOrEmpty() ?
|
|
model.FirstName :
|
|
xUser.FirstName;
|
|
//
|
|
// LastName ...
|
|
xUser.LastName = !model.LastName.IsNullOrEmpty() ?
|
|
model.LastName :
|
|
xUser.LastName;
|
|
|
|
//
|
|
// Email ...
|
|
xUser.Email = !model.Email.IsNullOrEmpty() ?
|
|
model.Email :
|
|
xUser.Email;
|
|
|
|
//
|
|
// EmailConfirmed ...
|
|
if (model.EmailConfirmed.HasValue)
|
|
{
|
|
xUser.EmailConfirmed = model.EmailConfirmed.Value;
|
|
}
|
|
|
|
//
|
|
// PhoneNumber ...
|
|
xUser.PhoneNumber = !model.PhoneNumber.IsNullOrEmpty() ?
|
|
model.PhoneNumber :
|
|
xUser.PhoneNumber;
|
|
|
|
//
|
|
// PhoneNumberConfirmed ,,,
|
|
if (model.PhoneNumberConfirmed.HasValue)
|
|
{
|
|
xUser.PhoneNumberConfirmed = model.PhoneNumberConfirmed.Value;
|
|
}
|
|
|
|
//
|
|
// DateOfBirth ...
|
|
if (model.DateOfBirth.HasValue)
|
|
{
|
|
xUser.DateOfBirth = model.DateOfBirth.Value;
|
|
}
|
|
|
|
//
|
|
// CreationDate ...
|
|
if (model.CreationDate.HasValue)
|
|
{
|
|
xUser.CreationDate = model.CreationDate.Value;
|
|
}
|
|
|
|
//
|
|
// LastLogin ...
|
|
if (model.LastLogin.HasValue)
|
|
{
|
|
xUser.LastLogin = model.LastLogin.Value;
|
|
}
|
|
|
|
//
|
|
// Avatar ...
|
|
xUser.Avatar = !model.Avatar.IsNullOrEmpty() ?
|
|
model.Avatar :
|
|
xUser.Avatar;
|
|
|
|
//
|
|
// Gender ...
|
|
if (model.Gender.HasValue)
|
|
{
|
|
xUser.Gender = model.Gender.Value;
|
|
}
|
|
|
|
//
|
|
// IsEnable ...
|
|
if (model.IsEnable.HasValue)
|
|
{
|
|
xUser.IsEnable = model.IsEnable.Value;
|
|
}
|
|
|
|
//
|
|
// IsBanned ...
|
|
if (model.IsBanned.HasValue)
|
|
{
|
|
xUser.IsBanned = model.IsBanned.Value;
|
|
}
|
|
|
|
//
|
|
// Bio ...
|
|
xUser.Bio = model.Bio;
|
|
|
|
//
|
|
// Cover Image ...
|
|
xUser.CoverImage = model.CoverImage;
|
|
|
|
//
|
|
// Open To Search ...
|
|
xUser.OpenToSearch = model.OpenToSearch;
|
|
#endregion
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Handle Roles ...
|
|
|
|
//
|
|
// Remove User from All Roles ...
|
|
if (xUser.Roles.HasChild())
|
|
{
|
|
//
|
|
var roleNames = await GetRoleNamesAsync(
|
|
xUser.Id,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
|
|
//
|
|
foreach (var role in roleNames)
|
|
{
|
|
//
|
|
var isRoleExists = await IsRoleExistsAsync(role);
|
|
if (isRoleExists)
|
|
{
|
|
//
|
|
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
|
|
if (!isInRole)
|
|
{
|
|
//
|
|
var removeRoleResult = await UserManager.RemoveFromRoleAsync(xUser, role);
|
|
if (!removeRoleResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Roles and Add to Exists ...
|
|
if (model.Roles.HasChild())
|
|
{
|
|
//
|
|
// Check Exists Roles for Add ...
|
|
foreach (var role in model.Roles)
|
|
{
|
|
//
|
|
var isRoleExists = await IsRoleExistsAsync(role);
|
|
if (isRoleExists)
|
|
{
|
|
//
|
|
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
|
|
if (!isInRole)
|
|
{
|
|
//
|
|
var addToRoleResult = await UserManager.AddToRoleAsync(xUser, role);
|
|
if (!addToRoleResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Request For Actions ...
|
|
/// <summary>
|
|
/// Request Mobile Confirm
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="mobileNumber">mobile number which need to confirm</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmMobile(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string mobileNumber = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
MobileNumber = mobileNumber
|
|
};
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
context.UserName = user.UserName;
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
ValidationProvider.MobileNumber(user.PhoneNumber);
|
|
if (!mobileNumber.IsNullOrEmpty() &&
|
|
user.PhoneNumber == mobileNumber &&
|
|
user.PhoneNumberConfirmed)
|
|
{
|
|
XException.MobileInUsed.Throw();
|
|
}
|
|
|
|
//
|
|
if (mobileNumber.IsNullOrEmpty())
|
|
{
|
|
mobileNumber = user.PhoneNumber;
|
|
}
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var request = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestMobileVerificationCode,
|
|
context,
|
|
forceRenewToken: true
|
|
);
|
|
|
|
//
|
|
Logger.LogInformation($"ActionRequest: {request.ToJSON()}");
|
|
|
|
//
|
|
// Call Confirm Method of Registration ...
|
|
var result = await RequestMobileVerificationCode(
|
|
lang,
|
|
device,
|
|
request.Token,
|
|
mobileNumber,
|
|
checkMobileInUse: false);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Email Confirma
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="emailAddress">email address which need to confirm</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmEmail(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string emailAddress = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = emailAddress
|
|
};
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
context.UserName = user.UserName;
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
ValidationProvider.EmailAddress(user.Email);
|
|
if (!emailAddress.IsNullOrEmpty() &&
|
|
user.Email == emailAddress &&
|
|
user.EmailConfirmed)
|
|
{
|
|
XException.EmailInUsed.Throw();
|
|
}
|
|
|
|
//
|
|
if (emailAddress.IsNullOrEmpty())
|
|
{
|
|
emailAddress = user.Email;
|
|
context.Email = user.Email;
|
|
}
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var request = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestEmailVerificationCode,
|
|
context,
|
|
forceRenewToken: true
|
|
);
|
|
|
|
//
|
|
// Call Confirm Method of Registration ...
|
|
var result = await RequestEmailVerificationCode(
|
|
lang,
|
|
device,
|
|
request.Token,
|
|
emailAddress,
|
|
checkEmailInUse: false);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Reset Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.AddUrl(returnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = user.Email,
|
|
UserName = user.UserName
|
|
};
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
user.Email,
|
|
XAction.RequestResetPassword,
|
|
context
|
|
);
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetResetPasswordMessage(
|
|
lang,
|
|
user.Email,
|
|
result.Token,
|
|
returnUrl);
|
|
|
|
//
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Registration Confrirm
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task RequestConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.AddUrl(returnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Validate user and Retrieve it ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: true,
|
|
ignoreDisabledUser: true);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = user.Email
|
|
};
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
user.Email,
|
|
XAction.Finish,
|
|
context
|
|
);
|
|
|
|
//
|
|
// Prepare XMessage Instance ...
|
|
var xMessage = GetRegistrationConfirmMessage(
|
|
lang,
|
|
user.Email,
|
|
result.Token,
|
|
returnUrl);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Password Actions ...
|
|
/// <summary>
|
|
/// Change Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="newPassword">user's new password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ChangePassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string newPassword,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password,
|
|
newPassword,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Password Unique ...
|
|
if (password == newPassword)
|
|
{
|
|
XException.PasswordsSame.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password);
|
|
|
|
//
|
|
// Check Password Policies ...
|
|
await ValidatePasswordPolicies(user, newPassword);
|
|
|
|
//
|
|
// Clean All User Tokens ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Try to Change User Password ...
|
|
var passwordResetResult = await UserManager
|
|
.ChangePasswordAsync(
|
|
user,
|
|
password,
|
|
newPassword);
|
|
|
|
//
|
|
// Check Result ...
|
|
if (!passwordResetResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetPasswordChangedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl,
|
|
throwException: false
|
|
);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset User Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="newPassword">user's new password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string newPassword,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
actionToken,
|
|
newPassword,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Get User Identifier ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Check Password Policies ...
|
|
await ValidatePasswordPolicies(user, newPassword);
|
|
|
|
//
|
|
// Clean All User Tokens ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Try to Remove User Password ...
|
|
var removePasswordResult = await UserManager.RemovePasswordAsync(user);
|
|
if (!removePasswordResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// try to Add New Password ...
|
|
var passwordResetResult = await UserManager.AddPasswordAsync(user, newPassword);
|
|
if (!passwordResetResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetPasswordChangedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Profile Image Actions ...
|
|
/// <summary>
|
|
/// Add Profile Image to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatar(
|
|
string userSelectByParam,
|
|
IFormFile file
|
|
)
|
|
{
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider.HandleProfileImageSave(file);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = xUser.Id,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath,
|
|
CreationDate = DateTime.UtcNow
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Profile Images to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatars(
|
|
string userSelectByParam,
|
|
IFormFileCollection files
|
|
)
|
|
{
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
foreach (var file in files)
|
|
{
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider.HandleProfileImageSave(file);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = xUser.Id,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath,
|
|
CreationDate = DateTime.UtcNow
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
}
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Specific Profie Image as Current Profile Image
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> SetAvatar(
|
|
string userSelectByParam,
|
|
int id
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
var xProfileImage = xUser.Avatars.FirstOrDefault(pf => pf.Id == id);
|
|
if (xProfileImage.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Collection of User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> RemoveAvatar(
|
|
string userSelectByParam,
|
|
ICollection<int> ids
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
var xProfileImages = xUser.Avatars
|
|
.Where(pf => ids.Contains(pf.Id));
|
|
if (xProfileImages.HasChild())
|
|
{
|
|
//
|
|
xUser.Avatars = xUser.Avatars
|
|
.Except(xProfileImages)
|
|
.ToList();
|
|
|
|
//
|
|
// Creat a List of Physical Files to Remove ...
|
|
var xFilePathsForRemove = xProfileImages.Select(pf => pf.Thumb).ToList();
|
|
xFilePathsForRemove.AddRange(xProfileImages.Select(pf => pf.Name));
|
|
|
|
//
|
|
StorageProvider.DeleteFiles(
|
|
xFilePathsForRemove,
|
|
forceFileExists: false);
|
|
|
|
//
|
|
var isCurrentProfileImage = xProfileImages.Any(pfi => pfi.ThumbPath == xUser.Avatar);
|
|
if (isCurrentProfileImage)
|
|
{
|
|
xUser.Avatar = "";
|
|
}
|
|
|
|
//
|
|
await UpdateUserAsync(xUser);
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Confirmations ...
|
|
/// <summary>
|
|
/// Confirm Registration
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
actionToken,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
if (request.Action != XAction.Finish)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
request,
|
|
forceNotNull: true);
|
|
|
|
//
|
|
// Validate user and Retrieve it ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
ignoreDisabledUser: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Make User Enabled ...
|
|
var xMessage = GetRegistrationFinishedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl);
|
|
|
|
//
|
|
user.IsEnable = true;
|
|
user.EmailConfirmed = true;
|
|
|
|
//
|
|
await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
// Remove Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
await RemoveVerificationCodeRequestByDevice(device);
|
|
|
|
//
|
|
// Send Mail ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Mobile Number
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="verificationCode">recieved verification code</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmMobileNumber(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, verificationCode)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
ValidationProvider.MobileNumber(request.Context.MobileNumber);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Check XActionRequest Action Must be Request Mobile Validation ...
|
|
if (request.Action != XAction.RequestMobileVerificationCode)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// since device must Requested before,
|
|
// Retrieve XVerification instance by Verification Code from Db
|
|
// and Validate it ...
|
|
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
// var isUserExists = await IsUserExistsAsync(userSelectByParam);
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Update Exists User's Mobile Confirmation ...
|
|
user.PhoneNumberConfirmed = true;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
|
|
|
|
//
|
|
request.Context.UserId = user.Id;
|
|
}
|
|
|
|
//
|
|
// Update Request Context MobileNumber Verification Code
|
|
// and it's Confirmation Status ...
|
|
request.Context.MobileVerificationCode = verificationCode;
|
|
request.Context.MobileVerified = true;
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.ConfirmMobileNumber,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
try
|
|
{
|
|
//
|
|
// Remove XVerificationRequest instance from Db ...
|
|
await RemoveVerificationRequest(verificationCode);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Email Address
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="verificationCode">recieved verification code</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmEmailAddress(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, verificationCode)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
ValidationProvider.EmailAddress(request.Context.Email);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Check XActionRequest Action Must be Request Mobile Validation ...
|
|
if (request.Action != XAction.RequestEmailVerificationCode)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// since device must Requested before,
|
|
// Retrieve XVerification instance by Verification Code from Db
|
|
// and Validate it ...
|
|
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Update Exists User's Email Confirmation ...
|
|
user.EmailConfirmed = true;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
|
|
|
|
//
|
|
request.Context.UserId = user.Id;
|
|
}
|
|
|
|
//
|
|
// Update Request Context Email Address Verification Code
|
|
// and it's Confirmation Status ...
|
|
request.Context.EmailVerificationCode = verificationCode;
|
|
request.Context.EmailVerified = true;
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.ConfirmEmailAddress,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Remove XVerificationRequest instance from Db ...
|
|
await RemoveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Query.cs
|
|
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIds.Extensions;
|
|
using xModels.Dtos;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
/// <summary>
|
|
/// Retrieve Users as Query Model for Query Service ...
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam"></param>
|
|
/// <param name="query"></param>
|
|
/// <param name="role"></param>
|
|
/// <param name="forceRole"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<string>> QueryUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query,
|
|
string role = null,
|
|
bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var items = GetUsersDbSet()
|
|
.ToList()
|
|
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
.ToList()
|
|
.AsEnumerable();
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<string>
|
|
{
|
|
Items = items
|
|
.Select(u => u.Id),
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return await Task.Run(() => result);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Registration.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Registration Actions ...
|
|
/// <summary>
|
|
/// Invite a User to Register on Dashboard
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="email">which email address is going to invite</param>
|
|
/// <param name="returnUrl">return url for invitation user to redirect</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> InviteUser(
|
|
string lang,
|
|
XDevice device,
|
|
string email,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
email,
|
|
returnUrl
|
|
)
|
|
.AddNotNull(device)
|
|
.AddEmailAddress(email)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Email is Unique ...
|
|
await ValidateUserNotExists(email);
|
|
|
|
//
|
|
// Get Request Result ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
email,
|
|
XAction.Invite,
|
|
forceCheckContext: false,
|
|
forceCheckUserExists: false);
|
|
|
|
//
|
|
// Prepare Propper Message ...
|
|
var xMessage = GetUserInviteMessage(lang, email, result.Token, returnUrl);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
// Send Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recieve some Basic Informations and Start Registration Proccess
|
|
/// if they Valid
|
|
///
|
|
/// Registration Proccess Starts with Invoking this Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="invitationHash">optional, if user invited, this is the invitation token</param>
|
|
/// <param name="firstName">user's FirstName</param>
|
|
/// <param name="lastName">user's LastName</param>
|
|
/// <param name="dateOfBirth">user's dob date</param>
|
|
/// <param name="mobileNumber">user's Mobile Number</param>
|
|
/// <param name="emailAddress">user's Email address</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string invitationHash,
|
|
string firstName,
|
|
string lastName,
|
|
DateTime dateOfBirth,
|
|
string mobileNumber = null,
|
|
string emailAddress = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
firstName,
|
|
lastName
|
|
)
|
|
.AddNotNull(
|
|
device,
|
|
dateOfBirth
|
|
)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Validate Mobile Number if Exists ...
|
|
if (!mobileNumber.IsNullOrEmpty())
|
|
{
|
|
//
|
|
ValidationProvider.MobileNumber(mobileNumber);
|
|
|
|
//
|
|
// Check Mobile is Uniqsue ...
|
|
await ValidateUserNotExists(mobileNumber);
|
|
}
|
|
|
|
//
|
|
// Validate Email Address if Exists ...
|
|
if (!emailAddress.IsNullOrEmpty())
|
|
{
|
|
//
|
|
ValidationProvider.EmailAddress(emailAddress);
|
|
|
|
//
|
|
// Check Email is Unique ...
|
|
await ValidateUserNotExists(emailAddress);
|
|
}
|
|
|
|
//
|
|
// Get Related Token and Validate it and
|
|
// Check Related Configurations ...
|
|
await ValidateInvitationHash(invitationHash);
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Validate DateOfBirth ...
|
|
ValidateDateOfBirth(dateOfBirth);
|
|
|
|
//
|
|
// Define Empty Objects for Using ...
|
|
var userSelectByParam = "";
|
|
var context = new XActionRequestContext();
|
|
//
|
|
context.Lang = lang;
|
|
context.Device = device;
|
|
context.LastName = lastName;
|
|
context.FirstName = firstName;
|
|
context.DateOfBirth = dateOfBirth;
|
|
context.MobileNumber = mobileNumber ?? "";
|
|
context.Email = !emailAddress.IsNullOrEmpty() ? emailAddress.ToNormalString() : "";
|
|
|
|
//
|
|
userSelectByParam = GetUserSelectByParam(context);
|
|
|
|
//
|
|
// Token Data Parsing ...
|
|
if (!invitationHash.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Get Related Token, Validate it and Parse Contains
|
|
// XAction Request and Validate the Request itself and
|
|
// Return it ...
|
|
var inviteRequest = await ValidateAndParseActionHash(invitationHash);
|
|
|
|
//
|
|
// Extract User Select By Param and Type ...
|
|
userSelectByParam = GetUserSelectByParam(inviteRequest);
|
|
var userSelectBy = GetUserSelectByType(userSelectByParam);
|
|
|
|
//
|
|
// Check Invitation Only done with Email Address ...
|
|
if (userSelectBy != XUserSelectBy.Email)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Invited Email and Given Email to be Same ...
|
|
if (emailAddress.IsNullOrEmpty() ||
|
|
(!emailAddress.IsNullOrEmpty() &&
|
|
!emailAddress.IsValidEmail()))
|
|
{
|
|
XException.InvalidEmailAddress.Throw();
|
|
}
|
|
var isSameEmail = inviteRequest.Context.Email.ToNormalString() == emailAddress.ToNormalString();
|
|
if (!isSameEmail)
|
|
{
|
|
XException.EmailsSame.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Context Email for Request Action ...
|
|
context.Email = userSelectByParam.ToNormalString();
|
|
context.EmailVerified = true;
|
|
}
|
|
|
|
//
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.Registration,
|
|
context,
|
|
forceCheckUserExists: false
|
|
);
|
|
|
|
//
|
|
// Remove Invitation Token ...
|
|
if (!invitationHash.IsNullOrEmpty())
|
|
{
|
|
await RemoveTokenByHash(invitationHash);
|
|
}
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add User Account Info
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="userName">user name</param>
|
|
/// <param name="password">assigne password</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> AddAcountInfo(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string userName,
|
|
string password
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
actionToken,
|
|
userName,
|
|
password)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Validate a UserSelector is Available or not ...
|
|
await ValidateCanRegister(userName);
|
|
|
|
//
|
|
// Check UserName is Unique ...
|
|
await ValidateUserNotExists(userName);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Validate Requeired Data for Register User must be in Action Context ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotNull(
|
|
request.Context,
|
|
request.Context.Device,
|
|
request.Context.DateOfBirth)
|
|
.AddNotEmpty(
|
|
request.Context.Email,
|
|
request.Context.MobileNumber,
|
|
request.Context.FirstName,
|
|
request.Context.LastName)
|
|
.AddEmailAddress(request.Context.Email)
|
|
.AddMobileNumber(request.Context.MobileNumber)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGivenDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// Validate Request Pointer User doesn't Exists ...
|
|
await ValidateUserNotExists(userSelectByParam);
|
|
|
|
//
|
|
// Create an Empty Instance of XUser ...
|
|
var xUser = new XUser();
|
|
|
|
//
|
|
// Start Filling User Fields ...
|
|
xUser.UserName = userName;
|
|
xUser.Email = request.Context.Email;
|
|
xUser.PhoneNumber = request.Context.MobileNumber;
|
|
|
|
//
|
|
xUser.FirstName = request.Context.FirstName;
|
|
xUser.LastName = request.Context.LastName;
|
|
xUser.DateOfBirth = request.Context.DateOfBirth;
|
|
|
|
//
|
|
xUser.EmailConfirmed = request.Context.EmailVerified;
|
|
xUser.PhoneNumberConfirmed = request.Context.MobileVerified;
|
|
|
|
//
|
|
xUser.CreationDate = DateTime.UtcNow;
|
|
xUser.LastLogin = null;
|
|
|
|
//
|
|
#region Handling New User IsEnable State ...
|
|
//
|
|
// By Default New Users will Enables ...
|
|
xUser.IsEnable = true;
|
|
xUser.IsBanned = false;
|
|
|
|
//
|
|
// Check Auto Enable Users ...
|
|
if (Configuration.RequireRegistrationConfirm)
|
|
{
|
|
xUser.IsEnable = false;
|
|
}
|
|
|
|
//
|
|
// Check Auto Confirm Email Users ...
|
|
if (Configuration.AutoConfirmNewUsersEmail)
|
|
{
|
|
xUser.EmailConfirmed = true;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Check Auto Confirm Phone Number Users ...
|
|
if (Configuration.AutoConfirmNewUsersPhoneNumber)
|
|
{
|
|
xUser.PhoneNumberConfirmed = true;
|
|
}
|
|
|
|
//
|
|
// Validating given Password ...
|
|
await ValidatePasswordPolicies(xUser, password);
|
|
|
|
//
|
|
// Now add new User to Database ...
|
|
var createUserResult = await CreateUserAsync(xUser, password);
|
|
if (!createUserResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Request UserId Value ...
|
|
request.Context.UserId = xUser.Id;
|
|
request.Context.UserName = xUser.UserName;
|
|
|
|
//
|
|
#region Handling New User Role ...
|
|
//
|
|
// Now Try to Assign Default User role ...
|
|
var isContainsDefaultUserRole = !Configuration.NewUsersRole.IsNullOrEmpty();
|
|
if (isContainsDefaultUserRole)
|
|
{
|
|
//
|
|
var newUserRoleName = Configuration.NewUsersRole;
|
|
var isNewUserRoleExists = await IsRoleExistsAsync(newUserRoleName);
|
|
//
|
|
// Make Sure New User role Exists ...
|
|
if (!isNewUserRoleExists)
|
|
{
|
|
//
|
|
// Create Default Roles ...
|
|
await CreateIdentityRoles();
|
|
}
|
|
|
|
//
|
|
// Assign User to Role ...
|
|
var assignNewUserToRoleResult = await AddUserToRoleAsync(xUser, newUserRoleName);
|
|
if (!assignNewUserToRoleResult.Succeeded)
|
|
{
|
|
//
|
|
// Delete User if Role Assignment Faild ...
|
|
await UserManager.DeleteAsync(xUser);
|
|
|
|
//
|
|
// Thrown ActionFailed Error ...
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Handle Profile Image ...
|
|
// Save and Attach Profile Image to User if it's Added Before ...
|
|
if (!request.Context.UserId.IsNullOrEmpty() &&
|
|
!request.Context.Thubmnail.IsNull())
|
|
{
|
|
//
|
|
xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider
|
|
.HandleProfileImageSave(request.Context.Thubmnail);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = request.Context.UserId,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (updateResult.Succeeded)
|
|
{
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Handle Attaching User device ...
|
|
var xUserDevice = await AddUserRelatedDevice(
|
|
userSelectByParam,
|
|
device,
|
|
checkCanLoginPolicies: false);
|
|
|
|
//
|
|
// Prepare New Token Result Resource,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.Finish,
|
|
request.Context,
|
|
forceCheckUserExists: false
|
|
);
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach Profile Image
|
|
/// </summary>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="file">an instance of <see>IFormFile</see> for user's Avatar</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> AttachProfileImage(
|
|
string actionToken,
|
|
IFormFile file
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(actionToken)
|
|
.AddNotNull(file)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Given FormFile as Profile Image ...
|
|
StorageProvider.ValidateProfileImage(file);
|
|
|
|
//
|
|
request.Context.Thubmnail = file;
|
|
|
|
//
|
|
// Save and Attach Profile Image to User if it's Added Before ...
|
|
if (!request.Context.UserId.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider.HandleProfileImageSave(file);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = request.Context.UserId,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (updateResult.Succeeded)
|
|
{
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remove Invitation Token ...
|
|
if (!actionToken.IsNullOrEmpty())
|
|
{
|
|
await RemoveTokenByHash(actionToken);
|
|
}
|
|
|
|
//
|
|
var result = await ActionRequest(
|
|
request.Context.Lang,
|
|
request.Context.Device,
|
|
userSelectByParam,
|
|
XAction.ProfileAction,
|
|
request.Context,
|
|
forceCheckUserExists: false
|
|
);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finishing Registration
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="password">assigne password</param>
|
|
/// <param name="returnUrl">return url for invitation user to redirect</param>
|
|
/// <returns></returns>
|
|
public async Task FinishRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, userSelectByParam, password, returnUrl)
|
|
.AddNotNull(device)
|
|
.AddUrl(returnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Validate User Exists And Retrieve it ...
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
#region Handling New User Email Notification Senario ...
|
|
//
|
|
// Here we Check if User is Enable and Approved Email
|
|
// send RegisteredMsg and if User is not Enable and
|
|
// Verify Registration value in Configuration is True
|
|
// send Verify Registration mail to user and handle it ...
|
|
if (Configuration.RequireRegistrationConfirm)
|
|
{
|
|
//
|
|
if (xUser.IsEnable)
|
|
{
|
|
//
|
|
// Send Registration Finished Message ...
|
|
// since in this step we need to prevent errors from
|
|
// going forward. add this try catch here ...
|
|
try
|
|
{
|
|
//
|
|
var xMessage = GetRegistrationFinishedMessage(lang, xUser.Email, returnUrl);
|
|
|
|
//
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Send Registration Confirm Message ...
|
|
// since in this step we need to prevent errors from
|
|
// going forward. add this try catch here ...
|
|
try
|
|
{
|
|
//
|
|
var request = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.Finish,
|
|
forceCheckContext: false,
|
|
forceCheckUserExists: true);
|
|
|
|
//
|
|
var xMessage = GetRegistrationConfirmMessage(lang, xUser.Email, request.Token, returnUrl);
|
|
|
|
//
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
// //
|
|
// await RemoveTokenByDevice (device);
|
|
#endregion
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Request.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Action Handlers ...
|
|
/// <summary>
|
|
/// Request an Action
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <param name="step">a member of <see>XAction</see> which represent Action Step</param>
|
|
/// <param name="context">an instance of <see>XActionRequestContext</see> which provides required informations for specified step</param>
|
|
/// <param name="forceCheckContext">specify checking context, default is false</param>
|
|
/// <param name="forceCheckUserExists">specify check user exists, default is true</param>
|
|
/// <param name="forceCheckUserDevice">specify check user and device relation, default is false</param>
|
|
/// <param name="forceRenewToken">specifies force renew Action Token if it's expired, default is false</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
private async Task<XActionResponse> ActionRequest(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
XAction step,
|
|
XActionRequestContext context = null,
|
|
bool forceCheckContext = false,
|
|
bool forceCheckUserExists = true,
|
|
bool forceCheckUserDevice = false,
|
|
bool forceRenewToken = false
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(lang);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Check Device not Banned ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Check User Exists and Device Relation ...
|
|
if (forceCheckUserExists)
|
|
{
|
|
if (forceCheckUserDevice)
|
|
{
|
|
//
|
|
if (context.Device != null &&
|
|
!device.IsSameAs(context.Device))
|
|
{
|
|
XException.InvalidDevice.Throw();
|
|
}
|
|
|
|
//
|
|
await ValidateUserAndDeviceRelation(userSelectByParam, device);
|
|
}
|
|
else
|
|
{
|
|
await ValidateUserExistsAsync(userSelectByParam);
|
|
}
|
|
}
|
|
|
|
//
|
|
XToken xToken = null;
|
|
XActionResponse result = null;
|
|
XActionRequestToken xRequest = null;
|
|
|
|
//
|
|
var isExists = false;
|
|
var forceUserSelectByParamNotEmpty = true;
|
|
switch (step)
|
|
{
|
|
case XAction.Registration:
|
|
//
|
|
forceUserSelectByParamNotEmpty = false;
|
|
isExists = await IsTokenExistsByDeviceAndType(device, step);
|
|
|
|
//
|
|
if (isExists)
|
|
{
|
|
xToken = await ValidateAndRetieveTokenByDeviceAndType(device, step);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
//
|
|
isExists = await IsTokenExistsByUserAndType(userSelectByParam, step);
|
|
|
|
//
|
|
if (isExists)
|
|
{
|
|
xToken = await ValidateAndRetieveTokenByUserAndType(userSelectByParam, step);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
if (isExists)
|
|
{
|
|
//
|
|
var isValidToken = IsValidToken(xToken.Token);
|
|
if (!isValidToken && !forceRenewToken)
|
|
{
|
|
switch (step)
|
|
{
|
|
case XAction.Registration:
|
|
case XAction.Invite:
|
|
forceRenewToken = true;
|
|
break;
|
|
|
|
default:
|
|
throw XException.InvalidToken.ToException();
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!isValidToken && forceRenewToken)
|
|
{
|
|
await ValidateAndHandleToken(xToken.Token);
|
|
return await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
step,
|
|
context,
|
|
forceCheckContext,
|
|
forceCheckUserExists,
|
|
forceCheckUserDevice,
|
|
forceRenewToken);
|
|
}
|
|
|
|
//
|
|
xRequest = ValidateAndParseActionToken(xToken.Token);
|
|
|
|
//
|
|
// Check Exists Context ...
|
|
if (forceCheckContext)
|
|
{
|
|
//
|
|
var isSameContext = xRequest.Context.IsSameAs(context);
|
|
if (!isSameContext)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
if (context != null)
|
|
{
|
|
//
|
|
var contextUserSelectByParam = GetUserSelectByParam(
|
|
context,
|
|
false,
|
|
new List<XUserSelectBy> {
|
|
XUserSelectBy.ID,
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
var contextLang = context.Lang;
|
|
var contextDevice = context.Device;
|
|
|
|
//
|
|
// prevent from issues on Registration Request ...
|
|
if (forceUserSelectByParamNotEmpty)
|
|
{
|
|
var userSelectByType = GetUserSelectByType(userSelectByParam);
|
|
var contextUserSelectByType = GetUserSelectByType(contextUserSelectByParam);
|
|
if (contextUserSelectByType != userSelectByType)
|
|
{
|
|
//
|
|
var excludesList = GenerateUserSelectByExcludes(new List<XUserSelectBy> { userSelectByType });
|
|
|
|
//
|
|
contextUserSelectByParam = GetUserSelectByParam(context, false, excludesList);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fix Device Not Same on Invitation and Request
|
|
if (step == XAction.Registration)
|
|
{
|
|
//
|
|
context.Device = device;
|
|
contextDevice = context.Device;
|
|
}
|
|
|
|
//
|
|
// Validate Context Data must be Same as Request Data ...
|
|
if ((!contextUserSelectByParam.IsNullOrEmpty() &&
|
|
contextUserSelectByParam != userSelectByParam) ||
|
|
(!contextLang.IsNullOrEmpty() &&
|
|
contextLang != lang) ||
|
|
(contextDevice != null &&
|
|
!contextDevice.IsSameAs(device)))
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device
|
|
};
|
|
|
|
//
|
|
// Add Content ...
|
|
var userSelectByType = GetUserSelectByType(
|
|
userSelectByParam,
|
|
forceUserSelectByParamNotEmpty);
|
|
switch (userSelectByType)
|
|
{
|
|
case XUserSelectBy.MobileNumber:
|
|
context.MobileNumber = userSelectByParam;
|
|
break;
|
|
|
|
case XUserSelectBy.Email:
|
|
context.Email = userSelectByParam;
|
|
break;
|
|
|
|
case XUserSelectBy.Username:
|
|
context.UserName = userSelectByParam;
|
|
break;
|
|
|
|
case XUserSelectBy.ID:
|
|
context.UserId = userSelectByParam;
|
|
break;
|
|
|
|
case XUserSelectBy.NotSpecified:
|
|
default:
|
|
if (forceCheckUserExists)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Generate Registration Request ...
|
|
xRequest = new XActionRequestToken
|
|
{
|
|
Action = step,
|
|
Context = context
|
|
};
|
|
|
|
//
|
|
// Add User Id if Exists to Context ...
|
|
var isUserExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (isUserExists)
|
|
{
|
|
//
|
|
var user = await GetUserAsync(userSelectByParam);
|
|
if (user != null)
|
|
{
|
|
xRequest.Context.UserId = user.Id;
|
|
}
|
|
}
|
|
|
|
//
|
|
xRequest.Prepare(Configuration.IdentitySecretKey);
|
|
|
|
//
|
|
xToken = await HashRequest(
|
|
xRequest,
|
|
forceUserSelectByParamNotEmpty);
|
|
}
|
|
|
|
//
|
|
// When XToken Exists Passed XToken ...
|
|
result = GetActionResultResponse(xToken);
|
|
|
|
//
|
|
if (result == null)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request a Mobile Verification Code
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="mobileNumber">the mobile number which is going to request a verification code</param>
|
|
/// <param name="checkMobileInUse">check mobile number is in use or not, default is true</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
private async Task<XActionResponse> RequestMobileVerificationCode(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string mobileNumber,
|
|
bool checkMobileInUse = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, mobileNumber)
|
|
.AddMobileNumber(mobileNumber)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Check Mobile is Unique ...
|
|
if (checkMobileInUse)
|
|
{
|
|
var isUserExists = await IsUserExistsAsync(mobileNumber);
|
|
if (isUserExists)
|
|
{
|
|
//
|
|
var xUser = await GetUserAsync(mobileNumber);
|
|
|
|
//
|
|
if (xUser.PhoneNumberConfirmed)
|
|
{
|
|
XException.MobileInUsed.Throw();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
request,
|
|
forceNotNull: false,
|
|
excludes: new List<XUserSelectBy> {
|
|
XUserSelectBy.ID,
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// if it's null, means user doesn't have Invitation Token
|
|
// and there is no User Selector ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Since Mobile is Unique so it can act as a
|
|
// UserSelector ...
|
|
userSelectByParam = mobileNumber;
|
|
}
|
|
|
|
//
|
|
// Define empty Verification Code
|
|
// and Empty Verification Request ...
|
|
var verificationCode = "";
|
|
XVerificationRequest xVerificationRequest = null;
|
|
|
|
//
|
|
// Check Device Request Verification Code before or Not ...
|
|
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
|
|
if (isDeviceRequested)
|
|
{
|
|
//
|
|
// if Requested before, Retrieve XVerification instance by Device from Db
|
|
// and Validate it ...
|
|
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
|
|
|
|
//
|
|
if (xVerificationRequest.VerificationCode.IsNullOrEmpty())
|
|
{
|
|
//
|
|
verificationCode = GenerateRandom().ToString();
|
|
xVerificationRequest.VerificationCode = verificationCode;
|
|
|
|
//
|
|
await RemoveVerificationCodeRequestByDevice(
|
|
device,
|
|
saveChanges: false
|
|
);
|
|
await AddVerificationRequest(
|
|
xVerificationRequest,
|
|
saveChanges: false
|
|
);
|
|
|
|
//
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
// if XVerificationRequest is Valid, it must Contain an Alive Verification Code
|
|
// so retrieve it and assign it ...
|
|
verificationCode = xVerificationRequest.VerificationCode;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
verificationCode = GenerateRandom().ToString();
|
|
}
|
|
|
|
//
|
|
// if it's First Verification Request of given Device
|
|
// Generate a new Verification Code ...
|
|
if (verificationCode.IsNullOrEmpty())
|
|
{
|
|
verificationCode = GenerateRandom().ToString();
|
|
}
|
|
|
|
//
|
|
// Check Context Mobile and given Mobile ...
|
|
if (!request.Context.MobileNumber.IsNullOrEmpty() &&
|
|
mobileNumber != request.Context.MobileNumber)
|
|
{
|
|
XException.InvalidMobileNumber.Throw();
|
|
}
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Check Mobiles Same ...
|
|
if (user.PhoneNumber == mobileNumber &&
|
|
user.PhoneNumberConfirmed)
|
|
{
|
|
XException.MobilesSame.Throw();
|
|
}
|
|
|
|
//
|
|
// Update User Object's Mobile Number and
|
|
// Confirmation Status ...
|
|
user.PhoneNumber = mobileNumber;
|
|
user.PhoneNumberConfirmed = false;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
|
|
}
|
|
|
|
//
|
|
// Prepare Verification Request by Checking Next Tries,
|
|
// Device Status, and etc, Update or Add XVerificationRequest to db
|
|
// and Retrieve the added Entity ...
|
|
xVerificationRequest = await HandleVerificationRequestPreparation(verificationCode, request);
|
|
|
|
//
|
|
// Update Request Context MobileNumber
|
|
// and it's Confirmation Status ...
|
|
request.Context.MobileNumber = mobileNumber;
|
|
request.Context.MobileVerified = false;
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Prepare New Token Result Resource,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestMobileVerificationCode,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetVerificationCodeMessage(lang, mobileNumber, verificationCode);
|
|
|
|
//
|
|
// Send Verification Code Message to User Using SMS Provider ...
|
|
await MessageProvider.SendSmsAsync(xMessage, throwException: false);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request a Email Verification Code
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="emailAddress">the email address which is going to request a verification code</param>
|
|
/// <param name="checkEmailInUse">check email address is in use or not, default is true</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestEmailVerificationCode(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string emailAddress,
|
|
bool checkEmailInUse = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, emailAddress)
|
|
.AddEmailAddress(emailAddress)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Check Email is Unique ...
|
|
if (checkEmailInUse)
|
|
{
|
|
var isUserExists = await IsUserExistsAsync(emailAddress);
|
|
if (isUserExists)
|
|
{
|
|
//
|
|
var xUser = await GetUserAsync(emailAddress);
|
|
|
|
//
|
|
if (xUser.EmailConfirmed)
|
|
{
|
|
XException.EmailInUsed.Throw();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
request,
|
|
forceNotNull: false,
|
|
excludes: new List<XUserSelectBy> {
|
|
XUserSelectBy.ID,
|
|
XUserSelectBy.Email,
|
|
XUserSelectBy.MobileNumber
|
|
});
|
|
|
|
//
|
|
// if it's null, means user doesn't have Invitation Token
|
|
// and there is no User Selector ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Since Email is Unique so it can act as a
|
|
// UserSelector ...
|
|
userSelectByParam = emailAddress;
|
|
}
|
|
|
|
//
|
|
// Define empty Verification Code
|
|
// and Empty Verification Request ...
|
|
var verificationCode = "";
|
|
XVerificationRequest xVerificationRequest = null;
|
|
|
|
//
|
|
// Check Device Request Verification Code before or Not ...
|
|
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
|
|
if (isDeviceRequested)
|
|
{
|
|
//
|
|
// if Requested before, Retrieve XVerification instance by Device from Db
|
|
// and Validate it ...
|
|
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
|
|
|
|
//
|
|
if (xVerificationRequest.VerificationCode.IsNullOrEmpty())
|
|
{
|
|
//
|
|
verificationCode = GenerateRandom().ToString();
|
|
xVerificationRequest.VerificationCode = verificationCode;
|
|
|
|
//
|
|
await RemoveVerificationCodeRequestByDevice(
|
|
device,
|
|
saveChanges: false
|
|
);
|
|
await AddVerificationRequest(
|
|
xVerificationRequest,
|
|
saveChanges: true
|
|
);
|
|
}
|
|
|
|
//
|
|
// if XVerificationRequest is Valid, it must Contain an Alive Verification Code
|
|
// so retrieve it and assign it ...
|
|
verificationCode = xVerificationRequest.VerificationCode;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
verificationCode = GenerateRandom().ToString();
|
|
}
|
|
|
|
//
|
|
// Check Context Email and given Email ...
|
|
if (!request.Context.Email.IsNullOrEmpty() &&
|
|
emailAddress != request.Context.Email)
|
|
{
|
|
XException.InvalidEmailAddress.Throw();
|
|
}
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Check Email Same ...
|
|
if (user.Email == emailAddress &&
|
|
user.EmailConfirmed)
|
|
{
|
|
XException.MobilesSame.Throw();
|
|
}
|
|
|
|
//
|
|
// Update User Object's Email and
|
|
// Confirmation Status ...
|
|
user.Email = emailAddress;
|
|
user.EmailConfirmed = false;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Verification Request by Checking Next Tries,
|
|
// Device Status, and etc, Update or Add XVerificationRequest to db
|
|
// and Retrieve the added Entity ...
|
|
xVerificationRequest = await HandleVerificationRequestPreparation(verificationCode, request);
|
|
|
|
//
|
|
// Update Request Context Email
|
|
// and it's Confirmation Status ...
|
|
request.Context.Email = emailAddress;
|
|
request.Context.EmailVerified = false;
|
|
|
|
//
|
|
// Prepare New Token Result Resource,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestEmailVerificationCode,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Remove Hash ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetVerificationCodeMessage(lang, emailAddress, verificationCode);
|
|
|
|
//
|
|
// Send Verification Code Message to User Using Mail Provider ...
|
|
await MessageProvider.SendMailAsync(xMessage, throwException: false);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Role.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Role Actions ...
|
|
/// <summary>
|
|
/// Check a Role exists or not
|
|
/// </summary>
|
|
/// <param name="roleName">role name</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsRoleExistsAsync(
|
|
string roleName
|
|
)
|
|
{
|
|
//
|
|
if (roleName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return await RoleManager.RoleExistsAsync(roleName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new Role
|
|
/// </summary>
|
|
/// <param name="roleName">role name</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> CreateRoleAsync(
|
|
string roleName
|
|
)
|
|
{
|
|
//
|
|
var isExists = await RoleManager
|
|
.RoleExistsAsync(roleName);
|
|
if (isExists)
|
|
{
|
|
XException.Duplicate.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await RoleManager
|
|
.CreateAsync(new IdentityRole(roleName));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Role
|
|
/// </summary>
|
|
/// <param name="roleName">role name</param>
|
|
/// <returns>an instance of <see>IdentityRole</see></returns>
|
|
public async Task<IdentityRole> GetRoleAsync(
|
|
string roleName
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsRoleExistsAsync(roleName);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await RoleManager
|
|
.FindByNameAsync(roleName);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a User From Role
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="roleName">role name</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> RemoveFromRoleAsync(
|
|
XUser user,
|
|
string roleName
|
|
)
|
|
{
|
|
return await UserManager.RemoveFromRoleAsync(user, roleName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a User From Roles
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="roleNames">a collection of role names</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> RemoveFromRolesAsync(
|
|
XUser user,
|
|
IEnumerable<string> roleNames
|
|
)
|
|
{
|
|
return await UserManager.RemoveFromRolesAsync(user, roleNames);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Assign a User to Specific Role
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="roleName">role name</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> AddUserToRoleAsync(
|
|
XUser user,
|
|
string roleName
|
|
)
|
|
{
|
|
//
|
|
if (user == null ||
|
|
roleName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var userSelectByParam = GetUserSelectByParam(user);
|
|
var isExistsUser = await IsUserExistsAsync(userSelectByParam);
|
|
var isExistsRole = await IsRoleExistsAsync(roleName);
|
|
if (!isExistsUser || !isExistsRole)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await UserManager
|
|
.AddToRoleAsync(user, roleName);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Role Name by it's ID
|
|
/// </summary>
|
|
/// <param name="roleId">role id</param>
|
|
/// <returns>role name as string</returns>
|
|
public async Task<string> GetRoleNameAsync(
|
|
string roleId
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (roleId.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var role = await RoleManager
|
|
.FindByIdAsync(roleId);
|
|
|
|
//
|
|
return role.Name.ToNormalString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a List Of User Roles
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="checkCanLoginPolicies"></param>
|
|
/// <param name="checkIsBanned"></param>
|
|
/// <returns>a collection of role names</returns>
|
|
public async Task<IEnumerable<string>> GetRoleNamesAsync(
|
|
string userSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
var result = new List<string>();
|
|
foreach (var role in user.Roles)
|
|
{
|
|
//
|
|
var roleName = await GetRoleNameAsync(role.RoleId);
|
|
roleName = roleName.ToNormalString();
|
|
|
|
//
|
|
result.Add(roleName);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is Adminr not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsAdmin(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: true);
|
|
|
|
//
|
|
var result = await IsAdmin(user);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User is Adminr not
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsAdmin(
|
|
XUser user
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(user);
|
|
ValidationProvider.NotEmpty(user.Id);
|
|
|
|
//
|
|
// Retrieve Admin Role ...
|
|
// TODO: Fix this ...
|
|
var adminRole = "admin";
|
|
// XUserRole.Admin
|
|
// .GetStringValue ()
|
|
// .ToNormalString ();
|
|
|
|
//
|
|
// Check Admin Role Exists in User Roles or not ...
|
|
var userRoleNames = await GetRoleNamesAsync(user.Id);
|
|
var isContainsAdminRole = userRoleNames.Contains(adminRole);
|
|
|
|
//
|
|
// Return Result ...
|
|
return isContainsAdminRole;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Search.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xModels.Dtos;
|
|
using xDataService.Extensions;
|
|
using xIds.Extensions;
|
|
using System.Linq;
|
|
using xIdentityModels.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Query User Profiles
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryOpenToSearchUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var totalEntities = GetUsersDbSet()
|
|
.Where(u => u.OpenToSearch)
|
|
.ToList()
|
|
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
.Select(u => u.Id)
|
|
.ToList();
|
|
|
|
//
|
|
var items = await GetUserProfilesAsync(
|
|
totalEntities,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false
|
|
);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XUserProfileDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Seed.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Descriptors;
|
|
using xIdentityModels.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Default Identity Preparation Actions ...
|
|
/// <summary>
|
|
/// Create Default Roles based on Identity Configuration
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task CreateIdentityRoles()
|
|
{
|
|
//
|
|
if (Configuration == null ||
|
|
Configuration.IdentityRoles == null ||
|
|
Configuration.IdentityRoles.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check New Users Role exists in IdentityRole or not ...
|
|
if (!Configuration.NewUsersRole.IsNullOrEmpty())
|
|
{
|
|
//
|
|
// Ensure NewUsersRole Exists in IdentityRoles ...
|
|
var isNewUserRoleExistsInIdentityRoles = Configuration
|
|
.IdentityRoles
|
|
.Contains(Configuration.NewUsersRole);
|
|
if (!isNewUserRoleExistsInIdentityRoles)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
}
|
|
|
|
//
|
|
// loop through all roles and create them one by one ...
|
|
foreach (var roleName in Configuration.IdentityRoles)
|
|
{
|
|
//
|
|
var isRoleExists = await RoleManager.RoleExistsAsync(roleName);
|
|
if (!isRoleExists)
|
|
{
|
|
//
|
|
var result = await RoleManager.CreateAsync(new IdentityRole(roleName));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a user Based on User Descriptor
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XIdentityUserDescriptor</see></param>
|
|
/// <returns></returns>
|
|
public async Task CreateUserAsync(
|
|
XIdentityUserDescriptor user
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(user);
|
|
|
|
//
|
|
var isExistsRole = await RoleManager.RoleExistsAsync(user.Role);
|
|
if (!isExistsRole)
|
|
{
|
|
//
|
|
// Check Assigned role to user exists in app roles ...
|
|
if (!Configuration
|
|
.IdentityRoles
|
|
.Contains(user.Role))
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Ensure All Roles Created ...
|
|
await CreateIdentityRoles();
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
var isExistsUser = await IsUserExistsAsync(user.UserName);
|
|
if (!isExistsUser)
|
|
{
|
|
//
|
|
// Create a DashboardUser instance based on Configuration Data ...
|
|
var userEntity = user.ToXUser();
|
|
|
|
//
|
|
// Try to Create User ...
|
|
var userCreateResult = await CreateUserAsync(
|
|
userEntity,
|
|
user.Password
|
|
);
|
|
if (!userCreateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Assign Admin User to it's Role ...
|
|
var roleAssignResult = await UserManager.AddToRoleAsync(userEntity, user.Role);
|
|
if (!roleAssignResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var claims = await ToJwtClaims(
|
|
userEntity,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
var addClaimsResult = await UserManager.AddClaimsAsync(userEntity, claims);
|
|
if (!addClaimsResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Token.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Token Actions ...
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsByDeviceAndType(
|
|
XDevice device,
|
|
XAction type
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
var isExists = false;
|
|
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in enumerator)
|
|
{
|
|
//
|
|
if (token.Type == type &&
|
|
token.Device.IsSameAs(device))
|
|
{
|
|
isExists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return isExists;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsByUserAndType(
|
|
string userSelectByParam,
|
|
XAction type
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var isExists = false;
|
|
var tokensEnumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in tokensEnumerator)
|
|
{
|
|
//
|
|
if (token.Type == type &&
|
|
token.UserSelectByParam
|
|
.ToNormalString() == userSelectByParam
|
|
.ToNormalString())
|
|
{
|
|
//
|
|
isExists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return isExists;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsByToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
var result = await DbContext.Tokens
|
|
.AnyAsync(xt => xt.Token == token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="hash">represent specified action token hash</param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsByHash(
|
|
string hash
|
|
)
|
|
{
|
|
//
|
|
var result = await DbContext.Tokens
|
|
.AnyAsync(xt => xt.Hash == hash);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="item">an instance of <see>XToken</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsByToken(
|
|
XToken item
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var tokenEnumerator = DbContext.Tokens
|
|
.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in tokenEnumerator)
|
|
{
|
|
//
|
|
if (token.Hash == item.Hash &&
|
|
token.Token == item.Token &&
|
|
token.Type == item.Type &&
|
|
token.UserSelectByParam
|
|
.ToNormalString() == item.UserSelectByParam
|
|
.ToNormalString() &&
|
|
token.Device.IsSameAs(item.Device))
|
|
{
|
|
//
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Token Entity Exists or not
|
|
/// </summary>
|
|
/// <param name="id">specifies token id</param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsTokenExistsById(
|
|
int id
|
|
)
|
|
{
|
|
return await DbContext.Tokens.AnyAsync(t => t.Id == id);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Token Entity
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> GetTokenByDeviceAndType(
|
|
XDevice device,
|
|
XAction type
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsTokenExistsByDeviceAndType(device, type);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
XToken item = null;
|
|
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in enumerator)
|
|
{
|
|
//
|
|
if (token.Type == type &&
|
|
token.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
item = token;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Token Entity
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <param name="type">specifies Action Step by a member of <see>XAction</see></param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> GetTokenByUserAndType(
|
|
string userSelectByParam,
|
|
XAction type
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsTokenExistsByUserAndType(userSelectByParam, type);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
XToken item = null;
|
|
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in enumerator)
|
|
{
|
|
//
|
|
if (token.Type == type &&
|
|
token.UserSelectByParam
|
|
.ToNormalString() == userSelectByParam
|
|
.ToNormalString())
|
|
{
|
|
//
|
|
item = token;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Token Entity
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> GetTokenByToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsTokenExistsByToken(token);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = await DbContext.Tokens
|
|
.FirstOrDefaultAsync(xt => xt.Token == token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Related Hash to a Token
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>hash string</returns>
|
|
private async Task<string> GetRelatedHashByToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
var item = await GetTokenByToken(token);
|
|
if (item == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return item.Hash;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Token Entity
|
|
/// </summary>
|
|
/// <param name="hash">represent specified action token hash</param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> GetTokenByHash(
|
|
string hash
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByHash(hash);
|
|
if (!isExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var item = await DbContext.Tokens
|
|
.FirstOrDefaultAsync(t => t.Hash == hash);
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Related Token to a Hash string
|
|
/// </summary>
|
|
/// <param name="hash">represent specified action token hash</param>
|
|
/// <returns>token string</returns>
|
|
private async Task<string> GetRelatedTokenByHash(
|
|
string hash
|
|
)
|
|
{
|
|
//
|
|
var item = await GetTokenByHash(hash);
|
|
if (item == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return item.Token;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Token Expiration Date
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>an instance of <see>DateTime</see></returns>
|
|
private DateTime GetTokenExpirationDate(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
var result = IdentityHelper.GetTokenExpirationDate(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Token Entity
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns></returns>
|
|
private async Task RemoveTokenByToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByToken(token);
|
|
if (!isExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var item = await GetTokenByToken(token);
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DbContext.Tokens.Remove(item);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Token Entity
|
|
/// </summary>
|
|
/// <param name="hash">represent specified action token hash</param>
|
|
/// <returns></returns>
|
|
private async Task RemoveTokenByHash(
|
|
string hash
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByHash(hash);
|
|
if (!isExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var item = await GetTokenByHash(hash);
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DbContext.Tokens.Remove(item);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Token Entity
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns></returns>
|
|
private async Task RemoveTokenByDevice(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
XToken items = null;
|
|
var enumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var token in enumerator)
|
|
{
|
|
//
|
|
if (token.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
items = token;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!items.IsNull())
|
|
{
|
|
DbContext.Tokens.RemoveRange(items);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// add a token Entity
|
|
/// </summary>
|
|
/// <param name="item">an instance of <see>XToken</see></param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> AddTokenAsync(
|
|
XToken item
|
|
)
|
|
{
|
|
//
|
|
var isExist = await IsTokenExistsByToken(item);
|
|
if (isExist)
|
|
{
|
|
return await GetTokenByHash(item.Hash);
|
|
}
|
|
|
|
//
|
|
var entry = await DbContext.Tokens.AddAsync(item);
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
//
|
|
return entry.Entity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hash a Request Token
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
|
|
/// <param name="forceNotNullUserSelectByParam"></param>
|
|
/// <param name="forceDeviceNotNull"></param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> HashRequest(
|
|
XActionRequestToken request,
|
|
bool forceNotNullUserSelectByParam = true,
|
|
bool forceDeviceNotNull = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
var secretKey = Configuration.IdentitySecretKey;
|
|
ValidationProvider.NotNull(request);
|
|
ValidationProvider.NotEmpty(secretKey);
|
|
|
|
//
|
|
ValidateActionRequest(request);
|
|
|
|
//
|
|
var type = request.Action;
|
|
var device = request.Context.Device;
|
|
var tokenObject = ToSecurityToken(request);
|
|
var tokenString = ToTokenString(tokenObject);
|
|
var tokenHash = ToHash(tokenString);
|
|
var userSelectByParam = GetUserSelectByParam(request, forceNotNullUserSelectByParam);
|
|
|
|
//
|
|
if (forceNotNullUserSelectByParam)
|
|
{
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
}
|
|
|
|
//
|
|
ValidationProvider.NotEmpty(tokenString, tokenHash);
|
|
|
|
//
|
|
if (forceDeviceNotNull)
|
|
{
|
|
ValidationProvider.NotNull(device);
|
|
}
|
|
|
|
//
|
|
ValidationProvider.NotNull(tokenObject);
|
|
|
|
//
|
|
var xToken = new XToken
|
|
{
|
|
Type = type,
|
|
Device = device,
|
|
Hash = tokenHash,
|
|
Token = tokenString,
|
|
UserSelectByParam = userSelectByParam
|
|
};
|
|
|
|
//
|
|
var addedToken = await AddTokenAsync(xToken);
|
|
|
|
//
|
|
return addedToken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Token Hash string
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <param name="checkValidation">check token validation parameters, default is true</param>
|
|
/// <returns>hash string</returns>
|
|
private string ToHash(
|
|
string token,
|
|
bool checkValidation = true
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
if (checkValidation)
|
|
{
|
|
ValidateToken(token);
|
|
}
|
|
|
|
//
|
|
var result = token.ToMd5String().ToNormalString();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Token string
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>token string</returns>
|
|
private string ToTokenString(
|
|
SecurityToken token
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(token, IdentityHelper);
|
|
|
|
//
|
|
var result = IdentityHelper.ToTokenString(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Token string
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>token string</returns>
|
|
private string ToTokenString(
|
|
JwtSecurityToken token
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(token, IdentityHelper);
|
|
|
|
//
|
|
var result = IdentityHelper.ToTokenString(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Security Token
|
|
/// </summary>
|
|
/// <param name="token">represent specified action token</param>
|
|
/// <returns>an instance of <see>SecurityToken</see></returns>
|
|
private SecurityToken ToSecurityToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
var result = IdentityHelper.ToSecurityToken(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate Security Token
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
|
|
/// <returns>an instance of <see>SecurityToken</see></returns>
|
|
private SecurityToken ToSecurityToken(
|
|
XActionRequestToken request
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(request);
|
|
|
|
//
|
|
ValidateActionRequest(request);
|
|
|
|
//
|
|
var result = IdentityHelper.ToSecurityToken(request);
|
|
if (result == null)
|
|
{
|
|
XException.InvalidToken.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cleanup all exists tokens related to specified User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns></returns>
|
|
private async Task HandleRemoveExistsTokens(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xTokens = new List<XToken>();
|
|
var xTokenEnumerator = DbContext.Tokens.AsAsyncEnumerable();
|
|
await
|
|
foreach (var xToken in xTokenEnumerator)
|
|
{
|
|
//
|
|
if (xToken.UserSelectByParam == userSelectByParam &&
|
|
ObjectHelper.ToEnumerableValues<XAction>().Contains(xToken.Type))
|
|
{
|
|
xTokens.Add(xToken);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (xTokens.HasChild())
|
|
{
|
|
DbContext.Tokens.RemoveRange(xTokens);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cleanup all tokens related to specified User
|
|
/// </summary>
|
|
/// <param name="userSelectByParams">a collection of user identifiers</param>
|
|
/// <returns></returns>
|
|
private async Task HandleCleanUserTokens(
|
|
ICollection<string> userSelectByParams
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!userSelectByParams.HasChild())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
foreach (var userSelectByParam in userSelectByParams)
|
|
{
|
|
await HandleRemoveExistsTokens(userSelectByParam);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cleanup all tokens related to specified User
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <returns></returns>
|
|
private async Task HandleCleanUserTokens(
|
|
XUser user
|
|
)
|
|
{
|
|
//
|
|
if (user == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var userSelectByParams = GenerateUserSelectByParams(user);
|
|
|
|
//
|
|
await HandleCleanUserTokens(userSelectByParams);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+User.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Linq;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region User Handlers ...
|
|
/// <summary>
|
|
/// Check a User Exists or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsUserExistsAsync(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userSelectByParam.IsNullOrEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var selectType = GetUserSelectByType(userSelectByParam);
|
|
|
|
//
|
|
var result = false;
|
|
XUser user = null;
|
|
switch (selectType)
|
|
{
|
|
case XUserSelectBy.MobileNumber:
|
|
user = await GetUsersDbSet()
|
|
.Where(ur => ur.PhoneNumber == userSelectByParam)
|
|
.FirstOrDefaultAsync();
|
|
break;
|
|
|
|
case XUserSelectBy.Email:
|
|
user = await UserManager
|
|
.FindByEmailAsync(userSelectByParam);
|
|
break;
|
|
|
|
case XUserSelectBy.Username:
|
|
user = await UserManager
|
|
.FindByNameAsync(userSelectByParam);
|
|
break;
|
|
|
|
case XUserSelectBy.ID:
|
|
default:
|
|
user = await UserManager
|
|
.FindByIdAsync(userSelectByParam);
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = user != null;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a User Selector is Available for Registration or Not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> CanRegister(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate ARgs ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var selectByType = GetUserSelectByType(userSelectByParam);
|
|
|
|
//
|
|
if (selectByType == XUserSelectBy.Username &&
|
|
!ValidateUserName(userSelectByParam))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var isExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (isExists)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a User object
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specified user's identifier</param>
|
|
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
|
|
/// <returns>an instance of <see>XUser</see></returns>
|
|
public async Task<XUser> GetUserAsync(
|
|
string userSelectByParam,
|
|
bool containDetails = false
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (!isExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Fill User ...
|
|
var selectType = GetUserSelectByType(userSelectByParam);
|
|
XUser user = null;
|
|
var usersStore = GetUsersDbSet(containDetails);
|
|
|
|
//
|
|
// Select Type ...
|
|
switch (selectType)
|
|
{
|
|
case XUserSelectBy.MobileNumber:
|
|
user = await usersStore
|
|
.FirstOrDefaultAsync(ur => ur.PhoneNumber ==
|
|
userSelectByParam);
|
|
break;
|
|
|
|
case XUserSelectBy.Email:
|
|
user = await usersStore
|
|
.FirstOrDefaultAsync(ur => ur.Email ==
|
|
userSelectByParam);
|
|
break;
|
|
|
|
case XUserSelectBy.Username:
|
|
user = await usersStore
|
|
.FirstOrDefaultAsync(ur => ur.UserName ==
|
|
userSelectByParam);
|
|
break;
|
|
|
|
case XUserSelectBy.ID:
|
|
default:
|
|
user = await usersStore
|
|
.FirstOrDefaultAsync(ur => ur.Id ==
|
|
userSelectByParam);
|
|
break;
|
|
}
|
|
|
|
//
|
|
return user;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve User Names based on UserIds
|
|
/// </summary>
|
|
/// <param name="userIds">a collection of user identifiers</param>
|
|
/// <returns>a collection of Usernames</returns>
|
|
public async Task<IEnumerable<string>> GetUserNamesAsync(
|
|
IEnumerable<string> userIds
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (userIds == null ||
|
|
userIds.Count() == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = await GetUsersDbSet()
|
|
.Where(
|
|
xu =>
|
|
userIds
|
|
.Contains(xu.Id))
|
|
.Select(xt => xt.UserName)
|
|
.ToListAsync();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// get user ids and retrieve corresponding user names
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XUserNameIdRequest</see> which represent required UserIds collection</param>
|
|
/// <returns>a collection of <see>XUserNameIdResponse</see> instances</returns>
|
|
public async Task<IEnumerable<XUserNameIdResponse>> GetUserNameIdsAsync(
|
|
XUserNameIdRequest model
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (model.IsNull() || !model.Ids.HasChild())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = await GetUsersDbSet()
|
|
.Where(
|
|
xu =>
|
|
model.Ids.Contains(xu.Id) ||
|
|
model.Ids.Contains(xu.Email) ||
|
|
model.Ids.Contains(xu.UserName) ||
|
|
model.Ids.Contains(xu.PhoneNumber))
|
|
.Select(xt => new XUserNameIdResponse
|
|
{
|
|
Id = xt.Id,
|
|
UserName = xt.UserName,
|
|
})
|
|
.ToListAsync();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a User
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is false</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is false</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> CreateUserAsync(
|
|
XUser user,
|
|
string password,
|
|
bool checkCanLoginPolicies = false,
|
|
bool checkIsBanned = false
|
|
)
|
|
{
|
|
//
|
|
if (user == null ||
|
|
password.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Get User Select By param
|
|
var userSelectByParam = GetUserSelectByParam(user, excludes: new List<XUserSelectBy> { XUserSelectBy.ID });
|
|
|
|
//
|
|
// Check User Created before or not ...
|
|
var isExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (isExists)
|
|
{
|
|
XException.Duplicate.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await UserManager.CreateAsync(user, password);
|
|
if (result.Succeeded)
|
|
{
|
|
//
|
|
var claims = await ToJwtClaims(
|
|
user,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned);
|
|
|
|
//
|
|
var addClaimsResult = await UserManager.AddClaimsAsync(user, claims);
|
|
|
|
//
|
|
return addClaimsResult;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a User Information
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an instance of <see>IdentityResult</see></returns>
|
|
public async Task<IdentityResult> UpdateUserAsync(
|
|
XUser user,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
var updateResult = await this.UserManager.UpdateAsync(user);
|
|
if (updateResult.Succeeded)
|
|
{
|
|
//
|
|
var claims = await ToJwtClaims(
|
|
user,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
var existsClaims = await UserManager.GetClaimsAsync(user);
|
|
|
|
//
|
|
await UserManager.RemoveClaimsAsync(user, existsClaims);
|
|
var addClaimsResult = await UserManager.AddClaimsAsync(user, claims);
|
|
|
|
//
|
|
return addClaimsResult;
|
|
}
|
|
|
|
//
|
|
return updateResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate JWT Claims froma DashboardUser object
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>a collection of <see>Claim</see> instances</returns>
|
|
public async Task<Claim[]> ToJwtClaims(
|
|
XUser user,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Get New Instance of Claims ...
|
|
var claims = new List<Claim> {
|
|
//
|
|
// Mapping to User.Identity.Name ...
|
|
new Claim (JwtClaimTypes.Name, user.UserName),
|
|
|
|
//
|
|
// Mapping to User.Identity.Name ...
|
|
new Claim (JwtRegisteredClaimNames.UniqueName, user.UserName),
|
|
|
|
//
|
|
// Other Usefull User Related Data ...
|
|
new Claim (JwtClaimTypes.GivenName, user.FirstName),
|
|
new Claim (JwtClaimTypes.FamilyName, user.LastName),
|
|
|
|
//
|
|
// User Gendre ...
|
|
new Claim (JwtClaimTypes.Gender, user.Gender.ToString (), ClaimValueTypes.Integer),
|
|
|
|
//
|
|
// User Profile Picture ...
|
|
new Claim (JwtClaimTypes.Picture, !user.Avatar.IsNullOrEmpty () ?
|
|
user.Avatar.ToString () :
|
|
""),
|
|
|
|
//
|
|
// The Unique Identifier for Each Token ...
|
|
new Claim (JwtRegisteredClaimNames.Jti, Guid.NewGuid ().ToString ()),
|
|
|
|
//
|
|
// Add isEnable and isBanned feature ...
|
|
new Claim (
|
|
XCustomClaims.IsEnabled,
|
|
user.IsEnable.ToString (),
|
|
ClaimValueTypes.Boolean
|
|
),
|
|
new Claim (
|
|
XCustomClaims.IsBanned,
|
|
user.IsBanned.ToString (),
|
|
ClaimValueTypes.Boolean
|
|
),
|
|
};
|
|
|
|
//
|
|
#region Set Claims based on Profile Policies ...
|
|
//
|
|
if (Configuration.Policy.Profile.ContainsDateOfBirth)
|
|
{
|
|
claims.Add(new Claim(JwtRegisteredClaimNames.Birthdate, user.DateOfBirth.ToString()));
|
|
}
|
|
|
|
//
|
|
if (Configuration.Policy.Profile.ContainsEmail)
|
|
{
|
|
claims.Add(new Claim(JwtClaimTypes.Email, user.Email));
|
|
claims.Add(new Claim(
|
|
JwtClaimTypes.EmailVerified,
|
|
user.EmailConfirmed.ToString(),
|
|
ClaimValueTypes.Boolean));
|
|
}
|
|
|
|
//
|
|
if (Configuration.Policy.Profile.ContainsPhoneNumber)
|
|
{
|
|
claims.Add(new Claim(JwtClaimTypes.PhoneNumber, user.PhoneNumber));
|
|
claims.Add(new Claim(
|
|
JwtClaimTypes.PhoneNumberVerified,
|
|
user.PhoneNumberConfirmed.ToString(),
|
|
ClaimValueTypes.Boolean));
|
|
}
|
|
|
|
//
|
|
if (Configuration.Policy.Profile.ContainsRoles)
|
|
{
|
|
var roleNames = await GetRoleNamesAsync(
|
|
user.UserName,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned);
|
|
roleNames.ToList()
|
|
.ForEach(rn =>
|
|
{
|
|
claims.Add(new Claim(JwtClaimTypes.Role, rn));
|
|
});
|
|
}
|
|
|
|
//
|
|
if (Configuration.Policy.Profile.ContainsLastLogin)
|
|
{
|
|
claims.Add(new Claim(
|
|
JwtClaimTypes.AuthenticationTime,
|
|
user.LastLogin.ToString(),
|
|
ClaimValueTypes.DateTime));
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Return Result ...
|
|
return claims.ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check User and Password relation
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="language">specify destination language</param>
|
|
/// <param name="lockoutOnFailure">specify account lockout on failure log in</param>
|
|
/// <param name="isForced">specify log in force without checking <see>XDevice</see> and lang relation</param>
|
|
/// <returns>an instance of <see>SignInResult</see></returns>
|
|
public async Task<SignInResult> CheckPasswordSignInAsync(
|
|
XUser user,
|
|
string password,
|
|
XDevice device,
|
|
string language,
|
|
bool lockoutOnFailure,
|
|
bool isForced = true
|
|
)
|
|
{
|
|
//
|
|
var result = await SignInManager.CheckPasswordSignInAsync(
|
|
user, password, lockoutOnFailure
|
|
);
|
|
|
|
//
|
|
if (result.Succeeded && isForced)
|
|
{
|
|
//
|
|
var isExistsDevice = user.Devices.Any(d => d.IsSameAs(device));
|
|
if (!isExistsDevice && !user.Email.IsNullOrEmpty() && user.EmailConfirmed)
|
|
{
|
|
//
|
|
user.Devices.Add(device);
|
|
|
|
//
|
|
var updateUserResult = await UpdateUserAsync(user);
|
|
if (updateUserResult.Succeeded)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
var xMessage = GetUserNewDeviceLoggedInMessage(
|
|
language,
|
|
user.Email,
|
|
device
|
|
);
|
|
|
|
//
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+Validators.cs
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region User Validators ...
|
|
/// <summary>
|
|
/// Validate User Name for Registration based on Policies
|
|
/// </summary>
|
|
/// <param name="userName">provided user name</param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool ValidateUserName(
|
|
string userName
|
|
)
|
|
{
|
|
//
|
|
// Check min/max Length ...
|
|
if (userName.IsNullOrEmpty() ||
|
|
userName.Length < Configuration.Policy.User.MinLength ||
|
|
userName.Length > Configuration.Policy.User.MaxLength)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Check Allowed UserName Characters ...
|
|
if (!UserManager.Options.User.AllowedUserNameCharacters.IsNullOrEmpty() &&
|
|
userName.Any(c => !UserManager.Options.User.AllowedUserNameCharacters.Contains(c)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Check invalid UserNames ...
|
|
if (Configuration.Policy.User.InvalidUserNames
|
|
.HasChild() && Configuration.Policy.User.InvalidUserNames
|
|
.Any(u => userName
|
|
.ToNormalString()
|
|
.Contains(u.ToNormalString())))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a User Exists
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateUserExistsAsync(
|
|
string userSelectByParam,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
var isExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a User Not Exists
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateUserNotExists(
|
|
string userSelectByParam,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.UserRegisteredBefore.ToException();
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
var isExists = await IsUserExistsAsync(userSelectByParam);
|
|
if (isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate User Exists and Some Usefull Checks
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is false</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <param name="ignoreDisabledUser">specify do not thrown <see>Exception</see> if user is Disabled, default is false</param>
|
|
/// <param name="forceAdmin">specify requested person is Admin role, default is false</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XUser</see></returns>
|
|
public async Task<XUser> ValidateUserExistsAndRetrieve(
|
|
string userSelectByParam,
|
|
bool containDetails = false,
|
|
bool checkCanLoginPolicies = false,
|
|
bool checkIsBanned = true,
|
|
bool ignoreDisabledUser = false,
|
|
bool forceAdmin = false,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(
|
|
Configuration,
|
|
Configuration.Policy,
|
|
Configuration.Policy.SignIn);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidData.ToException();
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
await ValidateUserExistsAsync(userSelectByParam);
|
|
|
|
//
|
|
// Retrieve User ...
|
|
var result = await GetUserAsync(userSelectByParam, containDetails);
|
|
if (result == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
// Check Force Admin ...
|
|
if (forceAdmin)
|
|
{
|
|
//
|
|
var isAdmin = await IsAdmin(result);
|
|
if (!isAdmin)
|
|
{
|
|
XException.NotAuthorized.Throw();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check User not Bann ...
|
|
if (checkIsBanned &&
|
|
result.IsBanned)
|
|
{
|
|
XException.UserBanned.Throw();
|
|
}
|
|
|
|
//
|
|
var requireConfirmedEmail = Configuration.Policy.SignIn.RequireConfirmedEmail;
|
|
var requireConfirmedPhoneNumber = Configuration.Policy.SignIn.RequireConfirmedPhoneNumber;
|
|
var requireEnabled = Configuration.Policy.SignIn.RequiredEnabled;
|
|
|
|
//
|
|
var isEnabled = result.IsEnable;
|
|
var isMobileConfirmed = result.PhoneNumberConfirmed;
|
|
var isEmailConfirmed = result.EmailConfirmed;
|
|
|
|
//
|
|
if (checkCanLoginPolicies)
|
|
{
|
|
//
|
|
// Check IsEnabled ...
|
|
if (!ignoreDisabledUser &&
|
|
requireEnabled &&
|
|
!isEnabled)
|
|
{
|
|
XException.UserDisabled.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Email Confirmed ...
|
|
if (requireConfirmedEmail &&
|
|
!isEmailConfirmed)
|
|
{
|
|
XException.EmailNotConfirmed.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Mobile Confirmed ...
|
|
if (requireConfirmedPhoneNumber &&
|
|
!isMobileConfirmed)
|
|
{
|
|
XException.MobileNotConfirmed.Throw();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Device for User Actions
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns></returns>
|
|
private async Task ValidateDeviceForActions(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotNull(device);
|
|
|
|
//
|
|
// Check is Device Banned or not ...
|
|
var isDeviceBanned = await IsDeviceBanned(device);
|
|
if (isDeviceBanned)
|
|
{
|
|
//
|
|
// Retrieve Banned Device ...
|
|
var xBannedDevice = await GetBannedDevice(device);
|
|
if (xBannedDevice == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Banned Device Time out Passed or not ...
|
|
var isDelayTimePassed = IsDelayTimePassed(xBannedDevice);
|
|
if (!isDelayTimePassed)
|
|
{
|
|
//
|
|
var passedTime = GetPassedTime(xBannedDevice);
|
|
|
|
//
|
|
XException.DeviceBanned
|
|
.AddContentToException(passedTime.ToString());
|
|
}
|
|
|
|
//
|
|
// if Delay Passed of Banned Device
|
|
// the device must Removed ...
|
|
await BannedDeviceRemove(xBannedDevice);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a DateOfBirth for Registration
|
|
/// </summary>
|
|
/// <param name="dateOfBirth">users dob date, an instance of <see>DateTime</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private void ValidateDateOfBirth(
|
|
DateTime dateOfBirth,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(dateOfBirth);
|
|
|
|
//
|
|
if (exception.IsNull())
|
|
{
|
|
exception = XException.InvalidDate.ToException();
|
|
}
|
|
|
|
//
|
|
var currentDate = DateTime.UtcNow;
|
|
if (dateOfBirth >= currentDate)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
var zeroDate = (new DateTime(1, 1, 1)).ToUniversalTime();
|
|
var minAge = Configuration.Policy.User.MinAgeForRegistration;
|
|
var maxAge = Configuration.Policy.User.MaxAgeForRegistration;
|
|
|
|
//
|
|
var timeSpan = currentDate - dateOfBirth;
|
|
var age = (zeroDate + timeSpan).Year - 1;
|
|
|
|
//
|
|
if (age > maxAge || age < minAge)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Given User Can Registere
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateCanRegister(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var canRegister = await CanRegister(userSelectByParam);
|
|
if (!canRegister)
|
|
{
|
|
XException.Unavailable.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Password by Gicen Policies
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidatePasswordPolicies(
|
|
XUser user,
|
|
string password,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(user);
|
|
ValidationProvider.NotEmpty(password);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidPassword.ToException();
|
|
}
|
|
|
|
//
|
|
// Check new Password Validation ...
|
|
var passwordValidator = new PasswordValidator<XUser>();
|
|
var checkPasswordResult = await passwordValidator.ValidateAsync(UserManager, user, password);
|
|
if (!checkPasswordResult.Succeeded)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a User for Dangerous Actions
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="requester">specified which user request Action by an instance of <see>XUser</see></param>
|
|
/// <returns></returns>
|
|
private async Task ValidateUserForDangerousAction(
|
|
XUser user,
|
|
XUser requester
|
|
)
|
|
{
|
|
//
|
|
// Validate ARgs ...
|
|
ValidationProvider.NotNull(user, requester);
|
|
|
|
//
|
|
var requesterRoleNames = await GetRoleNamesAsync(requester.Id);
|
|
|
|
//
|
|
var isSame = user.Id == requester.Id;
|
|
var isRequesterAdmin = requesterRoleNames.Any(r => r.ToNormalString() == "admin");
|
|
if (!isSame && !isRequesterAdmin)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Device Validators ...
|
|
/// <summary>
|
|
/// Validate a Device for Specified User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateUserAndDeviceRelation(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidDevice.ToException();
|
|
}
|
|
|
|
//
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true);
|
|
|
|
//
|
|
var result = await IsDeviceRelateDToUser(
|
|
userSelectByParam,
|
|
device
|
|
);
|
|
if (!result)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Token Validators ...
|
|
/// <summary>
|
|
/// Validate a Token
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
private void ValidateToken(
|
|
string token,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
var result = IdentityHelper.ValidateToken(token);
|
|
if (!result)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token is Specified to a Device and User
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="type">specifies Action type by a member of <see>XAction</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> ValidateAndRetieveTokenByDeviceAndType(
|
|
XDevice device,
|
|
XAction type,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByDeviceAndType(device, type);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
var item = await GetTokenByDeviceAndType(device, type);
|
|
if (item == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token By User and Specified Type
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="type">specifies Action type by a member of <see>XAction</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XToken</see></returns>
|
|
private async Task<XToken> ValidateAndRetieveTokenByUserAndType(
|
|
string userSelectByParam,
|
|
XAction type,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidData.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByUserAndType(userSelectByParam, type);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
var item = await GetTokenByUserAndType(userSelectByParam, type);
|
|
if (item == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Token Validation
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsValidToken(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
var result = IdentityHelper.ValidateToken(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Action Request Based on Action Token
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XActionRequestToken</see></returns>
|
|
private XActionRequestToken ValidateAndParseActionToken(
|
|
string token,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
ValidateToken(token);
|
|
|
|
//
|
|
var result = IdentityHelper.ParseActionRequestToken(token);
|
|
if (result == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
ValidateActionRequest(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse Action Request from Token
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <returns>an instance of <see>XActionRequestToken</see></returns>
|
|
private XActionRequestToken ParseActionRequest(
|
|
string token
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
var result = IdentityHelper
|
|
.ParseActionRequestToken(token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse Action Hash by Corresponding Token
|
|
/// </summary>
|
|
/// <param name="hash">token hash string</param>
|
|
/// <returns>an instance of <see>XActionRequestToken</see></returns>
|
|
private async Task<XActionRequestToken> ParseActionHash(
|
|
string hash
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
var isHashExists = await IsTokenExistsByHash(hash);
|
|
if (!isHashExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var xToken = await GetTokenByHash(hash);
|
|
if (xToken == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var isValidToken = IsValidToken(xToken.Token);
|
|
if (!isValidToken)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = ParseActionRequest(xToken.Token);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate and Parse Action Hash
|
|
/// </summary>
|
|
/// <param name="hash">token hash string</param>
|
|
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
|
|
/// <param name="forceActionValidation">specifies check action Validations, default is true</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XActionRequestToken</see></returns>
|
|
private async Task<XActionRequestToken> ValidateAndParseActionHash(
|
|
string hash,
|
|
bool forceTokenValidation = true,
|
|
bool forceActionValidation = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
var token = await ValidateAndRetrieveRelatedToken(hash, forceTokenValidation);
|
|
|
|
//
|
|
var result = await ParseActionHash(hash);
|
|
if (result == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
if (forceActionValidation)
|
|
{
|
|
ValidateActionRequest(result);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Action Request
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
private void ValidateActionRequest(
|
|
XActionRequestToken request,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotNull(request);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidData.ToException();
|
|
}
|
|
|
|
//
|
|
var isValid = IsValidActionRequest(request);
|
|
if (!isValid)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Action Request Validation
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsValidActionRequest(
|
|
XActionRequestToken request
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (request == null ||
|
|
Configuration.IdentitySecretKey.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = request.Validate(Configuration.IdentitySecretKey);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Token and Act Based on it
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <param name="issueExcepion">specify <see>Excetion</see> to thrown on Issue failure</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateAndHandleToken(
|
|
string token,
|
|
bool issueExcepion = false,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
var isValidToken = IsValidToken(token);
|
|
|
|
//
|
|
if (!isValidToken)
|
|
{
|
|
//
|
|
await RemoveTokenByToken(token);
|
|
|
|
//
|
|
if (issueExcepion)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Hash Exists or not
|
|
/// </summary>
|
|
/// <param name="hash">token hash string</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateHashExists(
|
|
string hash,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByHash(hash);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token Exists
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateTokenExists(
|
|
string token,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsTokenExistsByToken(token);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Hash and Retrieve it's Corresponding Token
|
|
/// </summary>
|
|
/// <param name="hash">token hash string</param>
|
|
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
|
|
/// <param name="issueExcepion">specify <see>Excetion</see> to thrown on Issue failure</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>token string</returns>
|
|
private async Task<string> ValidateAndRetrieveRelatedToken(
|
|
string hash,
|
|
bool forceTokenValidation = true,
|
|
bool issueExcepion = false,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(hash);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
await ValidateHashExists(hash);
|
|
|
|
//
|
|
var token = await GetRelatedTokenByHash(hash);
|
|
if (token.IsNullOrEmpty())
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
if (forceTokenValidation)
|
|
{
|
|
await ValidateAndHandleToken(token, issueExcepion);
|
|
}
|
|
|
|
//
|
|
return token;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Token and Retrieve it's Corresponding Hash
|
|
/// </summary>
|
|
/// <param name="token">token string</param>
|
|
/// <param name="forceTokenValidation">specifies chack token Validation Parameter, default is true</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>hash string</returns>
|
|
private async Task<string> ValidateAndRetrieveRelatedHash(
|
|
string token,
|
|
bool forceTokenValidation = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(token);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidToken.ToException();
|
|
}
|
|
|
|
//
|
|
if (forceTokenValidation)
|
|
{
|
|
await ValidateAndHandleToken(token);
|
|
}
|
|
|
|
//
|
|
await ValidateTokenExists(token);
|
|
|
|
//
|
|
var hash = await GetRelatedHashByToken(token);
|
|
if (hash.IsNullOrEmpty())
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
return hash;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Invitation Hash
|
|
/// </summary>
|
|
/// <param name="invitationHash">registration invitation hash string</param>
|
|
/// <param name="forceUserExists">thrown <see>Exception</see> if user Exists, default is true</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateInvitationHash(
|
|
string invitationHash,
|
|
bool forceUserExists = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(Configuration);
|
|
|
|
//
|
|
if (Configuration.RegistrationJustWithInvite &&
|
|
invitationHash.IsNullOrEmpty())
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate Invitation Token if it isn't null ...
|
|
if (!invitationHash.IsNullOrEmpty())
|
|
{
|
|
//
|
|
await ValidateHashExists(invitationHash);
|
|
|
|
//
|
|
// Token Validation also done in this task ...
|
|
var relatedToken = await ValidateAndRetrieveRelatedToken(invitationHash);
|
|
|
|
//
|
|
var inviteAction = ValidateAndParseActionToken(relatedToken);
|
|
ValidationProvider.NotNull(inviteAction);
|
|
|
|
//
|
|
var inviteUerSelectByParam = GetUserSelectByParam(inviteAction);
|
|
var inviteUserSelectBy = GetUserSelectByType(inviteUerSelectByParam);
|
|
if (inviteUserSelectBy != XUserSelectBy.Email)
|
|
{
|
|
XException.InvalidToken.Throw();
|
|
}
|
|
|
|
//
|
|
if (forceUserExists)
|
|
{
|
|
//
|
|
await ValidateUserNotExists(
|
|
inviteUerSelectByParam,
|
|
XException.EmailInUsed.ToException());
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Profile Validators ...
|
|
/// <summary>
|
|
/// Validate a Request is Corresponding to Specific Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="requestDevice">specify requested device by an instance of <see>XDevice</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
private void ValidateRequestAndGiveDevices(
|
|
XDevice device,
|
|
XDevice requestDevice,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(device, requestDevice);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidDevice.ToException();
|
|
}
|
|
|
|
//
|
|
var isDevicesSame = device.IsSameAs(requestDevice);
|
|
|
|
//
|
|
if (!isDevicesSame)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Validation of a User SelectBy Param and Password
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">specifies user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateUserAndPassword(
|
|
string userSelectByParam,
|
|
string password,
|
|
bool checkCanLoginPolicies = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
password
|
|
);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.LoginFailed.ToException();
|
|
}
|
|
|
|
//
|
|
// Retrieve User and Validate User Exists ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
ignoreDisabledUser: false,
|
|
checkIsBanned: true,
|
|
exception: exception);
|
|
|
|
//
|
|
// Check Given Password Follows Policies ...
|
|
await ValidatePasswordPolicies(user, password, exception);
|
|
|
|
//
|
|
// Check Password for User ...
|
|
var checkPasswordResult = await UserManager.CheckPasswordAsync(user, password);
|
|
if (!checkPasswordResult)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship Validators ...
|
|
/// <summary>
|
|
/// Validate Friendship Requested Before or not
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateRequestBefore(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var isRequested = IsFollowRequested(source, dest);
|
|
if (!isRequested)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Friendship Not Requested Before
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateNotRequestBefore(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var isRequested = IsFollowRequested(source, dest);
|
|
if (isRequested)
|
|
{
|
|
XException.Duplicate.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate User Can Send Following Request to Dest User
|
|
/// </summary>
|
|
/// <param name="accepterUser">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
/// <param name="requesterUser">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
private void ValidateFollowingRequest(
|
|
XUser accepterUser,
|
|
XUser requesterUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(accepterUser, requesterUser);
|
|
|
|
//
|
|
var isRequest = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Pending);
|
|
if (!isRequest)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a User can Accept a Following Request or Not
|
|
/// </summary>
|
|
/// <param name="accepterUser">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
/// <param name="requesterUser">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
private void ValidateFollowingRequestForAccept(
|
|
XUser accepterUser,
|
|
XUser requesterUser
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(accepterUser, requesterUser);
|
|
|
|
//
|
|
var isRequestPending = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Pending);
|
|
var isRequestRejected = IsFollowRequested(requesterUser, accepterUser, XFriendshipState.Rejected);
|
|
if (!isRequestPending &&
|
|
!isRequestRejected)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Request is not Passed for Same Users
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateNotSameUsers(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate ARgs ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var isSame = source.Id == dest.Id;
|
|
if (isSame)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a user is in Followers of another
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateIsFollowers(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
ValidateNotSameUsers(source, dest);
|
|
ValidateRequestBefore(dest, source);
|
|
|
|
//
|
|
var isFollower = IsFollowRequested(dest, source, XFriendshipState.Accepted) ||
|
|
IsFollowRequested(dest, source, XFriendshipState.Blocked);
|
|
if (!isFollower)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a user is in Followings of another
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateIsFollowings(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
ValidateNotSameUsers(source, dest);
|
|
ValidateRequestBefore(source, dest);
|
|
|
|
//
|
|
var isFollowing = IsFollowRequested(source, dest, XFriendshipState.Accepted);
|
|
if (!isFollowing)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a User Blocked another
|
|
/// </summary>
|
|
/// <param name="source">specifies a user to check as source by an instance of <see>XUser</see></param>
|
|
/// <param name="dest">specifies a user to check as dest by an instance of <see>XUser</see></param>
|
|
private void ValidateIsBlock(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
ValidateNotSameUsers(source, dest);
|
|
ValidateRequestBefore(dest, source);
|
|
|
|
//
|
|
var isFollower = IsFollowRequested(dest, source, XFriendshipState.Blocked);
|
|
if (!isFollower)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XActionRequest Validators ...
|
|
/// <summary>
|
|
/// Validate a Device for Request
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="requestDevice">specify requested device by an instance of <see>XDevice</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
private void ValidateRequestAndGivenDevices(
|
|
XDevice device,
|
|
XDevice requestDevice,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(device, requestDevice);
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidDevice.ToException();
|
|
}
|
|
|
|
//
|
|
var isDevicesSame = device.IsSameAs(requestDevice);
|
|
|
|
//
|
|
if (!isDevicesSame)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XVerification Request ...
|
|
/// <summary>
|
|
/// Validate Verification Request Exists by Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateVerificationRequestExists(
|
|
XDevice device,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidDevice.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsDeviceRequestedForVerificationCodeBefor(device);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate Verification Request Exists by VerificationCode
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns></returns>
|
|
private async Task ValidateVerificationRequestExists(
|
|
string verificationCode,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(verificationCode);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidVerificationCode.ToException();
|
|
}
|
|
|
|
//
|
|
var isExists = await IsVerificationCodeRequested(verificationCode);
|
|
if (!isExists)
|
|
{
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate and Retrive Verification Request for Given Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> ValidateAndRetrieveVerificationRequest(
|
|
XDevice device,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidDevice.ToException();
|
|
}
|
|
|
|
//
|
|
await ValidateVerificationRequestExists(device);
|
|
|
|
//
|
|
var result = await GetVerificationRequest(device);
|
|
if (result == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate and Retrieve Verification Request for Given VerificationCode
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <param name="exception">specify <see>Excetion</see> to thrown on failure</param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> ValidateAndRetrieveVerificationRequest(
|
|
string verificationCode,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(verificationCode);
|
|
|
|
//
|
|
if (exception == null)
|
|
{
|
|
exception = XException.InvalidVerificationCode.ToException();
|
|
}
|
|
|
|
//
|
|
await ValidateVerificationRequestExists(verificationCode);
|
|
|
|
//
|
|
var result = await GetVerificationRequest(verificationCode);
|
|
if (result == null)
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Prepare Verification Request
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see></param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> HandleVerificationRequestPreparation(
|
|
string verificationCode,
|
|
XActionRequestToken request
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(verificationCode);
|
|
|
|
//
|
|
// Check Action Request Validation ...
|
|
ValidateActionRequest(request);
|
|
|
|
//
|
|
var device = request.Context.Device;
|
|
|
|
//
|
|
// Check is Device Requested Before or not ...
|
|
XVerificationRequest xVerificationRequest = null;
|
|
var isDeviceRequested = await IsDeviceRequestedForVerificationCodeBefor(device);
|
|
if (!isDeviceRequested)
|
|
{
|
|
//
|
|
xVerificationRequest = new XVerificationRequest
|
|
{
|
|
VerificationCode = verificationCode,
|
|
NumberOfTries = 1,
|
|
LastTryOn = DateTime.UtcNow,
|
|
Device = device,
|
|
Request = request
|
|
};
|
|
|
|
//
|
|
await AddVerificationRequest(xVerificationRequest);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Get Verification Request ...
|
|
xVerificationRequest = await ValidateAndRetrieveVerificationRequest(device);
|
|
}
|
|
|
|
//
|
|
return xVerificationRequest;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager\XIdentityManager+VerificationCode.cs
|
|
|
|
using System.Threading.Tasks;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Verification Code Actions ...
|
|
/// <summary>
|
|
/// Check a Device Requeste for Verification Code before or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsDeviceRequestedForVerificationCodeBefor(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var enumerator = DbContext.VerificationRequests
|
|
.AsAsyncEnumerable();
|
|
await
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
if (entity.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Verification Code Requested before or not
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsVerificationCodeRequested(
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (verificationCode.IsNullOrEmpty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = false;
|
|
var enumerator = DbContext.VerificationRequests
|
|
.AsAsyncEnumerable();
|
|
await
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
if (entity.VerificationCode == verificationCode)
|
|
{
|
|
//
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Verification Request
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> GetVerificationRequest(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
XVerificationRequest result = null;
|
|
var enumerator = DbContext.VerificationRequests
|
|
.AsAsyncEnumerable();
|
|
await
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
if (entity.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
result = entity;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Verification Request
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> GetVerificationRequest(
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
XVerificationRequest result = null;
|
|
var enumerator = DbContext.VerificationRequests
|
|
.AsAsyncEnumerable();
|
|
await
|
|
foreach (var entity in enumerator)
|
|
{
|
|
//
|
|
if (entity.VerificationCode == verificationCode)
|
|
{
|
|
//
|
|
result = entity;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Exists Verification Code Request
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="saveChanges">save changes on DbContext, default is true</param>
|
|
/// <returns></returns>
|
|
private async Task RemoveVerificationCodeRequestByDevice(
|
|
XDevice device,
|
|
bool saveChanges = true
|
|
)
|
|
{
|
|
//
|
|
if (!await IsDeviceRequestedForVerificationCodeBefor(device))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var xvr = await GetVerificationRequest(device);
|
|
DbContext.VerificationRequests.Remove(xvr);
|
|
|
|
//
|
|
if (saveChanges)
|
|
{
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Exists Verification Code Request
|
|
/// </summary>
|
|
/// <param name="verificationCode">Confirm Verification Code</param>
|
|
/// <param name="saveChanges">save changes on DbContext, default is true</param>
|
|
/// <returns></returns>
|
|
private async Task RemoveVerificationRequest(
|
|
string verificationCode,
|
|
bool saveChanges = true
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(verificationCode);
|
|
|
|
//
|
|
var request = await GetVerificationRequest(verificationCode);
|
|
DbContext.VerificationRequests.Remove(request);
|
|
|
|
//
|
|
if (saveChanges)
|
|
{
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Verification Code Request
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XVerificationRequest</see></param>
|
|
/// <param name="saveChanges">save changes on DbContext, default is true</param>
|
|
/// <returns>an instance of <see>XVerificationRequest</see></returns>
|
|
private async Task<XVerificationRequest> AddVerificationRequest(
|
|
XVerificationRequest request,
|
|
bool saveChanges = true
|
|
)
|
|
{
|
|
//
|
|
if (await IsDeviceRequestedForVerificationCodeBefor(request.Device))
|
|
{
|
|
await RemoveVerificationCodeRequestByDevice(request.Device);
|
|
}
|
|
|
|
//
|
|
var entry = await DbContext.VerificationRequests.AddAsync(request);
|
|
|
|
//
|
|
if (saveChanges)
|
|
{
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
//
|
|
return entry.Entity;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityManager.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Serialization;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Configurations;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Models;
|
|
using xMessageService.Interfaces;
|
|
using xStorageService.Interfaces;
|
|
using xIds.Configurations;
|
|
using xIds.DbContext;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager : IXIdentityManager
|
|
{
|
|
//
|
|
private JsonSerializerSettings jsonSerializerSettings;
|
|
|
|
//
|
|
public XIdentityDbContext DbContext { get; }
|
|
public UserManager<XUser> UserManager { get; }
|
|
public IXIdentityHelper IdentityHelper { get; }
|
|
public ILogger<IXIdentityManager> Logger { get; }
|
|
public IXMessageProvider MessageProvider { get; }
|
|
public IXStorageProvider StorageProvider { get; }
|
|
public SignInManager<XUser> SignInManager { get; }
|
|
public IXSecurityProvider SecurityProvider { get; }
|
|
public XIdentityConfiguration Configuration { get; }
|
|
public RoleManager<IdentityRole> RoleManager { get; }
|
|
public XValidationProvider ValidationProvider { get; }
|
|
public XDataServiceConfiguration DataConfiguration { get; }
|
|
public IXIdentityMessageProvider IdentityMessageProvider { get; }
|
|
public XIdentityResourceConfiguration IdentityResourceConfiguration { get; }
|
|
|
|
public XIdentityManager(
|
|
XIdentityDbContext dbContext,
|
|
UserManager<XUser> userManager,
|
|
IXIdentityHelper identityHelper,
|
|
ILogger<IXIdentityManager> logger,
|
|
IXMessageProvider messageProvider,
|
|
IXStorageProvider storageProvider,
|
|
SignInManager<XUser> signInManager,
|
|
IXSecurityProvider securityProvider,
|
|
XIdentityConfiguration configuration,
|
|
RoleManager<IdentityRole> roleManager,
|
|
XValidationProvider validationProvider,
|
|
XDataServiceConfiguration dataConfiguration,
|
|
IXIdentityMessageProvider identityMessageProvider,
|
|
XIdentityResourceConfiguration identityResourceConfiguration
|
|
)
|
|
{
|
|
//
|
|
Logger = logger;
|
|
DbContext = dbContext;
|
|
RoleManager = roleManager;
|
|
UserManager = userManager;
|
|
SignInManager = signInManager;
|
|
SecurityProvider = securityProvider;
|
|
Configuration = configuration;
|
|
IdentityHelper = identityHelper;
|
|
MessageProvider = messageProvider;
|
|
StorageProvider = storageProvider;
|
|
DataConfiguration = dataConfiguration;
|
|
ValidationProvider = validationProvider;
|
|
IdentityMessageProvider = identityMessageProvider;
|
|
IdentityResourceConfiguration = identityResourceConfiguration;
|
|
|
|
//
|
|
this.jsonSerializerSettings = new JsonSerializerSettings
|
|
{
|
|
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
|
};
|
|
}
|
|
|
|
//
|
|
#region Class Getter (s) Methods ...
|
|
/// <summary>
|
|
/// Retrieve User DB Set
|
|
/// </summary>
|
|
/// <param name="containDetails">specifies returned object contains all Navigation Properties or not, default is false</param>
|
|
/// <returns></returns>
|
|
public IQueryable<XUser> GetUsersDbSet(
|
|
bool containDetails = false
|
|
)
|
|
{
|
|
//
|
|
var dbSet = containDetails ? GetUsersFullDbSet() :
|
|
UserManager.Users;
|
|
return dbSet;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve User Db Set Full Navigation Properties
|
|
/// </summary>
|
|
/// <param name="enableTracking"></param>
|
|
/// <returns></returns>
|
|
public IQueryable<XUser> GetUsersFullDbSet(bool enableTracking = false)
|
|
{
|
|
//
|
|
var dbSet = UserManager.Users
|
|
.Include(u => u.Roles)
|
|
.Include(u => u.Devices)
|
|
.Include(u => u.Followers)
|
|
.Include(u => u.Followings)
|
|
.Include(u => u.Avatars);
|
|
|
|
//
|
|
return dbSet.AsSplitQuery();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Get User SelectBy Param
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="forceNotNull"></param>
|
|
/// <param name="excludes"></param>
|
|
/// <returns></returns>
|
|
public string GetUserSelectByParam(
|
|
XActionRequest model,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var id = model.UserId;
|
|
var userName = model.UserName;
|
|
var email = model.Email;
|
|
var phoneNumber = model.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
//
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityMessageProvider.cs
|
|
|
|
using System.Linq;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Configurations;
|
|
using xIds.Constants;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public class XIdentityMessageProvider : IXIdentityMessageProvider
|
|
{
|
|
//
|
|
public string InviteMsg { get; set; }
|
|
public string RegistrationApproveMsg { get; set; }
|
|
public string RegisteredMsg { get; set; }
|
|
public string VerificationCodeMsg { get; set; }
|
|
public string ChangePasswordMsg { get; set; }
|
|
public string PasswordChangedMsg { get; set; }
|
|
public string NewDeviceLoggedInMsg { get; set; }
|
|
|
|
private readonly ILogger<IXIdentityMessageProvider> logger;
|
|
private readonly XIdentityConfiguration identityConfiguration;
|
|
|
|
public XIdentityMessageProvider(
|
|
ILogger<IXIdentityMessageProvider> logger,
|
|
XIdentityConfiguration identityConfiguration
|
|
)
|
|
{
|
|
this.logger = logger;
|
|
this.identityConfiguration = identityConfiguration;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determine All things is Ready or Not
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsReady()
|
|
{
|
|
return !InviteMsg.IsNullOrEmpty() &&
|
|
!RegistrationApproveMsg.IsNullOrEmpty() &&
|
|
!RegisteredMsg.IsNullOrEmpty() &&
|
|
!VerificationCodeMsg.IsNullOrEmpty() &&
|
|
!ChangePasswordMsg.IsNullOrEmpty() &&
|
|
!PasswordChangedMsg.IsNullOrEmpty() &&
|
|
!NewDeviceLoggedInMsg.IsNullOrEmpty();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Translated Value Based on Given Lang
|
|
/// </summary>
|
|
/// <param name="resourceTitle"></param>
|
|
/// <param name="lang"></param>
|
|
/// <returns></returns>
|
|
private string GetStringResource(string resourceTitle, string lang)
|
|
{
|
|
//
|
|
var item = identityConfiguration.IdentityMessages
|
|
.FirstOrDefault(sr =>
|
|
sr.Language.ToNormalString() == lang.ToNormalString() &&
|
|
sr.ResourceTitle.ToNormalString() == resourceTitle.ToNormalString());
|
|
//
|
|
if (item == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
return item.TranslatedValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Helper Class and Fill Messages
|
|
/// with Specific Language
|
|
/// </summary>
|
|
/// <param name="lang"></param>
|
|
public void PrepareMessages(string lang)
|
|
{
|
|
//
|
|
InviteMsg = GetStringResource(IdentityMessagesKeys.InviteMsg, lang);
|
|
RegisteredMsg = GetStringResource(IdentityMessagesKeys.RegisteredMsg, lang);
|
|
ChangePasswordMsg = GetStringResource(IdentityMessagesKeys.ChangePasswordMsg, lang);
|
|
PasswordChangedMsg = GetStringResource(IdentityMessagesKeys.PasswordChangedMsg, lang);
|
|
VerificationCodeMsg = GetStringResource(IdentityMessagesKeys.VerificationCodeMsg, lang);
|
|
NewDeviceLoggedInMsg = GetStringResource(IdentityMessagesKeys.NewDeviceLoggedInMsg, lang);
|
|
RegistrationApproveMsg = GetStringResource(IdentityMessagesKeys.RegistrationApproveMsg, lang);
|
|
|
|
//
|
|
if (!IsReady())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XIdentityProfileService.cs
|
|
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using IdentityServer4.Extensions;
|
|
using IdentityServer4.Models;
|
|
using IdentityServer4.Services;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using xCommons.Extensions;
|
|
using xIdentityModels;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public class XIdentityProfileService : IProfileService
|
|
{
|
|
private readonly IXIdentityManager identityManager;
|
|
private readonly IUserClaimsPrincipalFactory<XUser> userClaimsPrincipalFacotry;
|
|
|
|
public XIdentityProfileService(
|
|
IXIdentityManager identityManager,
|
|
IUserClaimsPrincipalFactory<XUser> userClaimsPrincipalFacotry
|
|
)
|
|
{
|
|
this.identityManager = identityManager;
|
|
this.userClaimsPrincipalFacotry = userClaimsPrincipalFacotry;
|
|
}
|
|
|
|
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
|
|
{
|
|
//
|
|
var sub = context.Subject.GetSubjectId();
|
|
var user = await identityManager.GetUserAsync(sub, true);
|
|
var principal = await userClaimsPrincipalFacotry.CreateAsync(user);
|
|
|
|
//
|
|
var claims = principal.Claims.ToList();
|
|
|
|
//
|
|
context.IssuedClaims = claims;
|
|
}
|
|
|
|
public async Task IsActiveAsync(IsActiveContext context)
|
|
{
|
|
//
|
|
var sub = context.Subject.GetSubjectId();
|
|
var user = await identityManager.GetUserAsync(sub);
|
|
|
|
//
|
|
context.IsActive = !user.IsNull() && user.IsEnable && !user.IsBanned;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Providers\XSecurityProvider.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using xCommons.Extensions;
|
|
using xCommons.Providers;
|
|
using xIds.Configurations;
|
|
using xIds.Interfaces;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public class XSecurityProvider : IXSecurityProvider
|
|
{
|
|
//
|
|
#region Props ...
|
|
private readonly string secretKey;
|
|
private readonly byte[] iv;
|
|
private readonly byte[] key;
|
|
private readonly XValidationProvider validationProvider;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XSecurityProvider(
|
|
XIdentityResourceConfiguration identityConfiguration,
|
|
XValidationProvider validationProvider
|
|
)
|
|
{
|
|
//
|
|
this.secretKey = identityConfiguration.XRevisionSecretKey.ToMd5String();
|
|
this.validationProvider = validationProvider;
|
|
|
|
//
|
|
var ivBytes = new byte[16];
|
|
var keyBytes = new byte[32];
|
|
var secretBytes = Encoding.UTF8.GetBytes(this.secretKey);
|
|
|
|
//
|
|
Array.Copy(
|
|
secretBytes,
|
|
ivBytes,
|
|
secretBytes.Length < ivBytes.Length ?
|
|
secretBytes.Length :
|
|
ivBytes.Length
|
|
);
|
|
this.iv = ivBytes;
|
|
|
|
//
|
|
Array.Copy(
|
|
secretBytes,
|
|
keyBytes,
|
|
secretBytes.Length < keyBytes.Length ?
|
|
secretBytes.Length :
|
|
keyBytes.Length
|
|
);
|
|
this.key = keyBytes;
|
|
|
|
// Encoding.UTF8.GetBytes (this.secretKey);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
public string Encrypt(string plainText)
|
|
{
|
|
//
|
|
validationProvider.NotEmpty(plainText);
|
|
|
|
//
|
|
var textBytes = Encoding.UTF8.GetBytes(plainText);
|
|
var result = EncryptFromBytes(textBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string Decrypt(string cipherText)
|
|
{
|
|
//
|
|
validationProvider.NotEmpty(cipherText);
|
|
|
|
//
|
|
var cipherBytes = Convert.FromBase64String(cipherText);
|
|
var result = DecryptFromBytes(cipherBytes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public string EncryptFromBytes(byte[] textBytes)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(textBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
byte[] encryptedBytes = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged())
|
|
{
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
//
|
|
using (var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV))
|
|
{
|
|
encryptedBytes = encryptor.TransformFinalBlock(textBytes, 0, textBytes.Length);
|
|
}
|
|
}
|
|
|
|
//
|
|
return Convert.ToBase64String(encryptedBytes);
|
|
}
|
|
|
|
public string DecryptFromBytes(byte[] cipherBytes)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
validationProvider.NotNull(cipherBytes);
|
|
|
|
// Declare the string used to hold
|
|
// the decrypted text.
|
|
string plaintext = null;
|
|
|
|
// Create an RijndaelManaged object
|
|
// with the specified key and IV.
|
|
using (var rijAlg = new RijndaelManaged())
|
|
{
|
|
//Settings
|
|
rijAlg.Mode = CipherMode.CBC;
|
|
rijAlg.Padding = PaddingMode.PKCS7;
|
|
// rijAlg.FeedbackSize = 128;
|
|
|
|
rijAlg.Key = key;
|
|
rijAlg.IV = iv;
|
|
|
|
// Create a decrytor to perform the stream transform.
|
|
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
|
|
|
|
// Create the streams used for decryption.
|
|
using (var msDecrypt = new MemoryStream(cipherBytes))
|
|
{
|
|
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
|
{
|
|
using (var srDecrypt = new StreamReader(csDecrypt))
|
|
{
|
|
// Read the decrypted bytes from the decrypting stream
|
|
// and place them in a string.
|
|
plaintext = srDecrypt.ReadToEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return plaintext;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Stores\XPersistedGrantStore.cs
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using IdentityServer4.EntityFramework.DbContexts;
|
|
using IdentityServer4.EntityFramework.Mappers;
|
|
using IdentityServer4.Models;
|
|
using IdentityServer4.Stores;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace xIds.Stores
|
|
{
|
|
public class XPersistedGrantStore : IPersistedGrantStore
|
|
{
|
|
private readonly PersistedGrantDbContext dbContext;
|
|
|
|
public XPersistedGrantStore(PersistedGrantDbContext dbContext)
|
|
{
|
|
this.dbContext = dbContext;
|
|
}
|
|
|
|
public async Task<IEnumerable<PersistedGrant>> GetAllAsync(string subjectId)
|
|
{
|
|
//
|
|
var result = (await dbContext.PersistedGrants
|
|
.Where(g => g.SubjectId == subjectId)
|
|
.AsNoTracking()
|
|
.Select(res => res.ToModel())
|
|
.ToListAsync()).AsEnumerable();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
public async Task<PersistedGrant> GetAsync(string key)
|
|
{
|
|
//
|
|
var result = await dbContext.PersistedGrants
|
|
.FirstOrDefaultAsync(g => g.Key == key);
|
|
|
|
//
|
|
return result.ToModel();
|
|
}
|
|
|
|
public async Task RemoveAllAsync(string subjectId, string clientId)
|
|
{
|
|
//
|
|
var items = await dbContext.PersistedGrants
|
|
.Where(g =>
|
|
g.SubjectId == subjectId &&
|
|
g.ClientId == clientId)
|
|
.ToListAsync();
|
|
|
|
//
|
|
dbContext.PersistedGrants.RemoveRange(items);
|
|
|
|
//
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task RemoveAllAsync(string subjectId, string clientId, string type)
|
|
{
|
|
//
|
|
var items = await dbContext.PersistedGrants
|
|
.Where(g =>
|
|
g.SubjectId == subjectId &&
|
|
g.ClientId == clientId &&
|
|
g.Type == type)
|
|
.ToListAsync();
|
|
|
|
//
|
|
dbContext.PersistedGrants.RemoveRange(items);
|
|
|
|
//
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task RemoveAsync(string key)
|
|
{
|
|
//
|
|
var items = await dbContext.PersistedGrants
|
|
.Where(g => g.Key == key)
|
|
.ToListAsync();
|
|
|
|
//
|
|
dbContext.PersistedGrants.RemoveRange(items);
|
|
|
|
//
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task<bool> IsExistsAsync(string key)
|
|
{
|
|
return await this.dbContext.PersistedGrants.AnyAsync(g => g.Key == key);
|
|
}
|
|
|
|
public async Task<bool> IsExistsAsync(PersistedGrant grant)
|
|
{
|
|
return await IsExistsAsync(grant.Key);
|
|
}
|
|
|
|
public async Task AddOrUpdateAsync(PersistedGrant grant)
|
|
{
|
|
//
|
|
var isExists = await IsExistsAsync(grant);
|
|
if (isExists)
|
|
{
|
|
await UpdateAsync(grant);
|
|
}
|
|
else
|
|
{
|
|
await AddAsync(grant);
|
|
}
|
|
}
|
|
|
|
public async Task AddAsync(PersistedGrant grant)
|
|
{
|
|
//
|
|
var item = grant.ToEntity();
|
|
await dbContext.PersistedGrants.AddAsync(item);
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task UpdateAsync(PersistedGrant grant)
|
|
{
|
|
//
|
|
var item = grant.ToEntity();
|
|
var entity = dbContext.Attach(item);
|
|
entity.State = EntityState.Modified;
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task StoreAsync(PersistedGrant grant)
|
|
{
|
|
await AddOrUpdateAsync(grant);
|
|
}
|
|
|
|
//
|
|
// TODO: Complete this ...
|
|
public Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
//
|
|
// TODO: Complete this ...
|
|
public Task RemoveAllAsync(PersistedGrantFilter filter)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Validators\XResourceOwnerPasswordValidator.cs
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using IdentityServer4.Events;
|
|
using IdentityServer4.Models;
|
|
using IdentityServer4.Services;
|
|
using IdentityServer4.Validation;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Navigations;
|
|
using xIds.Interfaces;
|
|
using static IdentityModel.OidcConstants;
|
|
|
|
namespace xIds.Validators
|
|
{
|
|
public class XResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
|
|
{
|
|
private readonly IXIdentityManager identityManager;
|
|
private readonly IEventService events;
|
|
private readonly ILogger<XResourceOwnerPasswordValidator> logger;
|
|
|
|
public XResourceOwnerPasswordValidator(
|
|
IXIdentityManager identityProvider,
|
|
IEventService events,
|
|
ILogger<XResourceOwnerPasswordValidator> logger
|
|
)
|
|
{
|
|
this.identityManager = identityProvider;
|
|
this.events = events;
|
|
this.logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates the resource owner password credential
|
|
/// by providing UserName/Email or PhoneNumber
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
/// <returns></returns>
|
|
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
|
|
{
|
|
//
|
|
var clientId = context.Request?.Client?.ClientId;
|
|
var xUser = await identityManager.GetUserAsync(context.UserName, true);
|
|
|
|
//
|
|
// Check Force Data ...
|
|
var isForced = true;
|
|
var isForcedStr = context.Request?.Raw["force"];
|
|
if (!isForcedStr.IsNullOrEmpty())
|
|
{
|
|
isForced = isForcedStr.FromJSON<bool>();
|
|
}
|
|
|
|
//
|
|
XDevice device = null;
|
|
var language = context.Request?.Raw["language"];
|
|
var deviceStr = context.Request?.Raw["device"];
|
|
if (deviceStr.IsNullOrEmpty() && isForced)
|
|
{
|
|
//
|
|
logger.LogError($"Device not Found ...");
|
|
|
|
//
|
|
await events
|
|
.RaiseAsync(
|
|
new UserLoginFailureEvent(
|
|
xUser.UserName,
|
|
XException.InvalidDevice.ToXError().Message,
|
|
false,
|
|
clientId
|
|
));
|
|
return;
|
|
}
|
|
device = isForced ? deviceStr.FromJSON<XDevice>() : null;
|
|
|
|
//
|
|
XException exception;
|
|
if (!xUser.IsNull())
|
|
{
|
|
//
|
|
var result = await identityManager
|
|
.CheckPasswordSignInAsync(
|
|
xUser,
|
|
context.Password,
|
|
device,
|
|
language,
|
|
true,
|
|
isForced
|
|
);
|
|
if (result.Succeeded)
|
|
{
|
|
//
|
|
logger.LogInformation("Credentials validated for username: {username}", xUser.UserName);
|
|
|
|
//
|
|
// Update User Last Login ...
|
|
xUser.LastLogin = DateTime.UtcNow;
|
|
await identityManager.UpdateUserAsync(xUser);
|
|
|
|
//
|
|
await events.RaiseAsync(
|
|
new UserLoginSuccessEvent(
|
|
xUser.UserName, xUser.Id, xUser.UserName, false, clientId
|
|
));
|
|
|
|
//
|
|
context.Result = new GrantValidationResult(xUser.Id, AuthenticationMethods.Password);
|
|
return;
|
|
}
|
|
else if (result.IsLockedOut)
|
|
{
|
|
//
|
|
logger.LogInformation("Authentication failed for username: {username}, reason: locked out", xUser.UserName);
|
|
|
|
//
|
|
exception = XException.AccountLockedOut;
|
|
await events
|
|
.RaiseAsync(
|
|
new UserLoginFailureEvent(
|
|
xUser.UserName,
|
|
exception.ToXError().Message,
|
|
false,
|
|
clientId
|
|
));
|
|
}
|
|
else if (result.IsNotAllowed)
|
|
{
|
|
//
|
|
logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", xUser.UserName);
|
|
|
|
//
|
|
exception = XException.NotAllowed;
|
|
await events
|
|
.RaiseAsync(
|
|
new UserLoginFailureEvent(
|
|
xUser.UserName,
|
|
exception.ToXError().Message,
|
|
false,
|
|
clientId
|
|
));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", xUser.UserName);
|
|
|
|
//
|
|
exception = XException.LoginFailed;
|
|
await events
|
|
.RaiseAsync(
|
|
new UserLoginFailureEvent(
|
|
xUser.UserName,
|
|
exception.ToXError().Message,
|
|
false,
|
|
clientId
|
|
));
|
|
|
|
//
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
logger.LogInformation("No user found matching username: {username}", xUser.UserName);
|
|
|
|
//
|
|
exception = XException.InvalidUserName;
|
|
await events
|
|
.RaiseAsync(
|
|
new UserLoginFailureEvent(
|
|
xUser.UserName,
|
|
exception.ToXError().Message,
|
|
false,
|
|
clientId
|
|
));
|
|
}
|
|
|
|
//
|
|
Exception ecs = exception.ToException();
|
|
if (exception == XException.AccountLockedOut && xUser.LockoutEnd.HasValue)
|
|
{
|
|
//
|
|
var passedTime = xUser.LockoutEnd.Value.UtcDateTime;
|
|
ecs = XException.AccountLockedOut
|
|
.AddContentToException(passedTime.ToString());
|
|
}
|
|
|
|
//
|
|
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, ecs.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Program.cs
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace xIds
|
|
{
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
CreateHostBuilder(args).Build().Run();
|
|
}
|
|
|
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
|
Host.CreateDefaultBuilder(args)
|
|
.ConfigureWebHostDefaults(webBuilder =>
|
|
{
|
|
webBuilder.UseStartup<Startup>();
|
|
});
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\xIds\Startup.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using xCommons.Configurations;
|
|
using xCommons.Extensions;
|
|
using xStorageService.DI;
|
|
using xIds.Constants;
|
|
using xIds.DI;
|
|
using xIds.Interfaces;
|
|
using xIds.Providers;
|
|
|
|
namespace xIds
|
|
{
|
|
public class Startup
|
|
{
|
|
public IConfiguration Configuration { get; }
|
|
|
|
public Startup(IConfiguration configuration)
|
|
{
|
|
Configuration = configuration;
|
|
}
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
//
|
|
// Register Validation Provider and all XCommons Module Services ...
|
|
services.AddXCommons();
|
|
|
|
//
|
|
// Register App Configuration ...
|
|
services.AddXAppConfiguration(Configuration);
|
|
var appConfiguration = services.GetRegisteredService<XAppConfiguration>();
|
|
|
|
//
|
|
// Register XDataService Configuration ...
|
|
services.AddXDataServiceConfiguration(Configuration, ConnectionStringNames.IDENTITY_CONNECTION_NAME);
|
|
|
|
//
|
|
// Register Allowed Origins ...
|
|
services.AddXCors(appConfiguration.AllowedOrigins);
|
|
|
|
//
|
|
// Register Swagger ...
|
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
|
services.AddXSwagger(Configuration, xmlFilePath: xmlPath);
|
|
|
|
//
|
|
// Register IdentityServer to DI ...
|
|
// services.AddInMemoryXIdentityServer (Configuration);
|
|
services.AddEfSupportXIdentityServer(Configuration);
|
|
|
|
//
|
|
services.AddControllers()
|
|
.AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
|
|
|
|
//
|
|
// Register Authentication ...
|
|
services.AddXIdentityServerAuthentication(Configuration);
|
|
|
|
//
|
|
// Register Authorization ...
|
|
services.AddXAuthorization();
|
|
|
|
//
|
|
// Register Security Provider ...
|
|
services.AddSingleton<IXSecurityProvider, XSecurityProvider>();
|
|
}
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
|
|
{
|
|
//
|
|
if (env.IsDevelopment())
|
|
{
|
|
//
|
|
app.UseDeveloperExceptionPage();
|
|
|
|
//
|
|
// app.UseXRequestLogger();
|
|
}
|
|
|
|
//
|
|
// Use Swagger Middleware ...
|
|
app.UseXSwagger();
|
|
|
|
//
|
|
app.UseHttpsRedirection();
|
|
app.UseXForwardOptions();
|
|
|
|
//
|
|
// Using Cors ...
|
|
app.UseXCors();
|
|
|
|
//
|
|
// Force App to Use IdentityServer ...
|
|
app.UseXIdentityServer(logger);
|
|
|
|
//
|
|
// Force app to Use Storage Service ...
|
|
app.UseXStorageService();
|
|
|
|
//
|
|
app.UseRouting();
|
|
|
|
//
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
//
|
|
app.UseEndpoints(endpoints =>
|
|
{
|
|
endpoints.MapDefaultControllerRoute();
|
|
});
|
|
}
|
|
}
|
|
}
|