
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Configurations\Entities\XFileEntityConfiguration.cs

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using xDataService.Providers;
using xFileService.Constants;
using xFileService.Models.Entities;

namespace xFileService.Configurations.Entities
{
    public class XFileEntityConfiguration : XBaseEntityTypeConfiguration<XFile, Guid>
    {
        public override void Configure(EntityTypeBuilder<XFile> builder)
        {
            builder.ToTable(XFileServiceConstants.XFileTable);
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Constants\XFileServiceConstants.cs

using xFileService.Models.Entities;

namespace xFileService.Constants
{
    public struct XFileServiceConstants
    {
        //
        // Service Extensions Log Tag ...
        public const string XFileServiceDILogTag = "XFileService";

        //
        // Table Mapping Identifiers ...
        public const string XFileTable = "Files";

        //
        // GraphQL Collection Mappings ...
        public const string XFileSingleName = "file";
        public const string XFileCollectionName = "files";

        //
        // Hubs ...
        public const string XFileDtoHub = "fileDto";
        public const string XFileEntityHub = "fileEntity";

        //
        // Custome Constants ...
        public const string XFileTagProvided = nameof(XFile);

        //
        // EF Repositories Helper Extensions ...
        public const string GetXFileEFRepositoryDescriptor = "GetXFileEFRepositoryDescriptor";
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileProviderControllerBase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Extensions;
using xCommons.Providers;
using xDataService.Models;
using xExceptions.Constants;
using xFileService.Interfaces;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityService.Interfaces;
using xTagService.Controllers;

namespace xFileService.Controllers
{
    public abstract class XFileProviderControllerBase : XBaseProvidedHasTagControllerBase<XFile, XFileDto, Guid, XFileDtoHub>, IXFileProviderController
    {
        private readonly IXFileProvider provider;

        protected XFileProviderControllerBase(
            ILogger<XFileProviderControllerBase> logger,
            XAppConfiguration appConfiguration,
            IXIdentityProvider identityProvider,
            XValidationProvider validationProvider,
            IXFileProvider provider,
            IXFileTagProvided tagProvided,
            Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
            Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
        ) : base(
            logger,
            appConfiguration,
            identityProvider,
            validationProvider,
            provider,
            tagProvided,
            defaultOrderBuilder,
            defaultIncludeBuilder
        )
        {
            this.provider = provider;
        }

        //
        #region Tools ...
        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{id}/Stream/ById")]
        public virtual async Task<ActionResult> Stream(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                var result = await provider.Stream(
                    id: id,
                    cancellationToken: cancellationToken
                );

                //
                return result;
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{name}/Stream/ByName")]
        public virtual async Task<ActionResult> Stream(
            [FromRoute] string name,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                var result = await provider.Stream(
                    name: name,
                    cancellationToken: cancellationToken
                );

                //
                return result;
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{id}/Download/ById")]
        public virtual async Task<ActionResult> Download(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                var result = await provider.Download(
                    id: id,
                    cancellationToken: cancellationToken
                );

                //
                return result;
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{name}/Download/ByName")]
        public virtual async Task<ActionResult> Download(
            string name,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                var result = await provider.Download(
                    name: name,
                    cancellationToken: cancellationToken
                );

                //
                return result;
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Upload Files ...
        /// </summary>
        /// <param name="files"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpPost("Upload")]
        [RequestSizeLimit(966_367_641)]
        public virtual async Task<ActionResult<IEnumerable<XFileDto>>> Upload(
            [FromForm] IFormFileCollection files,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Retrieve User Info ...
                var userInfo = await GetUserInfo();
                var connectionId = GetConnectionId();

                //
                var result = await provider.Upload(
                    files: files,
                    userInfo: userInfo,
                    connectionId: connectionId,
                    cancellationToken: cancellationToken
                );

                //
                return Ok(result.ToDynamicObject());
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Remove Specified Files ...
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpDelete("")]
        public virtual async Task<ActionResult<IEnumerable<Guid>>> Remove(
            [FromQuery] string ids,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Retrieve User Info ...
                var userInfo = await GetUserInfo();
                var connectionId = GetConnectionId();

                //
                var result = await provider.Remove(
                    ids: ids,
                    userInfo: userInfo,
                    connectionId: connectionId,
                    cancellationToken: cancellationToken
                );

                //
                return Ok(result.ToDynamicObject());
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }
        #endregion                

        //
        #region Reference ...
        /// <summary>
        /// Check an Item Has Reference to Specified ProvideFor and Specified forProvidedId ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{id}/Reference/IsProvidedFor")]
        public virtual async Task<ActionResult<bool>> IsProvidedFor(
            [FromRoute] Guid id,
            [FromQuery] string providedFor,
            [FromQuery] object forProvidedId,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Validate ...
                if (!ModelState.IsValid)
                {
                    XException.InvalidArgs.Throw();
                }
                await ValidationProvider
                    .GroupValidationBuilder()
                    .AddNotNull(id)
                    .AddNotEmpty(providedFor)
                    .AddNotNull(forProvidedId)
                    .ValidateGroupAsync();

                //
                var result = await provider.IsProvidedFor(
                    id: id,
                    providedFor: providedFor,
                    forProvidedId: forProvidedId,
                    cancellationToken: cancellationToken
                );

                //
                return Ok(result);
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Add a Reference to Item for Specified ProvideFor and Specified forProvidedId ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="forIndex"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpPost("{id}/Reference")]
        public virtual async Task<ActionResult> AddReference(
            [FromRoute] Guid id,
            [FromQuery] string providedFor,
            [FromQuery] object forProvidedId,
            [FromQuery] int forIndex = 0,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Validate ...
                if (!ModelState.IsValid)
                {
                    XException.InvalidArgs.Throw();
                }
                await ValidationProvider
                    .GroupValidationBuilder()
                    .AddNotNull(id)
                    .AddNotEmpty(providedFor)
                    .AddNotNull(forProvidedId)
                    .ValidateGroupAsync();

                //
                var userInfo = await GetUserInfo();
                var connectionId = GetConnectionId();

                //
                await provider.AddReference(
                    id: id,
                    forIndex: forIndex,
                    userInfo: userInfo,
                    providedFor: providedFor,
                    connectionId: connectionId,
                    forProvidedId: forProvidedId,
                    cancellationToken: cancellationToken
                );

                //
                return Ok();
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Remove a Reference from Item for Specified ProvideFor and Specified forProvidedId ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="forIndex"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpDelete("{id}/Reference")]
        public virtual async Task<ActionResult> RemoveReference(
            [FromRoute] Guid id,
            [FromQuery] string providedFor,
            [FromQuery] object forProvidedId,
            [FromQuery] int forIndex = 0,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Validate ...
                if (!ModelState.IsValid)
                {
                    XException.InvalidArgs.Throw();
                }
                await ValidationProvider
                    .GroupValidationBuilder()
                    .AddNotNull(id)
                    .AddNotEmpty(providedFor)
                    .AddNotNull(forProvidedId)
                    .ValidateGroupAsync();

                //
                var userInfo = await GetUserInfo();
                var connectionId = GetConnectionId();

                //
                await provider.RemoveReference(
                    id: id,
                    forIndex: forIndex,
                    userInfo: userInfo,
                    providedFor: providedFor,
                    connectionId: connectionId,
                    forProvidedId: forProvidedId,
                    cancellationToken: cancellationToken
                );

                //
                return Ok();
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }

        /// <summary>
        /// Retrieve References of Specified Itemfor providedFor ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="providedFor"></param>
        /// <param name="cancellationToken"></param>
        /// <typeparam name="TReferenceKey"></typeparam>
        /// <returns></returns>
        [HttpGet("{id}/References")]
        public virtual async Task<ActionResult<IEnumerable<XReference<string>>>> GetReferences(
            [FromRoute] Guid id,
            [FromQuery] string providedFor,
            CancellationToken cancellationToken = default
        )
        {
            //
            try
            {
                //
                // Validate ...
                if (!ModelState.IsValid)
                {
                    XException.InvalidArgs.Throw();
                }
                await ValidationProvider
                    .GroupValidationBuilder()
                    .AddNotNull(id)
                    .AddNotEmpty(providedFor)
                    .ValidateGroupAsync();

                //
                var result = await provider.GetReferences(
                    id: id,
                    providedFor: providedFor,
                    cancellationToken: cancellationToken
                );

                //
                return Ok(result.ToDynamicObject());
            }
            catch (Exception ex)
            {
                //
                var result = GetExceptionActionResult(ex);
                return result;
            }
        }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileRepositoryControllerBase.cs

using System;
using System.Linq;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Providers;
using xDataService.Controllers;
using xDataService.Interfaces;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Controllers
{
    public abstract class XFileRepositoryControllerBase : XBaseRepositoryController<XFile, Guid>, IXBaseRepositoryController<XFile, Guid>
    {
        protected XFileRepositoryControllerBase(
            ILogger<XFileRepositoryControllerBase> logger,
            XAppConfiguration appConfiguration,
            XValidationProvider validationProvider,
            IXFileRepository repository,
            Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
            Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
        ) : base(
            logger,
            appConfiguration,
            validationProvider,
            repository,
            defaultOrderBuilder,
            defaultIncludeBuilder
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileRepositoryProviderControllerBase.cs

using System;
using System.Linq;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;
using xFileService.Providers.Entities;
using xIdentityService.Interfaces;
using xPushService.Controllers;
using xPushService.Interfaces;

namespace xFileService.Controllers
{
    public abstract class XFileRepositoryProviderControllerBase : XBaseRepositoryProviderController<XFile, Guid, XFileEntityHub>, IXBaseRepositoryProviderController<XFile, Guid, XFileEntityHub>
    {
        protected XFileRepositoryProviderControllerBase(
            ILogger<XFileRepositoryProviderControllerBase> logger,
            XAppConfiguration appConfiguration,
            IXIdentityProvider identityProvider,
            XValidationProvider validationProvider,
            IXFileRepositoryProvider provider,
            Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
            Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
        ) : base(
            logger,
            appConfiguration,
            identityProvider,
            validationProvider,
            provider,
            defaultOrderBuilder,
            defaultIncludeBuilder
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileServiceControllerBase.cs

using System;
using System.Linq;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Providers;
using xDataService.Controllers;
using xDataService.Interfaces;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;

namespace xFileService.Controllers
{
    public abstract class XFileServiceControllerBase : XBaseServiceController<XFile, XFileDto, Guid>, IXBaseServiceController<XFile, XFileDto, Guid>
    {
        protected XFileServiceControllerBase(
            ILogger<XFileServiceControllerBase> logger,
            XAppConfiguration appConfiguration,
            XValidationProvider validationProvider,
            IXFileRepositoryService repositoryService,
            Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
            Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
        ) : base(
            logger,
            appConfiguration,
            validationProvider,
            repositoryService,
            defaultOrderBuilder,
            defaultIncludeBuilder
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Controllers\XFileServiceProviderControllerBase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Providers;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityService.Interfaces;
using xPushService.Controllers;
using xPushService.Interfaces;

namespace xFileService.Controllers
{
    public abstract class XFileServiceProviderControllerBase : XBaseServiceProviderController<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseServiceProviderController<XFile, XFileDto, Guid, XFileDtoHub>
    {
        protected XFileServiceProviderControllerBase(
            ILogger<XFileServiceProviderControllerBase> logger,
            XAppConfiguration appConfiguration,
            IXIdentityProvider identityProvider,
            XValidationProvider validationProvider,
            IXFileServiceProvider provider,
            Func<IQueryable<XFile>, IOrderedQueryable<XFile>> defaultOrderBuilder = null,
            Func<IQueryable<XFile>, IIncludableQueryable<XFile, object>> defaultIncludeBuilder = null
        ) : base(
            logger,
            appConfiguration,
            identityProvider,
            validationProvider,
            provider,
            defaultOrderBuilder,
            defaultIncludeBuilder
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\DI\XDIHelperExtension.cs

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xCommons.Helpers;
using xDataService.Constants;
using xDataService.Db;
using xDataService.DI;
using xDataService.Models;
using xExceptions.Constants;
using xPushService.DI;
using xPushService.Helpers;
using xFileService.Helpers;
using xFileService.Interfaces.Dtos;
using xFileService.Interfaces.Entities;
using xFileService.Providers.Dtos;
using xFileService.Providers.Entities;
using xFileService.Interfaces;
using xFileService.Providers;
using xFileService.Constants;

namespace xFileService.DI
{
    public static class XDIHelperExtension
    {
        /// <summary>
        /// Register Service ...
        /// </summary>
        /// <param name="services"></param>
        /// <param name="repositoryType"></param>
        /// <param name="lifeTime"></param>
        public static void AddXFileService(
            this IServiceCollection services,
            XRepositoryType repositoryType,
            ServiceLifetime lifeTime = ServiceLifetime.Scoped
        )
        {
            AddFileService(
                contextType: null,
                services: services,
                lifeTime: lifeTime,
                repositoryType: repositoryType
            );
        }

        /// <summary>
        /// Register Service ...
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <param name="services"></param>
        /// <param name="repositoryType"></param>
        /// <param name="lifeTime"></param>
        public static void AddXFileService<TContext>(
            this IServiceCollection services,
            XRepositoryType repositoryType,
            ServiceLifetime lifeTime = ServiceLifetime.Scoped
        )
        where TContext : XDbContext
        {
            AddFileService(
                services: services,
                lifeTime: lifeTime,
                contextType: typeof(TContext),
                repositoryType: repositoryType
            );
        }

        /// <summary>
        /// Use XFileService Middleware ... 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="isDevelopmentEnvironment"></param>
        public static void UseXFileService(
            this IApplicationBuilder app,
            bool isDevelopmentEnvironment = false
        )
        {
            //
            #region  Using XFile Hubs ...
            //
            var pushHelper = new XPushServiceHelper();

            //
            pushHelper.AddHub<XFileDtoHub>(XFileServiceConstants.XFileDtoHub);
            pushHelper.AddHub<XFileEntityHub>(XFileServiceConstants.XFileEntityHub);

            //
            app.UseXPushService(pushHelper);
            #endregion

            //
            // Using XFile Repository Descriptor ...
            if (!descriptor.IsNull())
            {
                //
                app.UseXRepository(
                    descriptor: descriptor,
                    isDevelopmentEnvironment: isDevelopmentEnvironment
                );
            }
        }

        //
        #region Private ...
        private static XRepositoryDescriptor descriptor = null;

        /// <summary>
        /// a LogTag for Service ...
        /// </summary>
        private static string XLogTag = XFileServiceConstants.XFileServiceDILogTag;

        /// <summary>
        /// print a log in Console ...
        /// </summary>
        /// <param name="message"></param>
        private static void Log(string message)
        {
            Console.WriteLine($"{XLogTag} => {message}");
        }

        /// <summary>
        /// Register Service ...
        /// </summary>
        /// <param name="services"></param>
        /// <param name="repositoryType"></param>
        /// <param name="contextType"></param>
        /// <param name="lifeTime"></param>
        private static void AddFileService(
            IServiceCollection services,
            XRepositoryType repositoryType,
            Type contextType = null,
            ServiceLifetime lifeTime = ServiceLifetime.Scoped
        )
        {
            //
            var exception = XException.InvalidArgs.ToException(); ;

            //
            // Services ...
            var isServicesExists = !services.IsNull();
            if (!isServicesExists)
            {
                //
                Log("Service Registration failed, services not provided ...");
                throw exception;
            }

            //
            // Lifetime ...
            var isLifetimeExists = !lifeTime.IsNull();
            if (!isLifetimeExists)
            {
                //
                Log("Service Registration failed, lifetime not provided ...");
                throw exception;
            }

            //
            // Validate Repository Type ...
            var isRepositoryTypeValid =
                (repositoryType == XRepositoryType.EF &&
                !contextType.IsNull()) ||
                ((repositoryType == XRepositoryType.Mongo ||
                    repositoryType == XRepositoryType.InMemory) &&
                contextType.IsNull());
            if (!isRepositoryTypeValid)
            {
                //
                Log("Service Registration failed, Invalid Repository Type and Context Type ...");
                throw exception;
            }

            //
            // Maske Instance of Repository Descriptor 
            // Based on Provided Type ...
            switch (repositoryType)
            {
                //
                case XRepositoryType.EF:
                    //
                    descriptor = typeof(XFileServiceHelper)
                        .InvokeGenericMethod<XRepositoryDescriptor>(
                            args: null,
                            runtimeType: contextType,
                            methodName: XFileServiceConstants.GetXFileEFRepositoryDescriptor
                    );
                    break;

                //
                case XRepositoryType.Mongo:
                    descriptor = XFileServiceHelper.GetXFileMongoRepositoryDescriptor();
                    break;

                //
                case XRepositoryType.InMemory:
                    descriptor = XFileServiceHelper.GetXFileInMemoryRepositoryDescriptor();
                    break;
            }

            //
            // Register XFile Repository Descriptor ...
            services.AddXRepository(
                lifeTime: lifeTime,
                descriptor: descriptor
            );

            //
            // Register Dto Services ...
            services.Add(
                new ServiceDescriptor(typeof(IXFileServiceProvider), typeof(XFileServiceProvider), lifeTime)
            );
            services.Add(
                new ServiceDescriptor(typeof(IXFileRepositoryService), typeof(XFileRepositoryService), lifeTime)
            );
            services.Add(
                new ServiceDescriptor(typeof(IXFileRepositoryProvider), typeof(XFileRepositoryProvider), lifeTime)
            );

            //
            // Register Additional Service ...
            services.Add(
                new ServiceDescriptor(typeof(IXFileTagProvider), typeof(XFileTagProvider), lifeTime)
            );
            services.Add(
                new ServiceDescriptor(typeof(IXFileTagProvided), typeof(XFileTagProvided), lifeTime)
            );
            services.Add(
                new ServiceDescriptor(typeof(IXFileProvider), typeof(XFileProvider), lifeTime)
            );

            //
            Log("Service Regitration Succeed ...");
        }
        #endregion        
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Extensions\XModelExtensions.cs

using System.Collections.Generic;
using System.Linq;
using xCommons.Extensions;
using xDataService.Extensions;
using xDataService.Models;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;

namespace xFileService.Extensions
{
    public static class XModelExtensions
    {
        /// <summary>
        /// Extract References of a Model ...
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IList<XReference<string>> GetReferences(
            this XFile source
        )
        {
            //
            var result = new List<XReference<string>>();

            //
            if (
                !source.IsNullOrDefault() &&
                !source.References.IsNullOrEmpty()
            )
            {
                //  
                result = source.References
                    .ParseXReferenceList<string>()
                    .ToList();
            }

            //
            return result;
        }

        /// <summary>
        /// Extract References of a Model ...
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IList<XReference<string>> GetReferences(
            this XFileDto source
        )
        {
            //
            var result = new List<XReference<string>>();

            //
            if (
                !source.IsNullOrDefault() &&
                !source.References.IsNullOrEmpty()
            )
            {
                //  
                result = source.References
                    .ParseXReferenceList<string>()
                    .ToList();
            }

            //
            return result;
        }

        /// <summary>
        /// Update a Model's References by Providing References List ...
        /// </summary>
        /// <param name="source"></param>
        /// <param name="references"></param>
        /// <param name="forceClean"></param>
        /// <returns></returns>
        public static XFile UpdateReferences(
            this XFile source,
            IList<XReference<string>> references,
            bool forceClean = true
        )
        {
            //
            XFile result = source;

            //
            if (!source.IsNullOrDefault())
            {
                //
                result = source;
                
                //
                if (forceClean)
                {
                    result.References = string.Empty;
                }

                //
                if (!references.IsNull() && 
                    references.HasChild())
                {
                    result.References = references.ToXReferenceString();
                }
            }

            //
            return result;
        }

        /// <summary>
        /// Update a Model's References by Providing References List ...
        /// </summary>
        /// <param name="source"></param>
        /// <param name="references"></param>
        /// <param name="forceClean"></param>
        /// <returns></returns>
        public static XFileDto UpdateReferences(
            this XFileDto source,
            IList<XReference<string>> references,
            bool forceClean = true
        )
        {
            //
            XFileDto result = source;

            //
            if (!source.IsNullOrDefault())
            {
                //
                result = source;
                
                //
                if (forceClean)
                {
                    result.References = string.Empty;
                }

                //
                if (!references.IsNull() && 
                    references.HasChild())
                {
                    result.References = references.ToXReferenceString();
                }
            }

            //
            return result;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Helpers\XFileServiceHelper.cs

using System;
using GraphQL.Types;
using xDataService.Db;
using xDataService.Models;
using xDataService.Providers;
using xFileService.Interfaces;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;
using xFileService.Providers.Entities;
using xFileService.Providers.GraphQL;

namespace xFileService.Helpers
{
    public static class XFileServiceHelper
    {
        //
        #region EF Repository Descriptor Provider(s) ...
        public static XEFRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileEFRepository<TContext>,
            TContext
        > GetXFileEFRepositoryDescriptor<TContext>()
        where TContext : XDbContext
        {
            //
            var result = new XEFRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileEFRepository<TContext>,
                TContext
            >();

            //
            return result;
        }

        public static XEFRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileEFRepository<TContext>,
            TContext,
            IXFileSeeder,
            TSeederImplementation
        > GetXFileEFRepositoryDescriptor<TContext, TSeederImplementation>()
        where TContext : XDbContext
        where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
        {
            //
            var result = new XEFRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileEFRepository<TContext>,
                TContext,
                IXFileSeeder,
                TSeederImplementation
            >();

            //
            return result;
        }
        #endregion

        //
        #region Mongo Repository Descriptor Provider(s) ...
        public static XMongoRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileMongoRepository
        > GetXFileMongoRepositoryDescriptor()
        {
            //
            var result = new XMongoRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileMongoRepository
            >();

            //
            return result;
        }

        public static XMongoRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileMongoRepository,
            IXFileSeeder,
            TSeederImplementation
        > GetXFileMongoRepositoryDescriptor<TSeederImplementation>()
        where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
        {
            //
            var result = new XMongoRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileMongoRepository,
                IXFileSeeder,
                TSeederImplementation
            >();

            //
            return result;
        }
        #endregion

        //
        #region InMemory Repository Descriptor Provider(s) ...
        public static XInMemoryRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileInMemoryRepository
        > GetXFileInMemoryRepositoryDescriptor()
        {
            //
            var result = new XInMemoryRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileInMemoryRepository
            >();

            //
            return result;
        }

        public static XInMemoryRepositoryDescriptor<
            XFile,
            Guid,
            IXFileKeyGenerator,
            XFileKeyGenerator,
            IXFileRepositoryEvents,
            XFileRepositoryEvents,
            XFileGraphType,
            GuidGraphType,
            XFileGraphQuery,
            IXFileGraphQLTypeHelper,
            XFileGraphQLTypeHelper,
            XFileGraphSchema,
            IXFileRepository,
            XFileInMemoryRepository,
            IXFileSeeder,
            TSeederImplementation
        > GetXFileInMemoryRepositoryDescriptor<TSeederImplementation>()
        where TSeederImplementation : XBaseDbSeeder<XFile, Guid>
        {
            //
            var result = new XInMemoryRepositoryDescriptor<
                XFile,
                Guid,
                IXFileKeyGenerator,
                XFileKeyGenerator,
                IXFileRepositoryEvents,
                XFileRepositoryEvents,
                XFileGraphType,
                GuidGraphType,
                XFileGraphQuery,
                IXFileGraphQLTypeHelper,
                XFileGraphQLTypeHelper,
                XFileGraphSchema,
                IXFileRepository,
                XFileInMemoryRepository,
                IXFileSeeder,
                TSeederImplementation
            >();

            //
            return result;
        }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileProvider.cs

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityModels.Models;
using xIdentityService.Interfaces;
using xTagService.Interfaces;

namespace xFileService.Interfaces
{
    public interface IXFileProvider : IXBaseProvidedHasTag<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseReferenced<XFile, Guid>
    {
        //
        #region Tools ...
        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<FileStreamResult> Stream(
            Guid id,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<FileStreamResult> Stream(
            string name,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<PhysicalFileResult> Download(
            Guid id,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<PhysicalFileResult> Download(
            string name,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Upload Files ...
        /// </summary>
        /// <param name="files"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<IEnumerable<XFileDto>> Upload(
            IFormFileCollection files,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Remove Specified Files ...
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<IEnumerable<Guid>> Remove(
            string ids,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Retrieve Specified File Streaming Info ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<XFileStreamDescriptorDto> GetFileDescriptor(
            Guid id,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Retrieve Specified File Streaming Info ...
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<XFileStreamDescriptorDto> GetFileDescriptor(
            string fileName,
            CancellationToken cancellationToken = default
        );
        #endregion        
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileProviderController.cs

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityService.Interfaces;
using xTagService.Interfaces;

namespace xFileService.Interfaces
{
    public interface IXFileProviderController : IXBaseProvidedHasTagController<XFile, XFileDto, Guid, XFileDtoHub>, IXBaseReferencedController<XFile, Guid>
    {
        //
        #region Tools ...
        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{id}/Stream/ById")]
        Task<ActionResult> Stream(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{name}/Stream/ByName")]
        Task<ActionResult> Stream(
            [FromRoute] string name,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{id}/Download/ById")]
        Task<ActionResult> Download(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpGet("{name}/Download/ByName")]
        Task<ActionResult> Download(
            string name,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Upload Files ...
        /// </summary>
        /// <param name="files"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpPost("Upload")]
        [RequestSizeLimit(966_367_641)]        
        Task<ActionResult<IEnumerable<XFileDto>>> Upload(
            [FromForm] IFormFileCollection files,
            CancellationToken cancellationToken = default
        );

        /// <summary>
        /// Remove Specified Files ...
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        [HttpDelete("")]
        Task<ActionResult<IEnumerable<Guid>>> Remove(
            [FromQuery] string ids,
            CancellationToken cancellationToken = default
        );
        #endregion                
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileTagProvided.cs

using System;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xTagService.Interfaces;

namespace xFileService.Interfaces
{
    public interface IXFileTagProvided : IXTagProvided<XFile, XFileDto, Guid, XFileDtoHub>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\IXFileTagProvider.cs

using System;
using xTagService.Interfaces;

namespace xFileService.Interfaces
{
    public interface IXFileTagProvider : IXBaseTagProvider<Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileDtoHub.cs

using System;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xPushService.Interfaces;

namespace xFileService.Interfaces.Dtos
{
    public interface IXFileDtoHub : IXBaseDtoHub<XFile, XFileDto, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileRepositoryService.cs

using System;
using xDataService.Interfaces;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Dtos
{
    public interface IXFileRepositoryService : IXBaseRepositoryService<XFile, XFileDto, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Dtos\IXFileServiceProvider.cs

using System;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xPushService.Interfaces;

namespace xFileService.Interfaces.Dtos
{
    public interface IXFileServiceProvider : IXBaseDtoProvider<XFile, XFileDto, Guid, XFileDtoHub>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileEntityHub.cs

using System;
using xFileService.Models.Entities;
using xPushService.Interfaces;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileEntityHub : IXBaseEntityHub<XFile, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileGraphQLTypeHelper.cs

using System;
using xDataService.Interfaces;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileGraphQLTypeHelper : IXBaseGraphQLTypeHelper<XFile, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileKeyGenerator.cs

using System;
using xDataService.Interfaces;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileKeyGenerator : IXKeyGenerator<XFile, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepository.cs

using System;
using xDataService.Interfaces;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileRepository : IXBaseRepository<XFile, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepositoryEvents.cs

using xDataService.Interfaces;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileRepositoryEvents : IXBaseRepositoryEvents<XFile>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileRepositoryProvider.cs

using System;
using xFileService.Models.Entities;
using xFileService.Providers.Entities;
using xPushService.Interfaces;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileRepositoryProvider : IXBaseEntityProvider<XFile, Guid, XFileEntityHub>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Interfaces\Entities\IXFileSeeder.cs

using System;
using xDataService.Interfaces;
using xFileService.Models.Entities;

namespace xFileService.Interfaces.Entities
{
    public interface IXFileSeeder : IXBaseDbSeeder<XFile, Guid>
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Dtos\XFileDto.cs

using System;
using xCommons.Constants;
using xModels.Base;
using xModels.Dtos;

namespace xFileService.Models.Dtos
{
    public class XFileDto : XBaseGuidIDEntityDto
    {
        public XFileType Type { get; set; }
        public string Name { get; set; }
        public string Thumb { get; set; }
        public string Path { get; set; }
        public string ThumbPath { get; set; }
        public DateTime UploadedOn { get; set; }
        public string FileName { get; set; }

        public string OwnerId { get; set; }
        public XPersonDto Owner { get; set; }

        public string References { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Dtos\XFileStreamDescriptorDto.cs

using System.IO;
using xModels.Base;

namespace xFileService.Models.Dtos
{
    public class XFileStreamDescriptorDto : XBaseDto
    {
        public Stream Stream { get; set; }
        public string MIMEType { get; set; }
        public string Name { get; set; }
        public string Path { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Models\Entities\XFile.cs

using System;
using System.ComponentModel.DataAnnotations;
using xCommons.Constants;
using xModels.Base;

namespace xFileService.Models.Entities
{
    /// <summary>
    /// Specified File in Server ...
    /// </summary>
    public class XFile : XBaseGuidIDEntity
    {
        /// <summary>
        /// Specified File Type ...
        /// </summary>
        /// <value></value>
        public XFileType Type { get; set; }

        /// <summary>
        /// User Identifier ...
        /// </summary>
        /// <value></value>
        [Required]
        [StringLength(255)]
        public string OwnerId { get; set; }

        /// <summary>
        /// File Name on Server ...
        /// </summary>
        /// <value></value>
        [Required]
        [StringLength(255)]
        public string Name { get; set; }

        /// <summary>
        /// File Path On Server ...
        /// </summary>
        /// <value></value>
        [Required]
        public string Path { get; set; }

        /// <summary>
        /// Thumbnail FIle Name ...
        /// if File Type Supported Thumbnail ...
        /// </summary>
        /// <value></value>
        public string Thumb { get; set; }

        /// <summary>
        /// Thumbnail File Path ...
        /// if File Type Supported Thumbnail ...
        /// </summary>
        /// <value></value>
        public string ThumbPath { get; set; }

        /// <summary>
        /// File Uploading Time ...
        /// </summary>
        /// <value></value>
        public DateTime UploadedOn { get; set; }

        /// <summary>
        /// Request For Upload File Name on Client ...
        /// </summary>
        /// <value></value>
        public string FileName { get; set; }

        /// <summary>
        /// Comma Separated List Which Provides Pointer to Specified 
        /// Model for Describe ...
        /// </summary>
        /// <value></value>
        public string References { get; set; }        
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileEntityRegisterar.cs

using System;
using Microsoft.EntityFrameworkCore;
using xDataService.Interfaces;
using xDataService.Providers;
using xFileService.Configurations.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers
{
    public class XFileEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar
    {
        public XFileEntityRegisterar()
        : base(nameof(XFileEntityRegisterar))
        {
            //
            // Add XFile Entity ...
            AddEntity<XFile, Guid>();
        }

        /// <summary>
        /// Configure Entities ...
        /// </summary>
        /// <param name="modelBuilder"></param>
        public override void ConfigureEntities(ModelBuilder modelBuilder)
        {
            //
            // Configure Entity Using Provided ...
            modelBuilder
                .ApplyConfigurationsFromAssembly(typeof(XFileEntityConfiguration).Assembly);

            //
            base.ConfigureEntities(modelBuilder);
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileProvider.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using xCommons.Extensions;
using xDataService.Models;
using xExceptions.Constants;
using xFileService.Extensions;
using xFileService.Interfaces;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityModels.Models;
using xStorageService.Interfaces;
using xTagService.Providers;

namespace xFileService.Providers
{
    public class XFileProvider : XBaseProvidedHasTag<XFile, XFileDto, Guid, XFileDtoHub>, IXFileProvider
    {
        private readonly IXFileServiceProvider provider;
        private readonly IXStorageProvider storageProvider;

        public XFileProvider(
            IXFileTagProvider tagProvider,
            IXFileServiceProvider provider,
            IXStorageProvider storageProvider
        ) : base(
            provider: provider,
            tagProvider: tagProvider,
            permittedRoles: new string[] { "admin" }
        )
        {
            this.provider = provider;
            this.storageProvider = storageProvider;
        }

        public override bool IsOwned(
            XFile item,
            XUserClaimsInfoDto userInfo
        )
        {
            //
            var result =
                !item.IsNullOrDefault() &&
                !userInfo.IsNullOrDefault() &&
                !item.OwnerId.IsNullOrEmpty() &&
                userInfo.UserId == item.OwnerId;

            //
            return result;
        }

        public override bool IsOwned(
            XFileDto item,
            XUserClaimsInfoDto userInfo
        )
        {
            //
            var result =
                !item.IsNullOrDefault() &&
                !userInfo.IsNullOrDefault() &&
                !item.OwnerId.IsNullOrEmpty() &&
                userInfo.UserId == item.OwnerId;

            //
            return result;
        }

        //
        #region Tools ...
        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<FileStreamResult> Stream(
            Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !id.IsNull() &&
                !id.IsDefaultGuid();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Generate Stream Info and Validate it ...
            var stream = await GetFileDescriptor(
                id: id,
                cancellationToken: cancellationToken
            );
            if (stream.IsNull())
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Result Model ...
            var result = new FileStreamResult(
                stream.Stream,
                stream.MIMEType
            )
            {
                FileDownloadName = stream.Name
            };

            //
            return result;
        }

        /// <summary>
        /// Stream Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<FileStreamResult> Stream(
            string name,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !name.IsNullOrEmpty();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Generate Stream Info and Validate it ...
            var stream = await GetFileDescriptor(
                fileName: name,
                cancellationToken: cancellationToken
            );
            if (stream.IsNull())
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Result Model ...
            var result = new FileStreamResult(
                stream.Stream,
                stream.MIMEType
            )
            {
                FileDownloadName = stream.Name
            };

            //
            return result;
        }

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<PhysicalFileResult> Download(
            Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !id.IsNull() &&
                !id.IsDefaultGuid();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Generate Stream Info and Validate it ...
            var stream = await GetFileDescriptor(
                id: id,
                cancellationToken: cancellationToken
            );
            if (stream.IsNull())
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Result Model ...
            var result = new PhysicalFileResult(
                stream.Path,
                stream.MIMEType
            )
            {
                FileDownloadName = stream.Name
            };

            //
            return result;
        }

        /// <summary>
        /// Download Specified File ...
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<PhysicalFileResult> Download(
            string name,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !name.IsNullOrEmpty();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Generate Stream Info and Validate it ...
            var stream = await GetFileDescriptor(
                fileName: name,
                cancellationToken: cancellationToken
            );
            if (stream.IsNull())
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Result Model ...
            var result = new PhysicalFileResult(
                stream.Path,
                stream.MIMEType
            )
            {
                FileDownloadName = stream.Name
            };

            //
            return result;
        }

        /// <summary>
        /// Upload Files ...
        /// </summary>
        /// <param name="files"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<IEnumerable<XFileDto>> Upload(
            IFormFileCollection files,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !files.IsNull() &&
                files.HasChild() &&
                !userInfo.IsNullOrDefault();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Save Files On Server Side Physically ...
            // and Validate it ...
            var uploadResults = await storageProvider
                .HandleFilesSave(files);
            isValid = uploadResults.HasChild();
            if (!isValid)
            {
                XException.ActionFailed.Throw();
            }

            //
            // Prepare Result ...
            var result = new List<XFileDto>();
            foreach (var ur in uploadResults)
            {
                //
                var fileType = storageProvider.GetFileType(ur.FileName);

                //
                // Create Item Model ...
                var item = new XFileDto
                {
                    Type = fileType,
                    FileName = ur.Name,
                    Name = ur.FileName,
                    Path = ur.FilePath,
                    Thumb = ur.Thmbnail,
                    OwnerId = userInfo.UserId,
                    ThumbPath = ur.ThmbnailPath,
                    UploadedOn = DateTime.UtcNow,
                };

                //
                try
                {
                    //
                    // Add Entity Model to DB ...
                    item = await Add(
                        item: item,
                        userInfo: userInfo,
                        connectionId: connectionId,
                        cancellationToken: cancellationToken
                    );

                    //
                    result.Add(item);
                }
                catch { }
            }

            //
            return result;
        }

        /// <summary>
        /// Remove Specified Files ...
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<IEnumerable<Guid>> Remove(
            string ids,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate Args ...
            var isValid = !ids.IsNullOrEmpty() &&
                !userInfo.IsNullOrDefault();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Parse ID(s) List ...
            var idsList = ids.ParseListGuid();
            isValid = !idsList.IsNull() &&
                idsList.HasChild();
            if (!isValid)
            {
                XException.ActionFailed.Throw();
            }

            //
            // Loop Through Parsed Ids and Try to Remove ...
            var result = new List<Guid>();
            foreach (var id in idsList)
            {
                //
                // Retrieve XFileDto and Validate it ...
                var model = await Get(id);
                isValid = !model.IsNull() && !model.Id.IsNull() && !model.Id.IsDefaultGuid();
                if (!isValid)
                {
                    continue;
                }

                //
                // Check Physical File Exists or not ...
                var fileFullPath = storageProvider.GetFileFullPath(model.Name);
                var thumbFullPath = model.Thumb.IsNullOrEmpty()
                    ? ""
                    : storageProvider.GetThumbnailFileFullPath(model.Thumb);
                var isFileExists = storageProvider.IsFileExists(fileFullPath);
                var isThumbExists = model.Thumb.IsNullOrEmpty()
                    ? false
                    : storageProvider.IsFileExists(thumbFullPath);

                //
                // Remove Physical Thumbnail File ...
                if (isThumbExists)
                {
                    //
                    try
                    {
                        //
                        // Removed Stored Thumbnail ...
                        storageProvider.DeleteFile(
                           fileFullPath: thumbFullPath,
                           forceFileExists: false
                        );
                    }
                    catch { }
                }

                //
                // Remove Pgysical File ...
                if (isFileExists)
                {
                    //
                    try
                    {
                        //
                        // Remove Stored File ...
                        storageProvider.DeleteFile(
                            fileFullPath: fileFullPath,
                            forceFileExists: false
                        );

                        //
                        // Remove Tags ...
                        await DetachTags(
                            id: id,
                            userInfo: userInfo,
                            connectionId: connectionId,
                            cancellationToken: cancellationToken
                        );
                    }
                    catch { }
                }

                //
                // Remove File Entty ...
                var item = await provider.RemoveAsync(
                    id: model.Id,
                    softDelete: false,
                    saveChanges: true,
                    connectionId: connectionId,
                    cancellationToken: cancellationToken
                );
                result.Add(model.Id);
            }

            //
            return result;
        }

        /// <summary>
        /// Retrieve Specified File Streaming Info ...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<XFileStreamDescriptorDto> GetFileDescriptor(
            Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Check File Model Exists or not ...
            var isExists = await IsExists(
                id: id,
                cancellationToken: cancellationToken
            );
            if (!isExists)
            {
                XException.NotFound.Throw();
            }

            //
            // Retrieve Item and Validate it ...
            var item = await Get(
                id: id,
                includeBuilder: null,
                cancellationToken: cancellationToken
            );
            if (item.IsNullOrDefault())
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Physical File Path and Validate it ...
            var fileFullPath = storageProvider.GetFileFullPath(item.Name);
            isExists = storageProvider.IsFileExists(fileFullPath);
            var filePath = storageProvider.FilePathResolver(fileFullPath);
            filePath = Path.Combine("wwwroot", filePath);
            if (!isExists)
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Physical File Info ...
            IFileInfo fileInfo = storageProvider.FileProvider.GetFileInfo(filePath);

            //
            // Prepare Default Streaming Requirements ...
            var mimeType = "application/octetstream";
            var readStream = fileInfo.CreateReadStream();
            var fileMimeProvider = new FileExtensionContentTypeProvider();
            var fileName = item.Name;

            //
            // Try to Find Physical File's Content Type ...
            fileMimeProvider.TryGetContentType(
                filePath,
                out mimeType
            );

            //
            // Prepare Result Model ...
            var result = new XFileStreamDescriptorDto
            {
                Stream = readStream,
                MIMEType = mimeType,
                Name = fileName,
                Path = fileFullPath
            };

            //
            return result;
        }

        /// <summary>
        /// Retrieve Specified File Streaming Info ...
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public virtual async Task<XFileStreamDescriptorDto> GetFileDescriptor(
            string fileName,
            CancellationToken cancellationToken = default
        )
        {
            //
            if (fileName.IsNullOrEmpty())
            {
                XException.InvalidArgs.Throw();
            }
            var item = await FindOne(
                includeBuilder: null,
                predicate: e =>
                    e.Name.Contains(fileName) ||
                    e.Path.Contains(fileName) ||
                    e.Thumb.Contains(fileName) ||
                    e.FileName.Contains(fileName) ||
                    e.ThumbPath.Contains(fileName),
                cancellationToken: cancellationToken
            );
            var isExists = !item.IsNullOrDefault();
            if (!isExists)
            {
                XException.NotFound.Throw();
            }

            //
            // Extract File Name ...
            fileName = Path.GetFileName(fileName);

            //
            // Check File is Thumbnail or File ...
            var isThumb = fileName.StartsWith(storageProvider.Configuration.ThumbPrefix);
            var isFile = fileName.StartsWith(storageProvider.Configuration.FilePrefix);

            //
            // Check File Type is Valid ...
            isExists = isThumb || isFile;
            if (!isExists)
            {
                XException.UnsupportedFileType.Throw();
            }

            //
            // Extract File Full Path ...
            var fileFullPath = "";
            if (isThumb)
            {
                fileFullPath = storageProvider.GetThumbnailFileFullPath(fileName);
            }
            else
            {
                fileFullPath = storageProvider.GetFileFullPath(fileName);
            }

            //
            // Check Physical File Exists or Not ...
            isExists = storageProvider.IsFileExists(fileFullPath);
            if (!isExists)
            {
                XException.NotFound.Throw();
            }

            //
            // Generate Physical File Info ...
            var filePath = storageProvider.FilePathResolver(fileFullPath);
            filePath = Path.Combine("wwwroot", filePath);
            IFileInfo fileInfo = storageProvider.FileProvider.GetFileInfo(filePath);

            //
            // Prepare Default Streaming Requirements ...
            var mimeType = "application/octetstream";
            var readStream = fileInfo.CreateReadStream();
            var fileMimeProvider = new FileExtensionContentTypeProvider();

            //
            // Try to Find Physical File's Content Type ...
            fileMimeProvider.TryGetContentType(filePath, out mimeType);

            //
            // Prepare Result Model ...
            var result = new XFileStreamDescriptorDto
            {
                Stream = readStream,
                MIMEType = mimeType,
                Name = fileName,
                Path = fileFullPath
            };

            //
            return result;
        }
        #endregion

        //
        #region Referenced Actions ...
        /// <summary>
        /// Get Reference Identifier for Specified Provider and Specified Item ...
        /// </summary>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <returns></returns>
        public string GetIdentifier<TReferenceKey>(
            string providedFor,
            TReferenceKey forProvidedId
        )
        {
            //
            var result = $"{providedFor}_{forProvidedId}";

            //
            return result;
        }

        /// <summary>
        /// Check Specified Item has Refernce to Provider ...
        /// </summary>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<bool> IsProvidedFor<TReferenceKey>(
            string providedFor,
            TReferenceKey forProvidedId,
            Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate ...
            var isValid =
                !id.IsNull() &&
                !id.IsDefaultGuid() &&
                !forProvidedId.IsNull() &&
                !providedFor.IsNullOrEmpty();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Check Exists ...
            isValid = await IsExists(
                id: id,
                cancellationToken: cancellationToken
            );
            if (!isValid)
            {
                XException.NotFound.Throw();
            }

            //
            var item = await Get(
                id: id,
                includeBuilder: null,
                cancellationToken: cancellationToken
            );
            isValid = !item.IsNullOrDefault();
            if (!isValid)
            {
                XException.ActionFailed.Throw();
            }

            //
            var references = item.GetReferences();
            var result =
                references.IsNull() &&
                references.HasChild() &&
                references.Any(r =>
                    r.ProvidedFor == providedFor &&
                    r.ReferencedTo == $"{forProvidedId}"
                );

            //
            return result;
        }

        /// <summary>
        /// Add Specified Reference to Specified Item ...
        /// </summary>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="id"></param>
        /// <param name="forIndex"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task AddReference<TReferenceKey>(
            string providedFor,
            TReferenceKey forProvidedId,
            Guid id,
            int forIndex = 0,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate ...
            var isValid =
                !providedFor.IsNullOrEmpty() &&
                !id.IsNull() &&
                !id.IsDefaultGuid() &&
                !providedFor.IsNull() &&
                !userInfo.IsNullOrDefault();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Check Has Reference or not ...
            isValid = await IsProvidedFor(
                id: id,
                providedFor: providedFor,
                forProvidedId: forProvidedId,
                cancellationToken: cancellationToken
            );
            if (isValid)
            {
                //
                // Prevent Moving Forward Since Reference Exists ...
                return;
            }

            //
            // Check Permissions ...
            var item = await Get(
                id: id,
                includeBuilder: null,
                cancellationToken: cancellationToken
            );
            isValid =
                !item.IsNullOrDefault() &&
                (IsOwned(item, userInfo) ||
                HasPermision(userInfo));
            if (!isValid)
            {
                XException.NotAllowed.Throw();
            }

            //
            var reference = new XReference<string>
            {
                Index = forIndex,
                ProvidedFor = providedFor,
                ReferencedTo = $"{forProvidedId}"
            };
            var references = item.GetReferences();
            references.Add(reference);
            item = item.UpdateReferences(references);
            item = await Update(
                id: id,
                item: item,
                userInfo: userInfo,
                connectionId: connectionId,
                cancellationToken: cancellationToken
            );
        }

        /// <summary>
        /// Remove Specified Reference from Specified Item ...
        /// </summary>
        /// <param name="providedFor"></param>
        /// <param name="forProvidedId"></param>
        /// <param name="id"></param>
        /// <param name="forIndex"></param>
        /// <param name="userInfo"></param>
        /// <param name="connectionId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task RemoveReference<TReferenceKey>(
            string providedFor,
            TReferenceKey forProvidedId,
            Guid id,
            int forIndex = 0,
            XUserClaimsInfoDto userInfo = null,
            string connectionId = null,
            CancellationToken cancellationToken = default
        )
        {
            //
            // Validate ...
            var isValid =
                !id.IsNull() &&
                !id.IsDefaultGuid() &&
                !forProvidedId.IsNull() &&
                !userInfo.IsNullOrDefault() &&
                !providedFor.IsNullOrEmpty();
            if (!isValid)
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Check Has Reference or not ...
            isValid = await IsProvidedFor(
                id: id,
                providedFor: providedFor,
                forProvidedId: forProvidedId,
                cancellationToken: cancellationToken
            );
            if (!isValid)
            {
                //
                // Prevent Moving Forward Since Reference not Exists ...
                return;
            }

            //
            // Check Permissions ...
            var item = await Get(
                id: id,
                includeBuilder: null,
                cancellationToken: cancellationToken
            );
            isValid =
                !item.IsNullOrDefault() &&
                (IsOwned(item, userInfo) ||
                HasPermision(userInfo));
            if (!isValid)
            {
                XException.NotAllowed.Throw();
            }

            //
            var identifier = GetIdentifier(
                providedFor: providedFor,
                forProvidedId: forProvidedId
            );
            var references = item.GetReferences();
            references = references
                    .Where(r =>
                        r.Index != forIndex &&
                        r.ProvidedFor != providedFor &&
                        r.ReferencedTo != $"{forProvidedId}"
                    )
                    .ToList();
            item = item.UpdateReferences(references);

            //
            item = await Update(
                item: item,
                id: item.Id,
                userInfo: userInfo,
                connectionId: connectionId,
                cancellationToken: cancellationToken
            );
        }

        /// <summary>
        /// Get Specified References ...
        /// </summary>
        /// <param name="providedFor"></param>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<IEnumerable<XReference<string>>> GetReferences(
            string providedFor,
            Guid id,
            CancellationToken cancellationToken = default
        )
        {
            //
            IList<XReference<string>> result = new List<XReference<string>>();

            //
            var item = await provider.GetAsync(
                id: id,
                includeBuilder: null,
                ignoreSoftDeleteds: true,
                cancellationToken: cancellationToken
            );
            var isValid = !item.IsNullOrDefault();
            if (!isValid)
            {
                return result;
            }

            //
            result = item.GetReferences();

            //
            result = result.Where(r =>
                r.ProvidedFor == providedFor
            )
            .ToList();

            //
            return result;
        }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileTagProvided.cs

using System;
using xCommons.Extensions;
using xFileService.Interfaces;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xFileService.Providers.Dtos;
using xIdentityModels.Models;
using xTagService.Interfaces;
using xTagService.Providers;

namespace xFileService.Providers
{
    public class XFileTagProvided : XBaseTagProvided<XFile, XFileDto, Guid, XFileDtoHub>, IXFileTagProvided
    {
        public XFileTagProvided(
            IXFileTagProvider tagProvider,
            IXFileServiceProvider provider
        ) : base(
            provider: provider,
            tagProvider: tagProvider,
            permittedRoles: new string[] { "admin" }
        )
        { }

        public override bool IsOwned(
            XFileDto item,
            XUserClaimsInfoDto userInfo
        )
        {
            //
            var result =
                !item.IsNullOrDefault() &&
                !userInfo.IsNullOrDefault() &&
                item.OwnerId == userInfo.UserId;

            //
            return result;
        }

        public override bool IsOwned(
            XFile item,
            XUserClaimsInfoDto userInfo
        )
        {
            //
            var result =
                !item.IsNullOrDefault() &&
                !userInfo.IsNullOrDefault() &&
                item.OwnerId == userInfo.UserId;

            //
            return result;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\XFileTagProvider.cs

using System;
using xFileService.Constants;
using xFileService.Interfaces;
using xTagService.Interfaces.Dtos;
using xTagService.Providers;

namespace xFileService.Providers
{
    public class XFileTagProvider : XBaseTagProvider<Guid>, IXFileTagProvider
    {
        public XFileTagProvider(
            IXTagServiceProvider tagProvider
        ) : base(
            tagProvider: tagProvider,
            providedFor: XFileServiceConstants.XFileTagProvided
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileDtoHub.cs

using System;
using Microsoft.Extensions.Logging;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xPushService.Base;

namespace xFileService.Providers.Dtos
{
    public class XFileDtoHub : XBaseDtoHub<XFile, XFileDto, Guid>, IXFileDtoHub
    {
        public XFileDtoHub(
            ILogger<XFileDtoHub> logger
        ) : base(logger)
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileRepositoryService.cs

using System;
using System.Collections.Generic;
using AutoMapper;
using xDataService.Providers;
using xFileService.Interfaces.Dtos;
using xFileService.Interfaces.Entities;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;

namespace xFileService.Providers.Dtos
{
    public class XFileRepositoryService : XBaseRepositoryService<XFile, XFileDto, Guid>, IXFileRepositoryService
    {
        public XFileRepositoryService(
            IXFileRepository repository, 
            IEnumerable<Profile> mapperProfiles = null
        ) : base(
            repository, 
            mapperProfiles
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Dtos\XFileServiceProvider.cs

using System;
using Microsoft.AspNetCore.SignalR;
using xDataService.Configuration;
using xFileService.Interfaces.Dtos;
using xFileService.Models.Dtos;
using xFileService.Models.Entities;
using xIdentityService.Interfaces;
using xPushService.Base;

namespace xFileService.Providers.Dtos
{
    public class XFileServiceProvider : XBaseDtoProvider<XFile, XFileDto, Guid, XFileDtoHub>, IXFileServiceProvider
    {
        public XFileServiceProvider(
            IHubContext<XFileDtoHub> hub,
            XDataServiceConfiguration dataConfiguration,
            IXFileRepositoryService service,
            IXIdentityProvider identityProvider = null
        ) : base(
            hub,
            dataConfiguration,
            service,
            identityProvider
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileEFRepository.cs

using System;
using xDataService.Configuration;
using xDataService.Db;
using xDataService.Interfaces;
using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public class XFileEFRepository<TContext> : XBaseEFRepository<XFile, Guid, TContext>, IXFileRepository
    where TContext : XDbContext
    {
        public XFileEFRepository(
            IXUnitOfWorks<TContext> unitOfWorks,
            XDataServiceConfiguration configuration,
            IXFileKeyGenerator keyGenerator = null,
            IXFileRepositoryEvents baseRepositoryEvents = null
        ) : base(
            unitOfWorks,
            configuration,
            keyGenerator,
            baseRepositoryEvents
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileEntityHub.cs

using System;
using Microsoft.Extensions.Logging;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;
using xPushService.Base;

namespace xFileService.Providers.Entities
{
    public class XFileEntityHub : XBaseEntityHub<XFile, Guid>, IXFileEntityHub
    {
        public XFileEntityHub(
            ILogger<XFileEntityHub> logger
        ) : base(logger)
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileInMemoryRepository.cs

using System;
using xDataService.Configuration;
using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public class XFileInMemoryRepository : XBaseInMemoryRepository<XFile, Guid>, IXFileRepository
    {
        public XFileInMemoryRepository(
            XDataServiceConfiguration configuration,
            IXFileKeyGenerator keyGenerator = null,
            IXFileRepositoryEvents baseRepositoryEvents = null
        ) : base(
            configuration,
            keyGenerator,
            baseRepositoryEvents
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileKeyGenerator.cs

using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public class XFileKeyGenerator : XGuidKeyGenerator<XFile>, IXFileKeyGenerator
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileMongoRepository.cs

using System;
using xDataService.Configuration;
using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public class XFileMongoRepository : XBaseMongoRepository<XFile, Guid>, IXFileRepository
    {
        public XFileMongoRepository(
            XDataBaseConfiguration dbConfiguration,
            XDataServiceConfiguration configuration,
            string collectionName = null,
            IXFileKeyGenerator keyGenerator = null,
            IXFileRepositoryEvents baseRepositoryEvents = null
        ) : base(
            dbConfiguration,
            configuration,
            collectionName,
            keyGenerator,
            baseRepositoryEvents
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileRepositoryEvents.cs

using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public class XFileRepositoryEvents : XBaseRepositoryEvents<XFile>, IXFileRepositoryEvents
    { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileRepositoryProvider.cs

using System;
using Microsoft.AspNetCore.SignalR;
using xDataService.Configuration;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;
using xIdentityService.Interfaces;
using xPushService.Base;

namespace xFileService.Providers.Entities
{
    public class XFileRepositoryProvider : XBaseEntityProvider<XFile, Guid, XFileEntityHub>, IXFileRepositoryProvider
    {
        public XFileRepositoryProvider(
            IHubContext<XFileEntityHub> hub,
            IXFileRepository repository,
            XDataServiceConfiguration dataConfiguration,
            IXIdentityProvider identityProvider = null
        ) : base(
            hub,
            repository,
            dataConfiguration,
            identityProvider
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\Entities\XFileSeederBase.cs

using System;
using xDataService.Configuration;
using xDataService.Providers;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.Entities
{
    public abstract class XFileSeederBase : XBaseDbSeeder<XFile, Guid>, IXFileSeeder
    {
        protected XFileSeederBase(
            string entity,
            string database,
            IXFileRepository repository,
            XDataServiceConfiguration dataServiceConfiguration
        ) : base(
            entity,
            database,
            repository,
            dataServiceConfiguration
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphQLTypeHelper.cs

using System;
using xDataService.Configuration;
using xDataService.GraphQL;
using xFileService.Constants;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.GraphQL
{
    public class XFileGraphQLTypeHelper : XBaseGraphQLTypeHelper<XFile, Guid>, IXFileGraphQLTypeHelper
    {
        public XFileGraphQLTypeHelper(
            XDataServiceConfiguration configuration
        ) : base(configuration)
        { }

        public override string GetInQueryCollectionName()
        {
            return XFileServiceConstants.XFileCollectionName;
        }

        public override string GetInQuerySingleName()
        {
            return XFileServiceConstants.XFileSingleName;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphQuery.cs

using System;
using GraphQL.Types;
using xDataService.Configuration;
using xDataService.GraphQL;
using xFileService.Interfaces.Entities;
using xFileService.Models.Entities;

namespace xFileService.Providers.GraphQL
{
    public class XFileGraphQuery : XBaseGraphQLQuery<XFile, Guid, XFileGraphType, GuidGraphType>
    {
        public XFileGraphQuery(
            XDataServiceConfiguration configuration,
            IXFileRepository repository,
            IXFileGraphQLTypeHelper helper
        ) : base(
            configuration,
            repository,
            helper
        )
        { }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphSchema.cs

using System;
using GraphQL.Types;

namespace xFileService.Providers.GraphQL
{
    public class XFileGraphSchema : Schema
    {
        public XFileGraphSchema(IServiceProvider services) : base(services)
        {
            Query = (XFileGraphQuery)services.GetService(typeof(XFileGraphQuery));
        }

    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFileService\Providers\GraphQL\XFileGraphType.cs

using System;
using xDataService.GraphQL;
using xFileService.Models.Entities;

namespace xFileService.Providers.GraphQL
{
    public class XFileGraphType : XBaseGraphObjectType<XFile, Guid>
    {
        public XFileGraphType() : base()
        {
            Field(x => x.Type);
            Field(x => x.Name);
            Field(x => x.Path);
            Field(x => x.Thumb);
            Field(x => x.OwnerId);
            Field(x => x.FileName);
            Field(x => x.ThumbPath);
            Field(x => x.UploadedOn);
            Field(x => x.References);
        }
    }
}
