Compare commits

...
4 Commits
32 changed files with 609 additions and 172 deletions
+3 -3
View File
@@ -1,9 +1,9 @@
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using xCommons.Constants; using xCommons.Constants;
using xCommons.Extensions; using xCommons.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Authorization;
namespace xCommons.Attributes { namespace xCommons.Attributes {
public partial class RequireXPoweredAttribute : AuthorizeAttribute, IAuthorizationFilter { public partial class RequireXPoweredAttribute : AuthorizeAttribute, IAuthorizationFilter {
+1 -1
View File
@@ -1,6 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using IdentityModel; using IdentityModel;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
namespace xCommons.Authorization { namespace xCommons.Authorization {
+3 -3
View File
@@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Mvc; using xCommons.Providers;
using Microsoft.Extensions.Logging;
using xCommons.Attributes; using xCommons.Attributes;
using xCommons.Configurations; using xCommons.Configurations;
using xCommons.Providers; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace xCommons.Controllers { namespace xCommons.Controllers {
/// <summary> /// <summary>
+3 -3
View File
@@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Mvc; using xCommons.Providers;
using Microsoft.Extensions.Logging;
using xCommons.Attributes; using xCommons.Attributes;
using xCommons.Configurations; using xCommons.Configurations;
using xCommons.Providers; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace xCommons.Controllers { namespace xCommons.Controllers {
/// <summary> /// <summary>
+6 -6
View File
@@ -1,12 +1,12 @@
using System; using System;
using Microsoft.AspNetCore.Authorization; using xCommons.Providers;
using xCommons.Attributes;
using xCommons.Extensions;
using xExceptions.Constants;
using xCommons.Configurations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using xCommons.Attributes; using Microsoft.AspNetCore.Authorization;
using xCommons.Configurations;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
namespace xCommons.Controllers { namespace xCommons.Controllers {
/// <summary> /// <summary>
+1 -1
View File
@@ -1,5 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using xCommons.Providers; using xCommons.Providers;
using Microsoft.Extensions.DependencyInjection;
public static partial class XDIHelperExtension { public static partial class XDIHelperExtension {
/// <summary> /// <summary>
+23
View File
@@ -0,0 +1,23 @@
using xCommons.Providers;
using Microsoft.Extensions.DependencyInjection;
namespace xCommons.Extensions
{
public static class BackgroundServiceExtensions
{
/// <summary>
/// Register Background Services ...
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="source"></param>
public static void AddXBackgroundService<TService>(
this IServiceCollection source
)
where TService : XBackgroundService
{
//
source.AddSingleton<TService>();
source.AddHostedService<TService>();
}
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Configuration;
using xCommons.Constants;
using xCommons.Models; using xCommons.Models;
using xCommons.Constants;
using Microsoft.Extensions.Configuration;
namespace xCommons.Extensions { namespace xCommons.Extensions {
public static partial class CertificateExtensions { public static partial class CertificateExtensions {
+15 -15
View File
@@ -1,26 +1,26 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO; 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.Web;
using System.Xml; using System.Xml;
using AutoMapper; using AutoMapper;
using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using xCommons.Constants;
using xCommons.Helpers; using xCommons.Helpers;
using xExceptions.Attributes; using System.Threading;
using System.Reflection;
using xCommons.Constants;
using Newtonsoft.Json.Linq;
using System.Globalization;
using xExceptions.Constants; using xExceptions.Constants;
using System.Threading.Tasks;
using xExceptions.Attributes;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using Newtonsoft.Json.Serialization;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
namespace xCommons.Extensions namespace xCommons.Extensions
{ {
+179 -94
View File
@@ -1,19 +1,22 @@
using System; using System;
using System.Collections.Generic; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Builder; using xCommons.Filters;
using xCommons.Constants;
using xCommons.Configurations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Models;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Swashbuckle.AspNetCore.SwaggerUI;
using Swashbuckle.AspNetCore.SwaggerGen;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; 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 { namespace xCommons.Extensions
public static partial class DIExtensions { {
public static partial class DIExtensions
{
/// <summary> /// <summary>
/// Inject Specific Registered Service from IServiceCollection /// Inject Specific Registered Service from IServiceCollection
@@ -21,10 +24,11 @@ namespace xCommons.Extensions {
/// <param name="source"></param> /// <param name="source"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static T GetRegisteredService<T> (this IServiceCollection source) { public static T GetRegisteredService<T>(this IServiceCollection source)
{
// //
var serviceProvider = source.BuildServiceProvider (); var serviceProvider = source.BuildServiceProvider();
return serviceProvider.GetService<T> (); return serviceProvider.GetService<T>();
} }
/// <summary> /// <summary>
@@ -32,10 +36,55 @@ namespace xCommons.Extensions {
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="services"></param>
/// <param name="configuration"></param> /// <param name="configuration"></param>
public static void AddXAppConfiguration (this IServiceCollection services, IConfiguration configuration) { public static void AddXAppConfiguration(this IServiceCollection services, IConfiguration configuration)
{
// //
var appConfiguration = configuration.GetXAppConfiguration (); var appConfiguration = configuration.GetXAppConfiguration();
services.AddSingleton<XAppConfiguration> (appConfiguration); services.AddSingleton<XAppConfiguration>(appConfiguration);
}
/// <summary>
/// Search Assemblies, Extract XML Comments and
/// Integrate them inside swagger gen documents ...
/// </summary>
/// <param name="source"></param>
public static void IncludeAssembliesXMLComments(this SwaggerGenOptions source)
{
//
// Extract all Exists .xml files ...
var basePath = AppContext.BaseDirectory;
var xmlFiles = Directory.GetFiles(basePath, "*.xml", SearchOption.TopDirectoryOnly);
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
//
// Loop through Detected XML Files ...
foreach (var xmlFile in xmlFiles)
{
//
try
{
//
// Retrieve file name for Assembly Checking ...
var assemblyName = Path.GetFileNameWithoutExtension(xmlFile);
//
// Try to retrieve Assembly ...
var assembly = assemblies
.FirstOrDefault(a => a.GetName().Name == assemblyName);
if (!assembly.IsNullOrDefault() ||
File.Exists(Path.Combine(basePath, $"{assemblyName}.dll"))
)
{
//
// Includes Selected XML Comments ...
source.IncludeXmlComments(xmlFile);
}
}
catch (Exception ex)
{
Console.WriteLine($"Warning: Could not include XML comments from {xmlFile}. Error: {ex.Message}");
}
}
} }
/// <summary> /// <summary>
@@ -46,51 +95,62 @@ namespace xCommons.Extensions {
/// <param name="addRequiredXPoweredFilter"></param> /// <param name="addRequiredXPoweredFilter"></param>
/// <param name="addXTokenAuthorization"></param> /// <param name="addXTokenAuthorization"></param>
/// <param name="addDefaultValueFilter"></param> /// <param name="addDefaultValueFilter"></param>
public static void AddXSwaggerGenOptions ( public static void AddXSwaggerGenOptions(
this SwaggerGenOptions source, this SwaggerGenOptions source,
string xmlFilePath = null, string xmlFilePath = null,
bool addRequiredXPoweredFilter = true, bool addRequiredXPoweredFilter = true,
bool addXTokenAuthorization = true, bool addXTokenAuthorization = true,
bool addDefaultValueFilter = true bool addDefaultValueFilter = true
) { )
{
// //
if (source.IsNull ()) { if (source.IsNull())
source = new SwaggerGenOptions (); {
source = new SwaggerGenOptions();
} }
// //
// Add Xml File Path ... // Add Xml File Path ...
if (!xmlFilePath.IsNullOrEmpty ()) { if (!xmlFilePath.IsNullOrEmpty())
source.IncludeXmlComments (xmlFilePath); {
source.IncludeXmlComments(xmlFilePath);
} }
//
// Include all XML Documents ...
source.IncludeAssembliesXMLComments();
// //
// Handle RequireXPowered Filter ... // Handle RequireXPowered Filter ...
if (addRequiredXPoweredFilter) { if (addRequiredXPoweredFilter)
source.OperationFilter<RequireXPoweredOperationFilter> (); {
source.OperationFilter<RequireXPoweredOperationFilter>();
} }
// //
// Add Default Values Filter ... // Add Default Values Filter ...
if (addDefaultValueFilter) { if (addDefaultValueFilter)
source.OperationFilter<SwaggerDefaultValuesOperationFilter> (); {
source.OperationFilter<SwaggerDefaultValuesOperationFilter>();
} }
// //
// Handle XToken Authorizations ... // Handle XToken Authorizations ...
if (addXTokenAuthorization) { if (addXTokenAuthorization)
{
// //
#region Bearer AccessToken ... #region Bearer AccessToken ...
// //
source.AddSecurityDefinition (nameof (XAuthorization.AccessToken), new OpenApiSecurityScheme { source.AddSecurityDefinition(nameof(XAuthorization.AccessToken), new OpenApiSecurityScheme
{
In = ParameterLocation.Header, In = ParameterLocation.Header,
Description = "Bearer token", Description = "Bearer token",
Type = SecuritySchemeType.ApiKey, Type = SecuritySchemeType.ApiKey,
Name = XAuthorization.Header Name = XAuthorization.Header
}); });
// //
source.AddSecurityRequirement (new OpenApiSecurityRequirement { source.AddSecurityRequirement(new OpenApiSecurityRequirement {
{ {
new OpenApiSecurityScheme { new OpenApiSecurityScheme {
Reference = new OpenApiReference { Reference = new OpenApiReference {
@@ -105,15 +165,16 @@ namespace xCommons.Extensions {
// //
#region RefreshToken ... #region RefreshToken ...
// //
source.AddSecurityDefinition (nameof (XAuthorization.RefreshToken), new OpenApiSecurityScheme { source.AddSecurityDefinition(nameof(XAuthorization.RefreshToken), new OpenApiSecurityScheme
{
In = ParameterLocation.Header, In = ParameterLocation.Header,
Description = "refresh token", Description = "refresh token",
Type = SecuritySchemeType.ApiKey, Type = SecuritySchemeType.ApiKey,
Name = nameof (XAuthorization.RefreshToken) Name = nameof(XAuthorization.RefreshToken)
}); });
// //
source.AddSecurityRequirement (new OpenApiSecurityRequirement { source.AddSecurityRequirement(new OpenApiSecurityRequirement {
{ {
new OpenApiSecurityScheme { new OpenApiSecurityScheme {
Reference = new OpenApiReference { Reference = new OpenApiReference {
@@ -128,15 +189,16 @@ namespace xCommons.Extensions {
// //
#region ExpiresAt ... #region ExpiresAt ...
// //
source.AddSecurityDefinition (nameof (XAuthorization.ExpiresAt), new OpenApiSecurityScheme { source.AddSecurityDefinition(nameof(XAuthorization.ExpiresAt), new OpenApiSecurityScheme
{
In = ParameterLocation.Header, In = ParameterLocation.Header,
Description = "expires at", Description = "expires at",
Type = SecuritySchemeType.ApiKey, Type = SecuritySchemeType.ApiKey,
Name = nameof (XAuthorization.ExpiresAt) Name = nameof(XAuthorization.ExpiresAt)
}); });
// //
source.AddSecurityRequirement (new OpenApiSecurityRequirement { source.AddSecurityRequirement(new OpenApiSecurityRequirement {
{ {
new OpenApiSecurityScheme { new OpenApiSecurityScheme {
Reference = new OpenApiReference { Reference = new OpenApiReference {
@@ -160,7 +222,7 @@ namespace xCommons.Extensions {
/// <param name="addRequiredXPoweredFilter"></param> /// <param name="addRequiredXPoweredFilter"></param>
/// <param name="addXTokenAuthorization"></param> /// <param name="addXTokenAuthorization"></param>
/// <param name="addDefaultValueFilter"></param> /// <param name="addDefaultValueFilter"></param>
public static void AddXSwagger ( public static void AddXSwagger(
this IServiceCollection source, this IServiceCollection source,
IConfiguration configuration, IConfiguration configuration,
SwaggerGenOptions settings = null, SwaggerGenOptions settings = null,
@@ -168,11 +230,13 @@ namespace xCommons.Extensions {
bool addRequiredXPoweredFilter = true, bool addRequiredXPoweredFilter = true,
bool addXTokenAuthorization = true, bool addXTokenAuthorization = true,
bool addDefaultValueFilter = true bool addDefaultValueFilter = true
) { )
{
// //
var xSwaggerConfig = configuration.GetXSwaggerConfiguration (); var xSwaggerConfig = configuration.GetXSwaggerConfiguration();
if (xSwaggerConfig.IsNull ()) { if (xSwaggerConfig.IsNull())
xSwaggerConfig = new XSwaggerConfiguration (); {
xSwaggerConfig = new XSwaggerConfiguration();
} }
// //
@@ -180,10 +244,11 @@ namespace xCommons.Extensions {
// //
#region Prepare SwaggerGenOptions ... #region Prepare SwaggerGenOptions ...
if (settings.IsNull ()) { if (settings.IsNull())
settings = new SwaggerGenOptions (); {
settings = new SwaggerGenOptions();
} }
settings.AddXSwaggerGenOptions ( settings.AddXSwaggerGenOptions(
xmlFilePath: xmlFilePath, xmlFilePath: xmlFilePath,
addDefaultValueFilter: addDefaultValueFilter, addDefaultValueFilter: addDefaultValueFilter,
addXTokenAuthorization: addXTokenAuthorization, addXTokenAuthorization: addXTokenAuthorization,
@@ -195,7 +260,8 @@ namespace xCommons.Extensions {
#region Prepare Swagger Doc ... #region Prepare Swagger Doc ...
// //
// Api Document Section ... // Api Document Section ...
var apiDoc = new OpenApiInfo { var apiDoc = new OpenApiInfo
{
Title = xSwaggerConfig.Title, Title = xSwaggerConfig.Title,
Version = xSwaggerConfig.Version, Version = xSwaggerConfig.Version,
Description = xSwaggerConfig.Description, Description = xSwaggerConfig.Description,
@@ -203,23 +269,27 @@ namespace xCommons.Extensions {
// //
// Api Document TermsOfUse URL ... // Api Document TermsOfUse URL ...
if (!xSwaggerConfig.TermsOfServiceUrl.IsNullOrEmpty ()) { if (!xSwaggerConfig.TermsOfServiceUrl.IsNullOrEmpty())
apiDoc.TermsOfService = new Uri (xSwaggerConfig.TermsOfServiceUrl); {
apiDoc.TermsOfService = new Uri(xSwaggerConfig.TermsOfServiceUrl);
} }
// //
// Contact Section ... // Contact Section ...
if (!xSwaggerConfig.Contact.IsNull ()) { if (!xSwaggerConfig.Contact.IsNull())
{
// //
var apiContact = new OpenApiContact { var apiContact = new OpenApiContact
{
Name = xSwaggerConfig.Contact.Name, Name = xSwaggerConfig.Contact.Name,
Email = xSwaggerConfig.Contact.Email Email = xSwaggerConfig.Contact.Email
}; };
// //
// Contact URL ... // Contact URL ...
if (!xSwaggerConfig.Contact.Url.IsNullOrEmpty ()) { if (!xSwaggerConfig.Contact.Url.IsNullOrEmpty())
apiContact.Url = new Uri (xSwaggerConfig.Contact.Url); {
apiContact.Url = new Uri(xSwaggerConfig.Contact.Url);
} }
// //
@@ -228,16 +298,19 @@ namespace xCommons.Extensions {
// //
// License Section ... // License Section ...
if (!xSwaggerConfig.License.IsNull ()) { if (!xSwaggerConfig.License.IsNull())
{
// //
var apiLicense = new OpenApiLicense { var apiLicense = new OpenApiLicense
{
Name = xSwaggerConfig.License.Name, Name = xSwaggerConfig.License.Name,
}; };
// //
// License URL ... // License URL ...
if (!xSwaggerConfig.License.Url.IsNullOrEmpty ()) { if (!xSwaggerConfig.License.Url.IsNullOrEmpty())
apiLicense.Url = new Uri (xSwaggerConfig.License.Url); {
apiLicense.Url = new Uri(xSwaggerConfig.License.Url);
} }
// //
@@ -247,13 +320,14 @@ namespace xCommons.Extensions {
// //
// Register Swagger ... // Register Swagger ...
source.AddSwaggerGen ( source.AddSwaggerGen(
opt => { opt =>
{
// //
opt.UpdateData (settings); opt.UpdateData(settings);
// //
opt.SwaggerDoc ("v1", apiDoc); opt.SwaggerDoc("v1", apiDoc);
} }
); );
@@ -266,18 +340,22 @@ namespace xCommons.Extensions {
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <param name="options"></param> /// <param name="options"></param>
public static void UseXSwagger ( public static void UseXSwagger(
this IApplicationBuilder source, this IApplicationBuilder source,
SwaggerUIOptions options = null SwaggerUIOptions options = null
) { )
{
// //
source.UseSwagger (); source.UseSwagger();
// //
if (options.IsNull ()) { if (options.IsNull())
source.UseSwaggerUI (); {
} else { source.UseSwaggerUI();
source.UseSwaggerUI (options: options); }
else
{
source.UseSwaggerUI(options: options);
} }
} }
@@ -286,24 +364,28 @@ namespace xCommons.Extensions {
/// </summary> /// </summary>
/// <param name="source"></param> /// <param name="source"></param>
/// <param name="allowedOrigins"></param> /// <param name="allowedOrigins"></param>
public static void AddXCors ( public static void AddXCors(
this IServiceCollection source, this IServiceCollection source,
IEnumerable<string> allowedOrigins IEnumerable<string> allowedOrigins
) { )
{
// //
if (!allowedOrigins.HasChild ()) { if (!allowedOrigins.HasChild())
{
// //
Console.WriteLine ($"XCommons: there is no provided allowedOrigins, start app without any specific cors, this may be unsecure ..."); Console.WriteLine($"XCommons: there is no provided allowedOrigins, start app without any specific cors, this may be unsecure ...");
// //
source.AddCors (options => { source.AddCors(options =>
options.AddPolicy (XPolicy.AllowedOrigins, {
builder => { options.AddPolicy(XPolicy.AllowedOrigins,
builder =>
{
builder builder
.AllowAnyOrigin () .AllowAnyOrigin()
.AllowAnyHeader () .AllowAnyHeader()
.AllowAnyMethod () .AllowAnyMethod()
.WithExposedHeaders ("*"); .WithExposedHeaders("*");
}); });
}); });
@@ -312,15 +394,17 @@ namespace xCommons.Extensions {
} }
// //
source.AddCors (options => { source.AddCors(options =>
options.AddPolicy (XPolicy.AllowedOrigins, {
builder => { options.AddPolicy(XPolicy.AllowedOrigins,
builder =>
{
builder builder
.WithOrigins (allowedOrigins.ToArray ()) .WithOrigins(allowedOrigins.ToArray())
.AllowAnyHeader () .AllowAnyHeader()
.AllowAnyMethod () .AllowAnyMethod()
.AllowCredentials () .AllowCredentials()
.WithExposedHeaders ("*"); .WithExposedHeaders("*");
}); });
}); });
} }
@@ -329,9 +413,10 @@ namespace xCommons.Extensions {
/// Use X Registered Cross Origin Resource Sharings /// Use X Registered Cross Origin Resource Sharings
/// </summary> /// </summary>
/// <param name="sources"></param> /// <param name="sources"></param>
public static void UseXCors (this IApplicationBuilder sources) { public static void UseXCors(this IApplicationBuilder sources)
{
// //
sources.UseCors (XPolicy.AllowedOrigins); sources.UseCors(XPolicy.AllowedOrigins);
} }
/// <summary> /// <summary>
@@ -355,7 +440,7 @@ namespace xCommons.Extensions {
// //
// Report All Available Api Versions on Response ... // Report All Available Api Versions on Response ...
opt.ReportApiVersions = true; opt.ReportApiVersions = true;
}); });
} }
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
using System; using System;
using xExceptions.Constants;
using xExceptions.Models; using xExceptions.Models;
using xExceptions.Constants;
namespace xCommons.Extensions { namespace xCommons.Extensions {
/// <summary> /// <summary>
+2 -2
View File
@@ -1,8 +1,8 @@
using System.Linq; using System.Linq;
using xCommons.Configurations;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using xCommons.Configurations;
namespace xCommons.Extensions { namespace xCommons.Extensions {
public static partial class FilterExtensions { public static partial class FilterExtensions {
+3 -3
View File
@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Configuration;
using xCommons.Configurations;
using xCommons.Constants; using xCommons.Constants;
using xCommons.Configurations;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
namespace xCommons.Extensions namespace xCommons.Extensions
{ {
+1 -2
View File
@@ -1,12 +1,11 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using UglyToad.PdfPig; using UglyToad.PdfPig;
using System.Threading; using System.Threading;
using xCommons.Extensions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using xCommons.Extensions;
namespace xAiModels.Extensions namespace xAiModels.Extensions
{ {
+3 -3
View File
@@ -1,9 +1,9 @@
using System; using System;
using System.Linq;
using System.Reflection;
using System.Linq.Expressions;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace xCommons.Extensions namespace xCommons.Extensions
{ {
+1 -1
View File
@@ -1,8 +1,8 @@
using System; using System;
using xCommons.Helpers;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using xCommons.Helpers;
namespace xCommons.Extensions { namespace xCommons.Extensions {
public static class ServiceProviderExtensions { public static class ServiceProviderExtensions {
+1 -2
View File
@@ -1,6 +1,5 @@
using System;
using Microsoft.AspNetCore.Builder;
using xCommons.Middlewares; using xCommons.Middlewares;
using Microsoft.AspNetCore.Builder;
namespace xCommons.Extensions namespace xCommons.Extensions
{ {
+5 -5
View File
@@ -1,10 +1,10 @@
using System.Collections.Generic;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using xCommons.Configurations;
using xCommons.Constants; using xCommons.Constants;
using xCommons.Extensions; using xCommons.Extensions;
using Microsoft.OpenApi.Any;
using xCommons.Configurations;
using Microsoft.OpenApi.Models;
using System.Collections.Generic;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace xCommons.Filters { namespace xCommons.Filters {
/// <summary> /// <summary>
@@ -1,9 +1,9 @@
using System.Linq; using System.Linq;
using xCommons.Extensions;
using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Any;
using xCommons.Configurations;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerGen;
using xCommons.Configurations;
using xCommons.Extensions;
namespace xCommons.Filters namespace xCommons.Filters
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Collections.Generic;
namespace xCommons.Helpers { namespace xCommons.Helpers {
public partial class ObjectHelper { public partial class ObjectHelper {
+1 -1
View File
@@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using xCommons.Extensions; using xCommons.Extensions;
using System.Collections.Generic;
namespace xCommons.Helpers namespace xCommons.Helpers
{ {
+2 -2
View File
@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
using System.Xml; using System.Xml;
using System.Text;
using System.Collections.Generic;
namespace xCommons.Helpers { namespace xCommons.Helpers {
public partial class XMLToJSONHelper { public partial class XMLToJSONHelper {
+4 -4
View File
@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Linq;
using System.Net.Sockets;
using xCommons.Models; using xCommons.Models;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Net.NetworkInformation;
namespace xCommons.Helpers { namespace xCommons.Helpers {
public static class XNetworkHelper { public static class XNetworkHelper {
+3 -3
View File
@@ -1,10 +1,10 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using xCommons.Extensions; using xCommons.Extensions;
using xExceptions.Attributes;
using xExceptions.Constants; using xExceptions.Constants;
using System.Threading.Tasks;
using xExceptions.Attributes;
using System.Runtime.InteropServices;
namespace xCommons.Helpers namespace xCommons.Helpers
{ {
+2 -2
View File
@@ -1,10 +1,10 @@
using System; using System;
using System.IO; using System.IO;
using xCommons.Models;
using xCommons.Extensions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xCommons.Models;
namespace xCommons.Middlewares { namespace xCommons.Middlewares {
public partial class XRequestLogger { public partial class XRequestLogger {
+2 -2
View File
@@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic;
using System.Net.NetworkInformation;
namespace xCommons.Models { namespace xCommons.Models {
public class XNetworkInfo { public class XNetworkInfo {
+26
View File
@@ -0,0 +1,26 @@
using System;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace xCommons.Providers
{
/// <summary>
/// Default Background Service ...
/// </summary>
public abstract class XBackgroundService : BackgroundService
{
//
protected readonly IServiceProvider serviceProvider;
protected readonly ILogger<XBackgroundService> logger;
protected XBackgroundService(
IServiceProvider serviceProvider,
ILogger<XBackgroundService> logger
)
{
//
this.logger = logger;
this.serviceProvider = serviceProvider;
}
}
}
+1 -4
View File
@@ -1,12 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks;
using xCommons.Extensions; using xCommons.Extensions;
using xCommons.Interfaces; using xCommons.Interfaces;
using System.Security.Cryptography;
namespace xCommons.Providers namespace xCommons.Providers
{ {
+93
View File
@@ -0,0 +1,93 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace xCommons.Providers
{
/// <summary>
/// Resumable Background Task ...
/// </summary>
public abstract class XResumableBackgroundService : XBackgroundService
{
/// <summary>
/// Check is Paused ...
/// </summary>
protected bool paused = false;
protected XResumableBackgroundService(
IServiceProvider serviceProvider,
ILogger<XResumableBackgroundService> logger
) : base(
logger: logger,
serviceProvider: serviceProvider
)
{ }
protected override async Task ExecuteAsync(
CancellationToken stoppingToken = default
)
{
//
if (paused)
{
return;
}
//
await DoWorkAsync(
payload: null,
cancellationToken: stoppingToken
);
}
/// <summary>
/// do all required works here ...
/// </summary>
/// <param name="payload"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public abstract Task DoWorkAsync(
object payload = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Pause Consuming ...
/// </summary>
/// <returns></returns>
public bool Pause()
{
//
var result = !paused;
if (!result)
{
return result;
}
//
paused = true;
result = paused;
return result;
}
/// <summary>
/// Resume Consuming ...
/// </summary>
/// <returns></returns>
public bool Resume()
{
//
var result = paused;
if (!result)
{
return result;
}
//
paused = false;
result = !paused;
return result;
}
}
}
+215
View File
@@ -0,0 +1,215 @@
using System;
using System.Threading;
using xCommons.Extensions;
using xExceptions.Constants;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace xCommons.Providers
{
/// <summary>
/// Do Background Jobs based on Time Intervals ...
/// </summary>
public abstract class XTimeBasedBackgroundService : XBackgroundService
{
//
private bool isWorking = false;
private readonly TimeSpan restartInterval;
private readonly SemaphoreSlim mlock = new(1, 1);
public DateTime? LastRunTime { get; private set; }
private CancellationTokenSource cancellationTokenSource;
protected XTimeBasedBackgroundService(
IServiceProvider serviceProvider,
ILogger<XTimeBasedBackgroundService> logger,
int intervalInMinutes = 10
) : base(
logger: logger,
serviceProvider: serviceProvider
)
{
//
// Validate Interval ...
if (intervalInMinutes <= 0)
{
XException.InvalidArgs.Throw();
}
//
restartInterval = TimeSpan.FromMinutes(intervalInMinutes);
}
/// <summary>
/// Override base action to Implement timing ...
/// </summary>
/// <param name="stoppingToken"></param>
/// <returns></returns>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
//
while (!stoppingToken.IsCancellationRequested)
{
try
{
if (!isWorking)
{
//
// Enable Working ...
await mlock.WaitAsync(stoppingToken);
try
{
isWorking = true;
}
finally
{
mlock.Release();
}
//
// Start a new work task ...
cancellationTokenSource = CancellationTokenSource
.CreateLinkedTokenSource(stoppingToken);
//
// Execute the work ...
await ExecuteWorkAsync(cancellationTokenSource.Token);
//
// Disable Working ...
await mlock.WaitAsync(stoppingToken);
try
{
isWorking = false;
}
finally
{
mlock.Release();
}
//
// Wait for the restart interval ...
await Task.Delay(restartInterval, stoppingToken);
}
else
{
//
// Prevent tight error loops ...
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
catch (OperationCanceledException)
{
//
// Disable Working ...
await mlock.WaitAsync(stoppingToken);
try
{
isWorking = false;
}
finally
{
mlock.Release();
}
break;
}
catch (Exception)
{
//
// Disable Working ...
await mlock.WaitAsync(stoppingToken);
try
{
isWorking = false;
}
finally
{
mlock.Release();
}
//
// Prevent tight error loops ...
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
}
}
}
/// <summary>
/// Override Stop Background Worker ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task StopAsync(CancellationToken cancellationToken)
{
//
// Cancel the current work session
cancellationTokenSource.Cancel();
await base.StopAsync(cancellationToken);
}
/// <summary>
/// Dispose all Objects ...
/// </summary>
public override void Dispose()
{
mlock.Dispose();
cancellationTokenSource.Dispose();
GC.SuppressFinalize(this);
base.Dispose();
}
/// <summary>
/// do all required works here ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public abstract Task DoWorkAsync(
CancellationToken cancellationToken = default
);
/// <summary>
/// Refresh Worker ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Refresh(
CancellationToken cancellationToken = default
)
{
//
// Cancel current work if running
cancellationTokenSource.Cancel();
//
// Wait a moment for cancellation
await Task.Delay(100, cancellationToken);
//
// Start new work immediately
cancellationTokenSource = CancellationTokenSource
.CreateLinkedTokenSource(cancellationToken);
await ExecuteWorkAsync(cancellationTokenSource.Token);
}
//
#region Private ...
private async Task ExecuteWorkAsync(CancellationToken cancellationToken)
{
//
LastRunTime = DateTime.UtcNow;
try
{
await DoWorkAsync(cancellationToken);
}
catch (OperationCanceledException)
{
}
catch (Exception)
{
}
finally
{
}
}
#endregion
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using xCommons.Extensions; using xCommons.Extensions;
using xExceptions.Constants; using xExceptions.Constants;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace xCommons.Providers { namespace xCommons.Providers {
public partial class XValidationProvider { public partial class XValidationProvider {
+2 -2
View File
@@ -65,9 +65,9 @@
<!-- For XML Documentation Support --> <!-- For XML Documentation Support -->
<PropertyGroup> <PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn> <NoWarn>$(NoWarn);1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup> </PropertyGroup>
</Project> </Project>