
### 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    

    }
}
