This commit is contained in:
2026-05-27 16:11:39 +03:30
parent 30b3e80a8d
commit 0e8c3a9623
12 changed files with 1315 additions and 2 deletions
@@ -1,3 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using xDataService.Providers;
using xStringService.Models.Entities;
@@ -7,6 +8,8 @@ namespace xStringService.Configurations.Entities
public class XStringEntityConfiguration : XBaseEntityTypeConfiguration<XString, int>
{
public override void Configure(EntityTypeBuilder<XString> builder)
{ }
{
builder.ToTable("Strings");
}
}
}
@@ -0,0 +1,387 @@
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 xModels.Dtos;
using xStringService.Interfaces;
using xStringService.Models.Dtos;
namespace xStringService.Controllers
{
/// <summary>
/// an Implementation of Base Actions of a Controller which Provides
/// XString Resource Service Actions ...
/// </summary>
public abstract class XBaseStringResourceProviderControllerBase : XBaseIdentityApiV1Controller, IXBaseStringResourceProviderControllerBase
{
private readonly IXBaseStringResourceProvider resourceProvider;
protected XBaseStringResourceProviderControllerBase(
ILogger<XBaseStringResourceProviderControllerBase> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXBaseStringResourceProvider resourceProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{
this.resourceProvider = resourceProvider;
}
/// <summary>
/// Add Specified Locales ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="locales"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("Add")]
public virtual async Task<ActionResult<IEnumerable<XStringDto>>> Add(
[FromQuery] string suffix,
[FromBody] XBaseRangeRequest<XLocaleResourceDto> locales,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(suffix)
.AddNotNull(locales)
.AddNotZeroChilds(locales.Items)
.ValidateGroupAsync();
//
var connectionId = GetConnectionId();
//
var result = await resourceProvider.Add(
suffix: suffix,
locales: locales.Items,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Add or Update Specified Locales ...
/// </summary>
/// <param name="resource"></param>
/// <param name="locales"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddOrUpdate")]
public virtual async Task<ActionResult<IEnumerable<XStringDto>>> AddOrUpdate(
[FromQuery] string resource,
[FromBody] XBaseRangeRequest<XLocaleResourceDto> locales,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(resource)
.AddNotNull(locales)
.AddNotZeroChilds(locales.Items)
.ValidateGroupAsync();
//
var connectionId = GetConnectionId();
//
var result = await resourceProvider.AddOrUpdate(
resource: resource,
locales: locales.Items,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Add Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddResource")]
public virtual async Task<ActionResult<XResourceDto>> AddResource(
[FromQuery] string suffix,
[FromBody] XResourceDto item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(suffix)
.AddNotNull(item)
.AddNotZeroChilds(item.Locales)
.ValidateGroupAsync();
//
var connectionId = GetConnectionId();
//
var result = await resourceProvider.AddResource(
item: item,
suffix: suffix,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Get Specified Locale ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("GetLocale")]
public virtual async Task<ActionResult<XLocaleResourceDto>> GetLocale(
[FromQuery] string suffix,
[FromQuery] string language = null,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(suffix)
.ValidateGroupAsync();
//
var result = await resourceProvider.GetLocale(
suffix: suffix,
language: language,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Get Resources of Specified Resource Title ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("GetResource")]
public virtual async Task<ActionResult<XResourceDto>> GetResource(
[FromQuery] string suffix,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(suffix)
.ValidateGroupAsync();
//
var result = await resourceProvider.GetResource(
suffix: suffix,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Remove all Resources which belongs to Specified Suffix ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("Remove")]
public virtual async Task<ActionResult> Remove(
[FromQuery] string suffix,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(suffix)
.ValidateGroupAsync();
//
var connectionId = GetConnectionId();
//
await resourceProvider.Remove(
suffix: suffix,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Remove Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("RemoveResource")]
public virtual async Task<ActionResult> Remove(
[FromQuery] string resource,
[FromQuery] string language,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotEmpty(resource)
.AddNotEmpty(language)
.ValidateGroupAsync();
//
var connectionId = GetConnectionId();
//
await resourceProvider.Remove(
resource: resource,
language: language,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
}
}
@@ -0,0 +1,33 @@
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
)
{ }
}
}
@@ -0,0 +1,37 @@
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
)
{ }
}
}
@@ -0,0 +1,34 @@
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
)
{ }
}
}
@@ -0,0 +1,38 @@
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
)
{ }
}
}
+3
View File
@@ -168,6 +168,8 @@ namespace xStringService.DI
}
//
// Maske Instance of Repository Descriptor
// Based on Provided Type ...
switch(repositoryType)
{
//
@@ -193,6 +195,7 @@ namespace xStringService.DI
}
//
// Register XString Repository Descriptor ...
services.AddXRepository(
lifeTime: lifeTime,
descriptor: descriptor
@@ -0,0 +1,111 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using xModels.Base;
using xModels.Dtos;
using xStringService.Models.Dtos;
namespace xStringService.Interfaces
{
/// <summary>
/// an Interface which Described Base Actions of a Controller which Provides
/// XString Resource Service Actions ...
/// </summary>
public interface IXBaseStringResourceProviderControllerBase
{
/// <summary>
/// Add Specified Locales ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="locales"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("Add")]
Task<ActionResult<IEnumerable<XStringDto>>> Add(
[FromQuery] string suffix,
[FromBody] XBaseRangeRequest<XLocaleResourceDto> locales,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add or Update Specified Locales ...
/// </summary>
/// <param name="resource"></param>
/// <param name="locales"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddOrUpdate")]
Task<ActionResult<IEnumerable<XStringDto>>> AddOrUpdate(
[FromQuery] string resource,
[FromBody] XBaseRangeRequest<XLocaleResourceDto> locales,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddResource")]
Task<ActionResult<XResourceDto>> AddResource(
[FromQuery] string suffix,
[FromBody] XResourceDto item,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get Specified Locale ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("GetLocale")]
Task<ActionResult<XLocaleResourceDto>> GetLocale(
[FromQuery] string suffix,
[FromQuery] string language = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get Resources of Specified Resource Title ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("GetResource")]
Task<ActionResult<XResourceDto>> GetResource(
[FromQuery] string suffix,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove all Resources which belongs to Specified Suffix ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("Remove")]
Task<ActionResult> Remove(
[FromQuery] string suffix,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("RemoveResource")]
Task<ActionResult> Remove(
[FromQuery] string resource,
[FromQuery] string language,
CancellationToken cancellationToken = default
);
}
}
+24
View File
@@ -0,0 +1,24 @@
using xDataService.Configuration;
using xDataService.Interfaces;
using xDataService.Providers;
using xStringService.Interfaces;
using xStringService.Models.Entities;
namespace xStringService.Providers.Entities
{
public abstract class XStringSeederBase : XBaseDbSeeder<XString, int>, IXStringSeeder
{
protected XStringSeederBase(
string entity,
string database,
IXBaseRepository<XString, int> repository,
XDataServiceConfiguration dataServiceConfiguration
) : base(
entity,
database,
repository,
dataServiceConfiguration
)
{ }
}
}
+30
View File
@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore;
using xDataService.Interfaces;
using xDataService.Providers;
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)
{
base.ConfigureEntities(modelBuilder);
}
}
}
+614 -1
View File
@@ -1,6 +1,619 @@
# xStringService
it is a Part of xDashboard on SaherElm IT Center which provides String Resources Futures ...
it is a Part of xDashboard on SaherElm IT Center which provides:
- all requirements to Implement String Resource Features in a **xDashboard** based Project.
this module has following dependencies :
- xModels
- xCommons
- xDataService
- xPushService
- xIdentityModels
- xIdentityService
for configure and use this Module refer to DI.XDIHelperExtension.cs file.
## String Resource
an string resource is a Key/Value based structure which used in Multi Language Applications for accessing Translated of Spcified Values by Key, in Specified Languages.
this architecture is very useful for implementing other services in an Application. such as Terms and Conditions.
## Data Persists
all of Provided features of this Module is works based on Data Persistance. so data models is Very Important.
in this section all Data models explained.
data manipulation done using **xDataService** provided Features.
- **XString**: an Entity Model for Mapping to Tables.
- **XStringDto**: a Data Transfer Object for Representing a Data Model.
- **XStringEntityConfiguration**: a Configuration file for XString Entity.
- **XStringEntityHub**: a Hub Implementation for XString Entity Model.
- **XStringDtoHub**: a Hub Implementation for XStringDto Model.
- **XStringEntityRegisterar**: an Implementation class for Dynamically Register XString Entity in a DbContext.
- **IXStringRepositoryEvents**: an Interface for Repository Events Describing of XString Entity.
- **XStringRepositoryEvents**: an Implementation for Repository Events of XString Entity.
- **IXStringKeyGenerator**: an Interface for Describing Key Generator Actions for XString Entity.
- **XStringKeyGenerator**: an Implementation for Describing Key Generator Actions for XString Entity.
- **IXStringRepository**: an Interface for Describing XString Repository Actions.
- **XStringEFRepository**: an Implementation of EF Core based XString Repository Actions.
- **XStringMongoRepository**: an Implementation of MongoDb based XString Repository Actions.
- **XStringMongoRepository**: an Implementation of MongoDb based XString Repository Actions.
- **XStringInMemoryRepository**: an Implementation of InMemory based XString Repository Actions.
- **IXStringSeeder**: an Interface for Describe XString DbSeeder actions.
- **XStringSeederBase**: an abstraction of Implementation of XString DbSeeder actions.
- **IXStringRepositoryProvider**: an Interface for Describing XString Repository Provider (using Hubs) actions.
- **XStringRepositoryProvider**: an Implementation of XString Repository Provider (using Hubs) actions.
- **IXStringRepositoryService**: an Interface for Describing XString Repository Service Actions (using XStringDto).
- **XStringRepositoryService**: an Implementation of XString Repository Service Actions (using XStringDto).
- **IXStringServiceProvider**: an Interface for Describing XString Repository Service Actions Provider (using Hubs and XStringDto).
- **XStringServiceProvider**: an Implementation of XString Repository Service Actions Provider (using Hubs and XStringDto).
- **XStringGraphType**: introduce XString Data model for GraphQL using.
- **XStringGraphQuery**: introduce Repositry Implementation of XString model actions as Query Actions for GraphQL using.
- **XStringGraphSchema**: introduce XString Query Schema for GraphQL using.
- **IXStringGraphQLTypeHelper**: an Interface for Describing XString GraphQL Type Helper Provided Actions.
- **IXStringGraphQLTypeHelper**: an Implementation of XString GraphQL Type Helper Provided Actions.
data presistance almost is a Down Layer works which handled using Service it self.
but in some Used cases of Applications Business Logics, for Manipulating resources you can use above Registered Services by Injecting them.
## Providers
this module actually used to act as a base Provider for implementing Features based on it.
for this purpose, provides some Features which described in this section.
### String Resource Provider
some services used XString model for Provide Specially Concept's of Actions. for example Terms and Conditions Services use XString Persisted Resource for Specified Purpose.
this Module provides some sort of tools for this purpose. which described in this section.
#### Data Transfer Models
this service used some Data Transfer Models for Data Providing. which Described in this section.
```C#
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>();
}
```
#### IXBaseStringResourceProvider
an interface for Describe Provided Actions of Resource based Service.
```C#
/// <summary>
/// a Base Class for Handling Resources Based on Specified Types on
/// String Resources Use ...
/// such as:
/// - Terms and Conditions;
/// - Contents;
/// - News;
/// - etc ...
/// </summary>
public interface IXBaseStringResourceProvider
{
//
#region Props ...
string Prefix { get; }
IXStringServiceProvider Provider { get; }
XAppConfiguration AppConfiguration { get; }
#endregion
//
#region Actions ...
/// <summary>
/// Prepare Resource Title by Given Data ...
/// </summary>
/// <param name="suffix"></param>
/// <returns></returns>
string GetResourceTitle(string suffix);
/// <summary>
/// Add Specified Locales ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="locales"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XStringDto>> Add(
string suffix,
IEnumerable<XLocaleResourceDto> locales,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add Or Update Specified Locals ...
/// </summary>
/// <param name="resource"></param>
/// <param name="locales"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XStringDto>> AddOrUpdate(
string resource,
IEnumerable<XLocaleResourceDto> locales,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get Specified Locale ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XLocaleResourceDto> GetLocale(
string suffix,
string language = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XResourceDto> AddResource(
string suffix,
XResourceDto item,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get Resources of Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XResourceDto> GetResource(
string suffix,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove Specified Suffix Resources ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task Remove(
string suffix,
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 Remove(
string resource,
string language,
string connectionId = null,
CancellationToken cancellationToken = default
);
#endregion
}
```
#### XBaseStringResourceProvider
an implementation of Provided Actions of Resource based Service.
```C#
/// <summary>
/// a Base Class for Handling Resources Based on Specified Types on
/// String Resources Use ...
/// such as:
/// - Terms and Conditions;
/// - Contents;
/// - News;
/// - etc ...
/// </summary>
public abstract class XBaseStringResourceProvider : IXBaseStringResourceProvider
{
//
#region Props ...
public string Prefix { get; }
public IXStringServiceProvider Provider { get; }
public XAppConfiguration AppConfiguration { get; }
#endregion
//
#region Constructor ...
public XBaseStringResourceProvider(
string prefix,
IXStringServiceProvider provider,
XAppConfiguration appConfiguration
)
{
//
Prefix = prefix;
Provider = provider;
AppConfiguration = appConfiguration;
}
#endregion
//
#region Actions ...
/// <summary>
/// Prepare Resource Title by Given Data ...
/// </summary>
/// <param name="suffix"></param>
/// <returns></returns>
public string GetResourceTitle(string suffix)
{
//
string result = "";
//
if (suffix.IsNullOrEmpty())
{
return result;
}
//
result = $"{Prefix}_${suffix}";
//
return result;
}
/// <summary>
/// Add Specified Locales ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="locales"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XStringDto>> Add(
string suffix,
IEnumerable<XLocaleResourceDto> locales,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var has =
locales.HasChild() &&
!suffix.IsNullOrEmpty();
if (!has)
{
XException.InvalidArgs.Throw();
}
//
// Prepare Resource ID ...
string resourceID = GetResourceTitle(suffix);
var result = await locales.SelectAsync(async l =>
{
//
// Normalize Language ...
if (l.Language.IsNullOrEmpty())
{
l.Language = AppConfiguration.DefaultLanguage;
}
//
// Prepare Model for Add ...
var model = new XStringDto
{
Language = l.Language,
TranslatedValue = l.Value,
ResourceTitle = resourceID,
};
model = await Provider.AddAsync(
item: model,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
return model;
});
//
return result;
}
/// <summary>
/// Add Or Update Specified Locals ...
/// </summary>
/// <param name="resource"></param>
/// <param name="locales"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XStringDto>> AddOrUpdate(
string resource,
IEnumerable<XLocaleResourceDto> locales,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
locales.HasChild() &&
!resource.IsNullOrEmpty() &&
locales.All(l => !l.Value.IsNullOrEmpty() && !l.Language.IsNullOrEmpty());
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Resource ...
isValid = resource.Contains(Prefix);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
var result = await locales.SelectAsync(async l =>
await Provider.AddOrUpdateByLocaleResource(
item: l,
resource: resource,
connectionId: connectionId,
cancellationToken: cancellationToken
)
);
//
return result;
}
/// <summary>
/// Get Specified Locale ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XLocaleResourceDto> GetLocale(
string suffix,
string language = null,
CancellationToken cancellationToken = default
)
{
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
if (suffix.IsNullOrEmpty() || language.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Prepare Resource Title ...
string resource = GetResourceTitle(suffix);
//
// Check Resource Exists ...
var isExists = await Provider.IsResourceExists(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
if (!isExists)
{
XException.NotFound.Throw();
}
//
// Retrieve and Validate Dto Model ...
var model = await Provider.Get(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
if (model.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
// Prepare Result ...
var result = model
.ToXLocaleResourceDto();
return result;
}
/// <summary>
/// Add Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XResourceDto> AddResource(
string suffix,
XResourceDto item,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
if (suffix.IsNullOrEmpty() ||
item.IsNull() ||
!item.Locales.HasChild() ||
!item.Locales.All(l => !l.Value.IsNullOrEmpty()))
{
XException.InvalidArgs.Throw();
}
//
// Prepare Resource ID ...
var addedLocals = await Add(
suffix: suffix,
locales: item.Locales,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!addedLocals.HasChild())
{
XException.ActionFailed.Throw();
}
//
var result = await GetResource(
suffix: suffix,
cancellationToken: cancellationToken
);
return result;
}
/// <summary>
/// Get Resources of Specified Resource ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XResourceDto> GetResource(
string suffix,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
if (suffix.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Prepare Resource ID ...
string resourceID = GetResourceTitle(suffix);
//
// Prepare ...
var result = await Provider.GetResource(
resource: resourceID,
cancellationToken: cancellationToken
);
return result;
}
/// <summary>
/// Remove Specified Suffix Resources ...
/// </summary>
/// <param name="suffix"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Remove(
string suffix,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
if (suffix.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
var resourceID = GetResourceTitle(suffix);
await Provider.RemoveResource(
resource: resourceID,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
/// <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 Remove(
string resource,
string language,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
!resource.IsNullOrEmpty() &&
!language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check resource ID Contains Prefix ...
isValid = resource.Contains(Prefix);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
// Check Exists ...
var isExists = await Provider.IsResourceExists(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
if (!isExists)
{
XException.NotFound.Throw();
}
//
// Remove Resource ...
await Provider.Remove(
resource: resource,
language: language,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
#endregion
}
```
## Maintainer