├── .gitattributes ├── .gitignore ├── README.md ├── SchoolProject.Api ├── Base │ └── AppControllerBase.cs ├── Controllers │ ├── ApplicationUserController.cs │ ├── AuthenticationController.cs │ ├── AuthorizationController.cs │ ├── DepartmentController.cs │ ├── EmailsController.cs │ ├── InstructorController.cs │ └── StudentController.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── SchoolProject.Api.csproj ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ └── Instructors │ ├── 33dc20a0b6e844d18da60711272ef70d.jpg │ └── de8d3ad754044450b87d7ed3a0c4d961.jfif ├── SchoolProject.Core ├── Bases │ ├── Response.cs │ └── ResponseHandler.cs ├── Behaviors │ └── ValidationBehavior.cs ├── Features │ ├── ApplicationUser │ │ ├── Commands │ │ │ ├── Handlers │ │ │ │ └── UserCommandHandler.cs │ │ │ ├── Models │ │ │ │ ├── AddUserCommand.cs │ │ │ │ ├── ChangeUserPasswordCommand.cs │ │ │ │ ├── DeleteUserCommand.cs │ │ │ │ └── EditUserCommand.cs │ │ │ └── Validatiors │ │ │ │ ├── AddUserValidator.cs │ │ │ │ ├── ChangeUserPasswordValidator.cs │ │ │ │ └── EditUserValidator.cs │ │ └── Queries │ │ │ ├── Handlers │ │ │ └── UserQueryHandler.cs │ │ │ ├── Models │ │ │ ├── GetUserByIdQuery.cs │ │ │ └── GetUserPaginationQuery.cs │ │ │ └── Results │ │ │ ├── GetUserByIdResponse.cs │ │ │ └── GetUserPaginationReponse.cs │ ├── Authentication │ │ ├── Commands │ │ │ ├── Handlers │ │ │ │ └── AuthenticationCommandHandler.cs │ │ │ ├── Models │ │ │ │ ├── RefreshTokenCommand.cs │ │ │ │ ├── ResetPasswordCommand.cs │ │ │ │ ├── SendResetPasswordCommand.cs │ │ │ │ └── SignInCommand.cs │ │ │ └── Validators │ │ │ │ ├── ResetPasswordValidator.cs │ │ │ │ ├── SendResetPasswordCommandValidator.cs │ │ │ │ └── SignInValidators.cs │ │ └── Queries │ │ │ ├── Handles │ │ │ └── AuthenticationQueryHandler.cs │ │ │ ├── Models │ │ │ ├── AuthorizeUserQuery.cs │ │ │ ├── ConfirmEmailQuery.cs │ │ │ └── ConfirmResetPasswordQuery.cs │ │ │ └── Validators │ │ │ ├── ConfirmEmailValidator.cs │ │ │ └── ConfirmResetPasswordQueryValidator.cs │ ├── Authorization │ │ ├── Commands │ │ │ ├── Handlers │ │ │ │ ├── ClaimsCommandHandler.cs │ │ │ │ └── RoleCommandHandler.cs │ │ │ ├── Models │ │ │ │ ├── AddRoleCommand.cs │ │ │ │ ├── DeleteRoleCommand.cs │ │ │ │ ├── EditRoleCommand.cs │ │ │ │ ├── UpdateUserClaimsCommand.cs │ │ │ │ └── UpdateUserRolesCommand.cs │ │ │ └── Validators │ │ │ │ ├── AddRoleValidators.cs │ │ │ │ ├── DeleteRoleValidator.cs │ │ │ │ └── EditRoleValidator.cs │ │ └── Quaries │ │ │ ├── Handlers │ │ │ ├── ClaimsQueryHandler.cs │ │ │ └── RoleQueryHandler.cs │ │ │ ├── Models │ │ │ ├── GetRoleByIdQuery.cs │ │ │ ├── GetRolesListQuery.cs │ │ │ ├── ManageUserClaimsQuery.cs │ │ │ └── ManageUserRolesQuery.cs │ │ │ └── Results │ │ │ ├── GetRoleByIdResult.cs │ │ │ └── GetRolesListResult.cs │ ├── Department │ │ └── Queries │ │ │ ├── Handlers │ │ │ └── DepartmentQueryHandler.cs │ │ │ ├── Models │ │ │ ├── GetDepartmentByIDQuery.cs │ │ │ ├── GetDepartmentStudentCountByIDQuery.cs │ │ │ └── GetDepartmentStudentListCountQuery.cs │ │ │ └── Results │ │ │ ├── GetDepartmentByIDResponse.cs │ │ │ ├── GetDepartmentStudentCountByIDResult.cs │ │ │ └── GetDepartmentStudentListCountResults.cs │ ├── Emails │ │ └── Commands │ │ │ ├── Handlers │ │ │ └── EmailsCommandHandler.cs │ │ │ ├── Models │ │ │ └── SendEmailCommand.cs │ │ │ └── Validators │ │ │ └── SendEmailValidator.cs │ ├── Instructors │ │ ├── Commands │ │ │ ├── Handlers │ │ │ │ └── InstructorCommandHandler.cs │ │ │ ├── Models │ │ │ │ └── AddInstructorCommand.cs │ │ │ └── Validatior │ │ │ │ └── AddInstructorValidator.cs │ │ └── Queries │ │ │ ├── Handlers │ │ │ └── InstructorQueryHandler.cs │ │ │ └── Models │ │ │ └── GetSummationSalaryOfInstructorQuery.cs │ └── Students │ │ ├── Commands │ │ ├── Handlers │ │ │ └── StudentCommandHandler.cs │ │ ├── Models │ │ │ ├── AddStudentCommand.cs │ │ │ ├── DeleteStudentCommand.cs │ │ │ └── EditStudentCommand.cs │ │ └── Validatiors │ │ │ ├── AddStudentValidator.cs │ │ │ └── EditStudentValidator.cs │ │ └── Queries │ │ ├── Handlers │ │ └── StudentQueryHandler.cs │ │ ├── Models │ │ ├── GetStudentByIDQuery.cs │ │ ├── GetStudentListQuery.cs │ │ └── GetStudentPaginatedListQuery.cs │ │ └── Results │ │ ├── GetSingleStudentResponse.cs │ │ ├── GetStudentListResponse.cs │ │ └── GetStudentPaginatedListResponse.cs ├── Filters │ └── AuthFilter.cs ├── Mapping │ ├── ApplicationUser │ │ ├── ApplicationUserProfile.cs │ │ ├── Commands │ │ │ ├── AddUserMapping.cs │ │ │ └── UpdateUserMapping.cs │ │ └── Queries │ │ │ ├── GetUserByIdMapping.cs │ │ │ └── GetUserPaginationMapping.cs │ ├── Departments │ │ ├── DepartmentProfile.cs │ │ └── QueriesMapping │ │ │ ├── GetDepartmentByIdMapping.cs │ │ │ ├── GetDepartmentStudentCountByIdMapping.cs │ │ │ └── GetDepartmentStudentCountMapping.cs │ ├── Instructors │ │ ├── Commands │ │ │ └── AddInstructorMapping.cs │ │ └── InstructorProfile.cs │ ├── Roles │ │ ├── Queries │ │ │ ├── GetRoleByIdMapping.cs │ │ │ └── GetRolesListMapping.cs │ │ └── RoleProfile.cs │ └── Students │ │ ├── CommandMapping │ │ ├── AddStudentCommandMapping.cs │ │ └── EditStudentCommandMapping.cs │ │ ├── QueryMapping │ │ ├── GetStudentByIDMapping.cs │ │ ├── GetStudentListMapping.cs │ │ └── GetStudentPaginationMapping.cs │ │ └── StudentProfile.cs ├── MiddleWare │ └── ErrorHandlerMiddleware.cs ├── ModuleCoreDependencies.cs ├── Resources │ ├── SharedResources.ar.resx │ ├── SharedResources.cs │ ├── SharedResources.en.resx │ └── SharedResourcesKeys.cs ├── SchoolProject.Core.csproj └── Wrappers │ ├── PaginatedResult.cs │ └── QueryableExtensions.cs ├── SchoolProject.Data ├── AppMetaData │ └── Router.cs ├── Class1.cs ├── Commons │ ├── GeneralLocalizableEntity.cs │ └── LocalizableEntity.cs ├── Entities │ ├── Department.cs │ ├── DepartmetSubject.cs │ ├── Identity │ │ ├── Role.cs │ │ ├── User.cs │ │ └── UserRefreshToken.cs │ ├── Ins_Subject.cs │ ├── Instructor.cs │ ├── Procedures │ │ └── DepartmentStudentCountProc.cs │ ├── Student.cs │ ├── StudentSubject.cs │ ├── Subject.cs │ └── Views │ │ └── ViewDepartment.cs ├── Enums │ └── StudentOrderingEnum.cs ├── Helpers │ ├── ClaimsStore.cs │ ├── EmailSettings.cs │ ├── JwtSettings.cs │ └── UserClaimModel.cs ├── Requests │ ├── EditRoleRequest.cs │ ├── UpdateUserClaimsRequest.cs │ └── UpdateUserRolesRequest.cs ├── Results │ ├── GetInstructorFunctionResult.cs │ ├── JwtAuthResult.cs │ ├── ManageUserClaimsResult.cs │ └── ManageUserRolesResult.cs └── SchoolProject.Data.csproj ├── SchoolProject.Infrustructure ├── Abstracts │ ├── Functions │ │ └── IInstructorFunctionsRepository.cs │ ├── IDepartmentRepository.cs │ ├── IInstructorsRepository.cs │ ├── IRefreshTokenRepository.cs │ ├── IStudentRepository.cs │ ├── ISubjectRepository.cs │ ├── Procedures │ │ └── IDepartmentStudentCountProcRepository.cs │ └── Views │ │ └── IViewRepository.cs ├── Configurations │ ├── DepartmentConfigurations.cs │ ├── DepartmentSubjectConfigurations.cs │ ├── Ins_SubjectConfigurations.cs │ ├── InstructorConfigurations.cs │ └── StudentSubjectConfigurations.cs ├── Context │ └── ApplicationDBContext.cs ├── InfrastructureBases │ ├── GenericRepositoryAsync.cs │ └── IGenericRepositoryAsync.cs ├── Migrations │ ├── 20230729085130_AddDatabaseTables.Designer.cs │ ├── 20230729085130_AddDatabaseTables.cs │ ├── 20230805113940_AddImageFieldInInstructortable.Designer.cs │ ├── 20230805113940_AddImageFieldInInstructortable.cs │ └── ApplicationDBContextModelSnapshot.cs ├── ModuleInfrastructureDependencies.cs ├── Repositories │ ├── DepartmentRepository.cs │ ├── Functions │ │ └── InstructorFunctionsRepository.cs │ ├── InstructorsRepository.cs │ ├── Procedures │ │ └── DepartmentStudentCountProcRepository.cs │ ├── RefreshTokenRepository.cs │ ├── StudentRepository.cs │ ├── SubjectRepository.cs │ └── Views │ │ └── ViewDepartmentRepository.cs ├── SchoolProject.Infrustructure.csproj ├── Seeder │ ├── RoleSeeder.cs │ └── UserSeeder.cs └── ServiceRegisteration.cs ├── SchoolProject.Service ├── Abstracts │ ├── IApplicationUserService.cs │ ├── IAuthenticationService.cs │ ├── IAuthorizationService.cs │ ├── IDepartmentService.cs │ ├── IEmailsService.cs │ ├── IFileService.cs │ ├── IInstructorService.cs │ └── IStudentService.cs ├── AuthServices │ ├── Implementations │ │ └── CurrentUserService.cs │ └── Interfaces │ │ └── ICurrentUserService.cs ├── Implementations │ ├── ApplicationUserService.cs │ ├── AuthenticationService.cs │ ├── AuthorizationService.cs │ ├── DepartmentService.cs │ ├── EmailsService.cs │ ├── FileService.cs │ ├── InstructorService.cs │ └── StudentService.cs ├── ModuleServiceDependencies.cs └── SchoolProject.Service.csproj ├── SchoolProject.XUnitTest ├── AssertTest.cs ├── CoreTests │ └── Students │ │ ├── Commands │ │ └── StudentCommandHandlerTest.cs │ │ └── Queries │ │ └── StudentQueryHandlerTest.cs ├── MoqOperationTest.cs ├── MoqTest │ ├── CarMoqService.cs │ └── ICarMoqService.cs ├── SchoolProject.XUnitTest.csproj ├── ServicesTest │ └── ExtensionMethod │ │ └── ExtensionMethodTest.cs ├── TestModels │ ├── Car.cs │ ├── PassDataToParamUsingMemberData.cs │ └── PassDataUsingClassData.cs ├── Usings.cs ├── Wrappers │ ├── Implementations │ │ └── PaginatedService.cs │ └── Interfaces │ │ └── IPaginatedService.cs └── xunit.runner.json └── SchoolProjectCleanArchitecture.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SchoolProjectInCleanArchitecture 2 | 3 | ## Description 4 | SchoolProject Using Asp.net Core Web Api Using Clean Architecture Based On Code First 5 | 6 | ### Components 7 | 8 | 1.CQRS Design Pattern 9 | 10 | 2.Generic(Repository) Design Pattern 11 | 12 | 3.Pagination Schema 13 | 14 | 4.Localizations Of Data And Responses 15 | 16 | 5.Fluent Validations 17 | 18 | 6.Configurations Using Data Annotations 19 | 20 | 7.Configurations using Fluent API 21 | 22 | 8.EndPoints Of Operations 23 | 24 | 9.Allow CORS 25 | 26 | 10.Using Identity 27 | 28 | 11.Added Authentication 29 | 30 | 12.Added JWT Token And SwaggerGen 31 | 32 | 13.Authorizations(Roles,Claims) 33 | 34 | 14.Service Like Send (Email,Upload Image) 35 | 36 | 15.Filters 37 | 38 | 16.Database Operations(Views,Procedures,Functions) Endpoint 39 | 40 | 17.Logs 41 | 42 | 18.Unit Test (XUnit) 43 | -------------------------------------------------------------------------------- /SchoolProject.Api/Base/AppControllerBase.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Core.Bases; 4 | using System.Net; 5 | 6 | namespace SchoolProject.Api.Base 7 | { 8 | [ApiController] 9 | public class AppControllerBase : ControllerBase 10 | { 11 | private IMediator _mediatorInstance; 12 | protected IMediator Mediator => _mediatorInstance ??= HttpContext.RequestServices.GetService(); 13 | 14 | #region Actions 15 | public ObjectResult NewResult(Response response) 16 | { 17 | switch (response.StatusCode) 18 | { 19 | case HttpStatusCode.OK: 20 | return new OkObjectResult(response); 21 | case HttpStatusCode.Created: 22 | return new CreatedResult(string.Empty, response); 23 | case HttpStatusCode.Unauthorized: 24 | return new UnauthorizedObjectResult(response); 25 | case HttpStatusCode.BadRequest: 26 | return new BadRequestObjectResult(response); 27 | case HttpStatusCode.NotFound: 28 | return new NotFoundObjectResult(response); 29 | case HttpStatusCode.Accepted: 30 | return new AcceptedResult(string.Empty, response); 31 | case HttpStatusCode.UnprocessableEntity: 32 | return new UnprocessableEntityObjectResult(response); 33 | default: 34 | return new BadRequestObjectResult(response); 35 | } 36 | } 37 | #endregion 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/ApplicationUserController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Api.Base; 4 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 5 | using SchoolProject.Core.Features.ApplicationUser.Queries.Models; 6 | using SchoolProject.Data.AppMetaData; 7 | namespace SchoolProject.Api.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | [Authorize(Roles = "Admin,User")] 12 | public class ApplicationUserController : AppControllerBase 13 | { 14 | [HttpPost(Router.ApplicationUserRouting.Create)] 15 | public async Task Create([FromBody] AddUserCommand command) 16 | { 17 | var response = await Mediator.Send(command); 18 | return NewResult(response); 19 | } 20 | [HttpGet(Router.ApplicationUserRouting.Paginated)] 21 | public async Task Paginated([FromQuery] GetUserPaginationQuery query) 22 | { 23 | var response = await Mediator.Send(query); 24 | return Ok(response); 25 | } 26 | [HttpGet(Router.ApplicationUserRouting.GetByID)] 27 | public async Task GetStudentByID([FromRoute] int id) 28 | { 29 | return NewResult(await Mediator.Send(new GetUserByIdQuery(id))); 30 | } 31 | [HttpPut(Router.ApplicationUserRouting.Edit)] 32 | public async Task Edit([FromBody] EditUserCommand command) 33 | { 34 | var response = await Mediator.Send(command); 35 | return NewResult(response); 36 | } 37 | [HttpDelete(Router.ApplicationUserRouting.Delete)] 38 | public async Task Delete([FromRoute] int id) 39 | { 40 | return NewResult(await Mediator.Send(new DeleteUserCommand(id))); 41 | } 42 | [HttpPut(Router.ApplicationUserRouting.ChangePassword)] 43 | public async Task ChangePassword([FromBody] ChangeUserPasswordCommand command) 44 | { 45 | var response = await Mediator.Send(command); 46 | return NewResult(response); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/AuthenticationController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using SchoolProject.Api.Base; 3 | using SchoolProject.Core.Features.Authentication.Commands.Models; 4 | using SchoolProject.Core.Features.Authentication.Queries.Models; 5 | using SchoolProject.Data.AppMetaData; 6 | 7 | namespace SchoolProject.Api.Controllers 8 | { 9 | 10 | [ApiController] 11 | 12 | public class AuthenticationController : AppControllerBase 13 | { 14 | 15 | [HttpPost(Router.Authentication.SignIn)] 16 | public async Task Create([FromForm] SignInCommand command) 17 | { 18 | var response = await Mediator.Send(command); 19 | return NewResult(response); 20 | } 21 | 22 | [HttpPost(Router.Authentication.RefreshToken)] 23 | public async Task RefreshToken([FromForm] RefreshTokenCommand command) 24 | { 25 | var response = await Mediator.Send(command); 26 | return NewResult(response); 27 | } 28 | [HttpGet(Router.Authentication.ValidateToken)] 29 | public async Task ValidateToken([FromQuery] AuthorizeUserQuery query) 30 | { 31 | var response = await Mediator.Send(query); 32 | return NewResult(response); 33 | } 34 | [HttpGet(Router.Authentication.ConfirmEmail)] 35 | public async Task ConfirmEmail([FromQuery] ConfirmEmailQuery query) 36 | { 37 | var response = await Mediator.Send(query); 38 | return NewResult(response); 39 | } 40 | [HttpPost(Router.Authentication.SendResetPasswordCode)] 41 | public async Task SendResetPassword([FromQuery] SendResetPasswordCommand command) 42 | { 43 | var response = await Mediator.Send(command); 44 | return NewResult(response); 45 | } 46 | [HttpGet(Router.Authentication.ConfirmResetPasswordCode)] 47 | public async Task ConfirmResetPassword([FromQuery] ConfirmResetPasswordQuery query) 48 | { 49 | var response = await Mediator.Send(query); 50 | return NewResult(response); 51 | } 52 | [HttpPost(Router.Authentication.ResetPassword)] 53 | public async Task ResetPassword([FromForm] ResetPasswordCommand command) 54 | { 55 | var response = await Mediator.Send(command); 56 | return NewResult(response); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/AuthorizationController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Api.Base; 4 | using SchoolProject.Core.Features.Authorization.Commands.Models; 5 | using SchoolProject.Core.Features.Authorization.Quaries.Models; 6 | using SchoolProject.Data.AppMetaData; 7 | using Swashbuckle.AspNetCore.Annotations; 8 | namespace SchoolProject.Api.Controllers 9 | { 10 | [ApiController] 11 | [Authorize(Roles = "Admin")] 12 | public class AuthorizationController : AppControllerBase 13 | { 14 | [HttpPost(Router.AuthorizationRouting.Create)] 15 | public async Task Create([FromForm] AddRoleCommand command) 16 | { 17 | var response = await Mediator.Send(command); 18 | return NewResult(response); 19 | } 20 | [HttpPost(Router.AuthorizationRouting.Edit)] 21 | public async Task Edit([FromForm] EditRoleCommand command) 22 | { 23 | var response = await Mediator.Send(command); 24 | return NewResult(response); 25 | } 26 | [HttpDelete(Router.AuthorizationRouting.Delete)] 27 | public async Task Delete([FromRoute] int id) 28 | { 29 | var response = await Mediator.Send(new DeleteRoleCommand(id)); 30 | return NewResult(response); 31 | } 32 | [HttpGet(Router.AuthorizationRouting.RoleList)] 33 | public async Task GetRoleList() 34 | { 35 | var response = await Mediator.Send(new GetRolesListQuery()); 36 | return NewResult(response); 37 | } 38 | [SwaggerOperation(Summary = "idالصلاحية عن طريق ال", OperationId = "RoleById")] 39 | [HttpGet(Router.AuthorizationRouting.GetRoleById)] 40 | public async Task GetRoleById([FromRoute] int id) 41 | { 42 | var response = await Mediator.Send(new GetRoleByIdQuery() { Id=id }); 43 | return NewResult(response); 44 | } 45 | [SwaggerOperation(Summary = " ادارة صلاحيات المستخدمين", OperationId = "ManageUserRoles")] 46 | [HttpGet(Router.AuthorizationRouting.ManageUserRoles)] 47 | public async Task ManageUserRoles([FromRoute] int userId) 48 | { 49 | var response = await Mediator.Send(new ManageUserRolesQuery() { UserId=userId }); 50 | return NewResult(response); 51 | } 52 | [SwaggerOperation(Summary = " تعديل صلاحيات المستخدمين", OperationId = "UpdateUserRoles")] 53 | [HttpPut(Router.AuthorizationRouting.UpdateUserRoles)] 54 | public async Task UpdateUserRoles([FromBody] UpdateUserRolesCommand command) 55 | { 56 | var response = await Mediator.Send(command); 57 | return NewResult(response); 58 | } 59 | [SwaggerOperation(Summary = " ادارة صلاحيات الاستخدام المستخدمين", OperationId = "ManageUserClaims")] 60 | [HttpGet(Router.AuthorizationRouting.ManageUserClaims)] 61 | public async Task ManageUserClaims([FromRoute] int userId) 62 | { 63 | var response = await Mediator.Send(new ManageUserClaimsQuery() { UserId=userId }); 64 | return NewResult(response); 65 | } 66 | [SwaggerOperation(Summary = " تعديل صلاحيات الاستخدام المستخدمين", OperationId = "UpdateUserClaims")] 67 | [HttpPut(Router.AuthorizationRouting.UpdateUserClaims)] 68 | public async Task UpdateUserClaims([FromBody] UpdateUserClaimsCommand command) 69 | { 70 | var response = await Mediator.Send(command); 71 | return NewResult(response); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/DepartmentController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Api.Base; 4 | using SchoolProject.Core.Features.Department.Queries.Models; 5 | using SchoolProject.Data.AppMetaData; 6 | 7 | namespace SchoolProject.Api.Controllers 8 | { 9 | [ApiController] 10 | [Authorize(Roles = "Admin")] 11 | public class DepartmentController : AppControllerBase 12 | { 13 | [HttpGet(Router.DepartmentRouting.GetByID)] 14 | public async Task GetDepartmentByID([FromQuery] GetDepartmentByIDQuery query) 15 | { 16 | return NewResult(await Mediator.Send(query)); 17 | } 18 | [HttpGet(Router.DepartmentRouting.GetDepartmentStudentsCount)] 19 | public async Task GetDepartmentStudentsCount() 20 | { 21 | return NewResult(await Mediator.Send(new GetDepartmentStudentListCountQuery())); 22 | } 23 | 24 | [HttpGet(Router.DepartmentRouting.GetDepartmentStudentsCountById)] 25 | public async Task GetDepartmentStudentsCountById([FromRoute] int id) 26 | { 27 | return NewResult(await Mediator.Send(new GetDepartmentStudentCountByIDQuery() { DID=id })); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/EmailsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Api.Base; 4 | using SchoolProject.Core.Features.Emails.Commands.Models; 5 | using SchoolProject.Data.AppMetaData; 6 | 7 | namespace SchoolProject.Api.Controllers 8 | { 9 | [ApiController] 10 | [Authorize(Roles = "Admin,User")] 11 | public class EmailsController : AppControllerBase 12 | { 13 | [HttpPost(Router.EmailsRoute.SendEmail)] 14 | public async Task SendEmail([FromQuery] SendEmailCommand command) 15 | { 16 | var response = await Mediator.Send(command); 17 | return NewResult(response); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/InstructorController.cs: -------------------------------------------------------------------------------- 1 |  2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Mvc; 4 | using SchoolProject.Api.Base; 5 | using SchoolProject.Core.Features.Instructors.Commands.Models; 6 | using SchoolProject.Core.Features.Instructors.Queries.Models; 7 | using SchoolProject.Data.AppMetaData; 8 | namespace SchoolProject.Api.Controllers 9 | { 10 | [ApiController] 11 | [Authorize(Roles = "Admin")] 12 | public class InstructorController : AppControllerBase 13 | { 14 | [HttpGet(Router.InstructorRouting.GetSalarySummationOfInstructor)] 15 | public async Task GetSalarySummation() 16 | { 17 | return NewResult(await Mediator.Send(new GetSummationSalaryOfInstructorQuery())); 18 | } 19 | [HttpPost(Router.InstructorRouting.AddInstructor)] 20 | public async Task AddInstructor([FromForm] AddInstructorCommand command) 21 | { 22 | return NewResult(await Mediator.Send(command)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SchoolProject.Api/Controllers/StudentController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using SchoolProject.Api.Base; 4 | using SchoolProject.Core.Features.Students.Commands.Models; 5 | using SchoolProject.Core.Features.Students.Queries.Models; 6 | using SchoolProject.Core.Filters; 7 | using SchoolProject.Data.AppMetaData; 8 | 9 | namespace SchoolProject.Api.Controllers 10 | { 11 | [ApiController] 12 | [Authorize(Roles = "Admin,User")] 13 | public class StudentController : AppControllerBase 14 | { 15 | [HttpGet(Router.StudentRouting.List)] 16 | [Authorize(Roles = "User")] 17 | [ServiceFilter(typeof(AuthFilter))] 18 | public async Task GetStudentList() 19 | { 20 | var response = await Mediator.Send(new GetStudentListQuery()); 21 | return Ok(response); 22 | } 23 | [AllowAnonymous] 24 | [HttpGet(Router.StudentRouting.Paginated)] 25 | public async Task Paginated([FromQuery] GetStudentPaginatedListQuery query) 26 | { 27 | var response = await Mediator.Send(query); 28 | return Ok(response); 29 | } 30 | [HttpGet(Router.StudentRouting.GetByID)] 31 | public async Task GetStudentByID([FromRoute] int id) 32 | { 33 | return NewResult(await Mediator.Send(new GetStudentByIDQuery(id))); 34 | } 35 | [Authorize(Policy = "CreateStudent")] 36 | [HttpPost(Router.StudentRouting.Create)] 37 | public async Task Create([FromBody] AddStudentCommand command) 38 | { 39 | var response = await Mediator.Send(command); 40 | return NewResult(response); 41 | } 42 | [Authorize(Policy = "EditStudent")] 43 | [HttpPut(Router.StudentRouting.Edit)] 44 | public async Task Edit([FromBody] EditStudentCommand command) 45 | { 46 | var response = await Mediator.Send(command); 47 | return NewResult(response); 48 | } 49 | [Authorize(Policy = "DeleteStudent")] 50 | [HttpDelete(Router.StudentRouting.Delete)] 51 | public async Task Delete([FromRoute] int id) 52 | { 53 | return NewResult(await Mediator.Send(new DeleteStudentCommand(id))); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SchoolProject.Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:14976", 8 | "sslPort": 44393 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5167", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7089;http://localhost:5167", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SchoolProject.Api/SchoolProject.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /SchoolProject.Api/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "dbcontext": "data source=DESKTOP-CG26CQA\\SQLEXPRESS;integrated security=SSPI;initial catalog=SchoolDatabase;trustservercertificate=True;" 11 | }, 12 | "jwtSettings": { 13 | "secret": "SchoolProjectCleanArchitectureKey", 14 | "issuer": "SchoolProject", 15 | "audience": "WebSite", 16 | "validateAudience": true, 17 | "validateIssuer": true, 18 | "validateLifetime": true, 19 | "validateIssuerSigningKey": true, 20 | "AccessTokenExpireDate": 1, 21 | "RefreshTokenExpireDate": 20 22 | }, 23 | "emailSettings": { 24 | "port": "465", 25 | "host": "smtp.gmail.com", 26 | "FromEmail": "mofouad820@gmail.com", 27 | "password": "xxxxx" 28 | 29 | }, 30 | "Serilog": { 31 | "Using": [ "Serilog.Sinks.MSSqlServer", "Serilog.Sinks.Console" ], 32 | "MinimumLevel": { 33 | "Default": "Information", 34 | "override": { 35 | "Microsoft": "Error" 36 | } 37 | }, 38 | "WriteTo": [ 39 | { 40 | "Name": "Console" 41 | }, 42 | { 43 | "Name": "MSSqlServer", 44 | "Args": { 45 | "ConnectionString": "data source=DESKTOP-CG26CQA\\SQLEXPRESS;integrated security=SSPI;initial catalog=SchoolDatabase;trustservercertificate=True;", 46 | "TableName": "SystemLogs", 47 | "autoCreateSqlTable": true 48 | } 49 | } 50 | 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SchoolProject.Api/wwwroot/Instructors/33dc20a0b6e844d18da60711272ef70d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/engMohamedFouad/SchoolProjectCleanArchitecture/9af6bb000ee916c7a2aa461253c9f781b366bf1d/SchoolProject.Api/wwwroot/Instructors/33dc20a0b6e844d18da60711272ef70d.jpg -------------------------------------------------------------------------------- /SchoolProject.Api/wwwroot/Instructors/de8d3ad754044450b87d7ed3a0c4d961.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/engMohamedFouad/SchoolProjectCleanArchitecture/9af6bb000ee916c7a2aa461253c9f781b366bf1d/SchoolProject.Api/wwwroot/Instructors/de8d3ad754044450b87d7ed3a0c4d961.jfif -------------------------------------------------------------------------------- /SchoolProject.Core/Bases/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace SchoolProject.Core.Bases 4 | { 5 | public class Response 6 | { 7 | public Response() 8 | { 9 | 10 | } 11 | public Response(T data, string message = null) 12 | { 13 | Succeeded = true; 14 | Message = message; 15 | Data = data; 16 | } 17 | public Response(string message) 18 | { 19 | Succeeded = false; 20 | Message = message; 21 | } 22 | public Response(string message, bool succeeded) 23 | { 24 | Succeeded = succeeded; 25 | Message = message; 26 | } 27 | 28 | public HttpStatusCode StatusCode { get; set; } 29 | public object Meta { get; set; } 30 | 31 | public bool Succeeded { get; set; } 32 | public string Message { get; set; } 33 | public List Errors { get; set; } 34 | //public Dictionary> ErrorsBag { get; set; } 35 | public T Data { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SchoolProject.Core/Bases/ResponseHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Localization; 2 | using SchoolProject.Core.Resources; 3 | 4 | namespace SchoolProject.Core.Bases 5 | { 6 | public class ResponseHandler 7 | { 8 | private readonly IStringLocalizer _stringLocalizer; 9 | public ResponseHandler(IStringLocalizer stringLocalizer) 10 | { 11 | _stringLocalizer= stringLocalizer; 12 | } 13 | public Response Deleted(string Message = null) 14 | { 15 | return new Response() 16 | { 17 | StatusCode = System.Net.HttpStatusCode.OK, 18 | Succeeded = true, 19 | Message = Message == null ? _stringLocalizer[SharedResourcesKeys.Deleted] : Message 20 | }; 21 | } 22 | public Response Success(T entity, object Meta = null) 23 | { 24 | return new Response() 25 | { 26 | Data = entity, 27 | StatusCode = System.Net.HttpStatusCode.OK, 28 | Succeeded = true, 29 | Message = _stringLocalizer[SharedResourcesKeys.Success], 30 | Meta = Meta 31 | }; 32 | } 33 | public Response Unauthorized(string Message = null) 34 | { 35 | return new Response() 36 | { 37 | StatusCode = System.Net.HttpStatusCode.Unauthorized, 38 | Succeeded = true, 39 | Message = Message == null ? _stringLocalizer[SharedResourcesKeys.UnAuthorized] : Message 40 | }; 41 | } 42 | public Response BadRequest(string Message = null) 43 | { 44 | return new Response() 45 | { 46 | StatusCode = System.Net.HttpStatusCode.BadRequest, 47 | Succeeded = false, 48 | Message = Message == null ? _stringLocalizer[SharedResourcesKeys.BadRequest] : Message 49 | }; 50 | } 51 | 52 | public Response UnprocessableEntity(string Message = null) 53 | { 54 | return new Response() 55 | { 56 | StatusCode = System.Net.HttpStatusCode.UnprocessableEntity, 57 | Succeeded = false, 58 | Message = Message == null ? _stringLocalizer[SharedResourcesKeys.UnprocessableEntity] : Message 59 | }; 60 | } 61 | 62 | 63 | public Response NotFound(string message = null) 64 | { 65 | return new Response() 66 | { 67 | StatusCode = System.Net.HttpStatusCode.NotFound, 68 | Succeeded = false, 69 | Message = message == null ? _stringLocalizer[SharedResourcesKeys.NotFound] : message 70 | }; 71 | } 72 | 73 | public Response Created(T entity, object Meta = null) 74 | { 75 | return new Response() 76 | { 77 | Data = entity, 78 | StatusCode = System.Net.HttpStatusCode.Created, 79 | Succeeded = true, 80 | Message = _stringLocalizer[SharedResourcesKeys.Created], 81 | Meta = Meta 82 | }; 83 | } 84 | } 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /SchoolProject.Core/Behaviors/ValidationBehavior.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using MediatR; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Behaviors 7 | { 8 | public class ValidationBehavior : IPipelineBehavior 9 | where TRequest : IRequest 10 | { 11 | private readonly IEnumerable> _validators; 12 | private readonly IStringLocalizer _localizer; 13 | public ValidationBehavior(IEnumerable> validators, IStringLocalizer localizer) 14 | { 15 | _validators = validators; 16 | _localizer = localizer; 17 | } 18 | public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) 19 | { 20 | if (_validators.Any()) 21 | { 22 | var context = new ValidationContext(request); 23 | var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); 24 | var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList(); 25 | 26 | if (failures.Count != 0) 27 | { 28 | var message = failures.Select(x => _localizer[$"{x.PropertyName}"]+":"+_localizer[x.ErrorMessage]).FirstOrDefault(); 29 | 30 | throw new ValidationException(message); 31 | 32 | } 33 | } 34 | return await next(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Models/AddUserCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Models 5 | { 6 | public class AddUserCommand : IRequest> 7 | { 8 | public string FullName { get; set; } 9 | public string UserName { get; set; } 10 | public string Email { get; set; } 11 | public string? Address { get; set; } 12 | public string? Country { get; set; } 13 | public string? PhoneNumber { get; set; } 14 | public string Password { get; set; } 15 | public string ConfirmPassword { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Models/ChangeUserPasswordCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Models 5 | { 6 | public class ChangeUserPasswordCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public string CurrentPassword { get; set; } 10 | public string NewPassword { get; set; } 11 | public string ConfirmPassword { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Models/DeleteUserCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Models 5 | { 6 | public class DeleteUserCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public DeleteUserCommand(int id) 10 | { 11 | Id = id; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Models/EditUserCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Models 5 | { 6 | public class EditUserCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public string FullName { get; set; } 10 | public string UserName { get; set; } 11 | public string Email { get; set; } 12 | public string? Address { get; set; } 13 | public string? Country { get; set; } 14 | public string? PhoneNumber { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Validatiors/AddUserValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Validatiors 7 | { 8 | public class AddUserValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public AddUserValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Handle Functions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.FullName) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 29 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 30 | 31 | RuleFor(x => x.UserName) 32 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 33 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 34 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 35 | 36 | RuleFor(x => x.Email) 37 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 38 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 39 | RuleFor(x => x.Password) 40 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 41 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 42 | RuleFor(x => x.ConfirmPassword) 43 | .Equal(x => x.Password).WithMessage(_localizer[SharedResourcesKeys.PasswordNotEqualConfirmPass]); 44 | 45 | } 46 | 47 | public void ApplyCustomValidationsRules() 48 | { 49 | 50 | } 51 | 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Validatiors/ChangeUserPasswordValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Validatiors 7 | { 8 | public class ChangeUserPasswordValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public ChangeUserPasswordValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Handle Functions 24 | public void ApplyValidationsRules() 25 | { 26 | 27 | RuleFor(x => x.Id) 28 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 29 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 30 | 31 | RuleFor(x => x.CurrentPassword) 32 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 33 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 34 | RuleFor(x => x.NewPassword) 35 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 36 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 37 | RuleFor(x => x.ConfirmPassword) 38 | .Equal(x => x.NewPassword).WithMessage(_localizer[SharedResourcesKeys.PasswordNotEqualConfirmPass]); 39 | 40 | } 41 | 42 | public void ApplyCustomValidationsRules() 43 | { 44 | 45 | } 46 | 47 | #endregion 48 | } 49 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Commands/Validatiors/EditUserValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.ApplicationUser.Commands.Validatiors 7 | { 8 | public class EditUserValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public EditUserValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Handle Functions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.FullName) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 29 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 30 | 31 | RuleFor(x => x.UserName) 32 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 33 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 34 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 35 | 36 | RuleFor(x => x.Email) 37 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 38 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 39 | } 40 | 41 | public void ApplyCustomValidationsRules() 42 | { 43 | 44 | } 45 | 46 | #endregion 47 | } 48 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Queries/Handlers/UserQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.AspNetCore.Identity; 4 | using Microsoft.Extensions.Localization; 5 | using SchoolProject.Core.Bases; 6 | using SchoolProject.Core.Features.ApplicationUser.Queries.Models; 7 | using SchoolProject.Core.Features.ApplicationUser.Queries.Results; 8 | using SchoolProject.Core.Resources; 9 | using SchoolProject.Core.Wrappers; 10 | using SchoolProject.Data.Entities.Identity; 11 | 12 | namespace SchoolProject.Core.Features.ApplicationUser.Queries.Handlers 13 | { 14 | public class UserQueryHandler : ResponseHandler, 15 | IRequestHandler>, 16 | IRequestHandler> 17 | { 18 | #region Fields 19 | private readonly IMapper _mapper; 20 | private readonly IStringLocalizer _sharedResources; 21 | private readonly UserManager _userManager; 22 | #endregion 23 | 24 | #region Constructors 25 | public UserQueryHandler(IStringLocalizer stringLocalizer, 26 | IMapper mapper, 27 | UserManager userManager) : base(stringLocalizer) 28 | { 29 | _mapper = mapper; 30 | _sharedResources = stringLocalizer; 31 | _userManager= userManager; 32 | } 33 | #endregion 34 | 35 | #region Handle Functions 36 | public async Task> Handle(GetUserPaginationQuery request, CancellationToken cancellationToken) 37 | { 38 | var users = _userManager.Users.AsQueryable(); 39 | var paginatedList = await _mapper.ProjectTo(users) 40 | .ToPaginatedListAsync(request.PageNumber, request.PageSize); 41 | return paginatedList; 42 | } 43 | 44 | public async Task> Handle(GetUserByIdQuery request, CancellationToken cancellationToken) 45 | { 46 | //var user = await _userManager.Users.FirstOrDefaultAsync(x => x.Id==request.Id); 47 | var user = await _userManager.FindByIdAsync(request.Id.ToString()); 48 | if (user==null) return NotFound(_sharedResources[SharedResourcesKeys.NotFound]); 49 | var result = _mapper.Map(user); 50 | return Success(result); 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Queries/Models/GetUserByIdQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.ApplicationUser.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.ApplicationUser.Queries.Models 6 | { 7 | public class GetUserByIdQuery : IRequest> 8 | { 9 | public int Id { get; set; } 10 | public GetUserByIdQuery(int id) 11 | { 12 | Id = id; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Queries/Models/GetUserPaginationQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Features.ApplicationUser.Queries.Results; 3 | using SchoolProject.Core.Wrappers; 4 | 5 | namespace SchoolProject.Core.Features.ApplicationUser.Queries.Models 6 | { 7 | public class GetUserPaginationQuery : IRequest> 8 | { 9 | public int PageNumber { get; set; } 10 | public int PageSize { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Queries/Results/GetUserByIdResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.ApplicationUser.Queries.Results 2 | { 3 | public class GetUserByIdResponse 4 | { 5 | public string FullName { get; set; } 6 | public string Email { get; set; } 7 | public string? Address { get; set; } 8 | public string? Country { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/ApplicationUser/Queries/Results/GetUserPaginationReponse.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.ApplicationUser.Queries.Results 2 | { 3 | public class GetUserPaginationReponse 4 | { 5 | public string FullName { get; set; } 6 | public string Email { get; set; } 7 | public string? Address { get; set; } 8 | public string? Country { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Models/RefreshTokenCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.Results; 4 | 5 | namespace SchoolProject.Core.Features.Authentication.Commands.Models 6 | { 7 | public class RefreshTokenCommand : IRequest> 8 | { 9 | public string AccessToken { get; set; } 10 | public string RefreshToken { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Models/ResetPasswordCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authentication.Commands.Models 5 | { 6 | public class ResetPasswordCommand : IRequest> 7 | { 8 | public string Email { get; set; } 9 | public string Password { get; set; } 10 | public string ConfirmPassword { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Models/SendResetPasswordCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authentication.Commands.Models 5 | { 6 | public class SendResetPasswordCommand : IRequest> 7 | { 8 | public string Email { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Models/SignInCommand.cs: -------------------------------------------------------------------------------- 1 |  2 | using MediatR; 3 | using SchoolProject.Core.Bases; 4 | using SchoolProject.Data.Results; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Commands.Models 7 | { 8 | public class SignInCommand : IRequest> 9 | { 10 | public string UserName { get; set; } 11 | public string Password { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Validators/ResetPasswordValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authentication.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Commands.Validators 7 | { 8 | public class ResetPasswordValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public ResetPasswordValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Handle Functions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.Email) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 29 | RuleFor(x => x.Password) 30 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 31 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 32 | RuleFor(x => x.ConfirmPassword) 33 | .Equal(x => x.Password).WithMessage(_localizer[SharedResourcesKeys.PasswordNotEqualConfirmPass]); 34 | 35 | } 36 | 37 | public void ApplyCustomValidationsRules() 38 | { 39 | 40 | } 41 | 42 | #endregion 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Validators/SendResetPasswordCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authentication.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Commands.Validators 7 | { 8 | public class SendResetPasswordCommandValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public SendResetPasswordCommandValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Actions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.Email) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 29 | 30 | 31 | } 32 | 33 | public void ApplyCustomValidationsRules() 34 | { 35 | } 36 | 37 | #endregion 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Commands/Validators/SignInValidators.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authentication.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Commands.Validators 7 | { 8 | public class SignInValidators : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public SignInValidators(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Actions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.UserName) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 29 | 30 | RuleFor(x => x.Password) 31 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 32 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 33 | } 34 | 35 | public void ApplyCustomValidationsRules() 36 | { 37 | } 38 | 39 | #endregion 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Handles/AuthenticationQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Bases; 4 | using SchoolProject.Core.Features.Authentication.Queries.Models; 5 | using SchoolProject.Core.Resources; 6 | using SchoolProject.Service.Abstracts; 7 | 8 | namespace SchoolProject.Core.Features.Authentication.Queries.Handles 9 | { 10 | public class AuthenticationQueryHandler : ResponseHandler, 11 | IRequestHandler>, 12 | IRequestHandler>, 13 | IRequestHandler> 14 | { 15 | 16 | 17 | #region Fields 18 | private readonly IStringLocalizer _stringLocalizer; 19 | private readonly IAuthenticationService _authenticationService; 20 | 21 | #endregion 22 | 23 | #region Constructors 24 | public AuthenticationQueryHandler(IStringLocalizer stringLocalizer, 25 | IAuthenticationService authenticationService) : base(stringLocalizer) 26 | { 27 | _stringLocalizer=stringLocalizer; 28 | _authenticationService=authenticationService; 29 | } 30 | 31 | 32 | #endregion 33 | 34 | #region Handle Functions 35 | public async Task> Handle(AuthorizeUserQuery request, CancellationToken cancellationToken) 36 | { 37 | var result = await _authenticationService.ValidateToken(request.AccessToken); 38 | if (result=="NotExpired") 39 | return Success(result); 40 | return Unauthorized(_stringLocalizer[SharedResourcesKeys.TokenIsExpired]); 41 | } 42 | 43 | public async Task> Handle(ConfirmEmailQuery request, CancellationToken cancellationToken) 44 | { 45 | var confirmEmail = await _authenticationService.ConfirmEmail(request.UserId, request.Code); 46 | if (confirmEmail=="ErrorWhenConfirmEmail") 47 | return BadRequest(_stringLocalizer[SharedResourcesKeys.ErrorWhenConfirmEmail]); 48 | return Success(_stringLocalizer[SharedResourcesKeys.ConfirmEmailDone]); 49 | } 50 | 51 | public async Task> Handle(ConfirmResetPasswordQuery request, CancellationToken cancellationToken) 52 | { 53 | var result = await _authenticationService.ConfirmResetPassword(request.Code, request.Email); 54 | switch (result) 55 | { 56 | case "UserNotFound": return BadRequest(_stringLocalizer[SharedResourcesKeys.UserIsNotFound]); 57 | case "Failed": return BadRequest(_stringLocalizer[SharedResourcesKeys.InvaildCode]); 58 | case "Success": return Success(""); 59 | default: return BadRequest(_stringLocalizer[SharedResourcesKeys.InvaildCode]); 60 | } 61 | } 62 | #endregion 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Models/AuthorizeUserQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authentication.Queries.Models 5 | { 6 | public class AuthorizeUserQuery : IRequest> 7 | { 8 | public string AccessToken { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Models/ConfirmEmailQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authentication.Queries.Models 5 | { 6 | public class ConfirmEmailQuery : IRequest> 7 | { 8 | public int UserId { get; set; } 9 | public string Code { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Models/ConfirmResetPasswordQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authentication.Queries.Models 5 | { 6 | public class ConfirmResetPasswordQuery : IRequest> 7 | { 8 | public string Code { get; set; } 9 | public string Email { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Validators/ConfirmEmailValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authentication.Queries.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Queries.Validators 7 | { 8 | public class ConfirmEmailValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public ConfirmEmailValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Actions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.UserId) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 29 | 30 | RuleFor(x => x.Code) 31 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 32 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 33 | } 34 | 35 | public void ApplyCustomValidationsRules() 36 | { 37 | } 38 | 39 | #endregion 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authentication/Queries/Validators/ConfirmResetPasswordQueryValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authentication.Queries.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authentication.Commands.Validators 7 | { 8 | public class ConfirmResetPasswordQueryValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | 14 | #region Constructors 15 | public ConfirmResetPasswordQueryValidator(IStringLocalizer localizer) 16 | { 17 | _localizer = localizer; 18 | ApplyValidationsRules(); 19 | ApplyCustomValidationsRules(); 20 | } 21 | #endregion 22 | 23 | #region Actions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.Code) 27 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 29 | RuleFor(x => x.Email) 30 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 31 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 32 | 33 | } 34 | 35 | public void ApplyCustomValidationsRules() 36 | { 37 | } 38 | 39 | #endregion 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Handlers/ClaimsCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Bases; 4 | using SchoolProject.Core.Features.Authorization.Commands.Models; 5 | using SchoolProject.Core.Resources; 6 | using SchoolProject.Service.Abstracts; 7 | 8 | namespace SchoolProject.Core.Features.Authorization.Commands.Handlers 9 | { 10 | public class ClaimsCommandHandler : ResponseHandler, 11 | IRequestHandler> 12 | { 13 | #region Fileds 14 | private readonly IStringLocalizer _stringLocalizer; 15 | private readonly IAuthorizationService _authorizationService; 16 | 17 | #endregion 18 | #region Constructors 19 | public ClaimsCommandHandler(IStringLocalizer stringLocalizer, 20 | IAuthorizationService authorizationService) : base(stringLocalizer) 21 | { 22 | _authorizationService= authorizationService; 23 | _stringLocalizer = stringLocalizer; 24 | } 25 | #endregion 26 | #region Handle Functions 27 | public async Task> Handle(UpdateUserClaimsCommand request, CancellationToken cancellationToken) 28 | { 29 | var result = await _authorizationService.UpdateUserClaims(request); 30 | switch (result) 31 | { 32 | case "UserIsNull": return NotFound(_stringLocalizer[SharedResourcesKeys.UserIsNotFound]); 33 | case "FailedToRemoveOldClaims": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToRemoveOldClaims]); 34 | case "FailedToAddNewClaims": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToAddNewClaims]); 35 | case "FailedToUpdateClaims": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToUpdateClaims]); 36 | } 37 | return Success(_stringLocalizer[SharedResourcesKeys.Success]); 38 | } 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Handlers/RoleCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Bases; 4 | using SchoolProject.Core.Features.Authorization.Commands.Models; 5 | using SchoolProject.Core.Resources; 6 | using SchoolProject.Service.Abstracts; 7 | namespace SchoolProject.Core.Features.Authorization.Commands.Handlers 8 | { 9 | public class RoleCommandHandler : ResponseHandler, 10 | IRequestHandler>, 11 | IRequestHandler>, 12 | IRequestHandler>, 13 | IRequestHandler> 14 | { 15 | #region MyRegion 16 | private readonly IStringLocalizer _stringLocalizer; 17 | private readonly IAuthorizationService _authorizationService; 18 | 19 | #endregion 20 | #region MyRegion 21 | public RoleCommandHandler(IStringLocalizer stringLocalizer, 22 | IAuthorizationService authorizationService) : base(stringLocalizer) 23 | { 24 | _stringLocalizer = stringLocalizer; 25 | _authorizationService = authorizationService; 26 | } 27 | 28 | #endregion 29 | #region MyRegion 30 | public async Task> Handle(AddRoleCommand request, CancellationToken cancellationToken) 31 | { 32 | var result = await _authorizationService.AddRoleAsync(request.RoleName); 33 | if (result=="Success") return Success(""); 34 | return BadRequest(_stringLocalizer[SharedResourcesKeys.AddFailed]); 35 | } 36 | 37 | public async Task> Handle(EditRoleCommand request, CancellationToken cancellationToken) 38 | { 39 | var result = await _authorizationService.EditRoleAsync(request); 40 | if (result=="notFound") return NotFound(); 41 | else if (result=="Success") return Success((string)_stringLocalizer[SharedResourcesKeys.Updated]); 42 | else 43 | return BadRequest(result); 44 | } 45 | 46 | public async Task> Handle(DeleteRoleCommand request, CancellationToken cancellationToken) 47 | { 48 | var result = await _authorizationService.DeleteRoleAsync(request.Id); 49 | if (result=="NotFound") return NotFound(); 50 | else if (result=="Used") return BadRequest(_stringLocalizer[SharedResourcesKeys.RoleIsUsed]); 51 | else if (result=="Success") return Success((string)_stringLocalizer[SharedResourcesKeys.Deleted]); 52 | else 53 | return BadRequest(result); 54 | } 55 | public async Task> Handle(UpdateUserRolesCommand request, CancellationToken cancellationToken) 56 | { 57 | var result = await _authorizationService.UpdateUserRoles(request); 58 | switch (result) 59 | { 60 | case "UserIsNull": return NotFound(_stringLocalizer[SharedResourcesKeys.UserIsNotFound]); 61 | case "FailedToRemoveOldRoles": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToRemoveOldRoles]); 62 | case "FailedToAddNewRoles": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToAddNewRoles]); 63 | case "FailedToUpdateUserRoles": return BadRequest(_stringLocalizer[SharedResourcesKeys.FailedToUpdateUserRoles]); 64 | } 65 | return Success(_stringLocalizer[SharedResourcesKeys.Success]); 66 | } 67 | #endregion 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Models/AddRoleCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authorization.Commands.Models 5 | { 6 | public class AddRoleCommand : IRequest> 7 | { 8 | public string RoleName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Models/DeleteRoleCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Authorization.Commands.Models 5 | { 6 | public class DeleteRoleCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public DeleteRoleCommand(int id) 10 | { 11 | Id = id; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Models/EditRoleCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.DTOs; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Commands.Models 6 | { 7 | public class EditRoleCommand : EditRoleRequest, IRequest> 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Models/UpdateUserClaimsCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.Requests; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Commands.Models 6 | { 7 | public class UpdateUserClaimsCommand : UpdateUserClaimsRequest, IRequest> 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Models/UpdateUserRolesCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.DTOs; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Commands.Models 6 | { 7 | public class UpdateUserRolesCommand : UpdateUserRolesRequest, IRequest> 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Validators/AddRoleValidators.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authorization.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | using SchoolProject.Service.Abstracts; 6 | 7 | namespace SchoolProject.Core.Features.Authorization.Commands.Validators 8 | { 9 | public class AddRoleValidators : AbstractValidator 10 | { 11 | #region Fields 12 | private readonly IStringLocalizer _stringLocalizer; 13 | private readonly IAuthorizationService _authorizationService; 14 | #endregion 15 | #region Constructors 16 | 17 | #endregion 18 | public AddRoleValidators(IStringLocalizer stringLocalizer, 19 | IAuthorizationService authorizationService) 20 | { 21 | _stringLocalizer = stringLocalizer; 22 | _authorizationService = authorizationService; 23 | ApplyValidationsRules(); 24 | ApplyCustomValidationsRules(); 25 | } 26 | 27 | #region Actions 28 | public void ApplyValidationsRules() 29 | { 30 | RuleFor(x => x.RoleName) 31 | .NotEmpty().WithMessage(_stringLocalizer[SharedResourcesKeys.NotEmpty]) 32 | .NotNull().WithMessage(_stringLocalizer[SharedResourcesKeys.Required]); 33 | } 34 | 35 | public void ApplyCustomValidationsRules() 36 | { 37 | RuleFor(x => x.RoleName) 38 | .MustAsync(async (Key, CancellationToken) => !await _authorizationService.IsRoleExistByName(Key)) 39 | .WithMessage(_stringLocalizer[SharedResourcesKeys.IsExist]); 40 | } 41 | 42 | #endregion 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Validators/DeleteRoleValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authorization.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | using SchoolProject.Service.Abstracts; 6 | 7 | namespace SchoolProject.Core.Features.Authorization.Commands.Validators 8 | { 9 | public class DeleteRoleValidator : AbstractValidator 10 | { 11 | #region Fields 12 | private readonly IStringLocalizer _stringLocalizer; 13 | public readonly IAuthorizationService _authorizationService; 14 | 15 | #endregion 16 | #region Constructors 17 | public DeleteRoleValidator(IStringLocalizer stringLocalizer, IAuthorizationService authorizationService) 18 | { 19 | _stringLocalizer = stringLocalizer; 20 | _authorizationService = authorizationService; 21 | ApplyValidationsRules(); 22 | ApplyCustomValidationsRules(); 23 | } 24 | #endregion 25 | #region Functions 26 | public void ApplyValidationsRules() 27 | { 28 | RuleFor(x => x.Id) 29 | .NotEmpty().WithMessage(_stringLocalizer[SharedResourcesKeys.NotEmpty]) 30 | .NotNull().WithMessage(_stringLocalizer[SharedResourcesKeys.Required]); 31 | } 32 | public void ApplyCustomValidationsRules() 33 | { 34 | //RuleFor(x => x.Id) 35 | // .MustAsync(async (Key, CancellationToken) => await _authorizationService.IsRoleExistById(Key)) 36 | // .WithMessage(_stringLocalizer[SharedResourcesKeys.RoleNotExist]); 37 | } 38 | #endregion 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Commands/Validators/EditRoleValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Authorization.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Authorization.Commands.Validators 7 | { 8 | public class EditRoleValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _stringLocalizer; 12 | #endregion 13 | #region Constructors 14 | 15 | #endregion 16 | public EditRoleValidator(IStringLocalizer stringLocalizer) 17 | { 18 | _stringLocalizer = stringLocalizer; 19 | ApplyValidationsRules(); 20 | ApplyCustomValidationsRules(); 21 | } 22 | 23 | #region Actions 24 | public void ApplyValidationsRules() 25 | { 26 | RuleFor(x => x.Id) 27 | .NotEmpty().WithMessage(_stringLocalizer[SharedResourcesKeys.NotEmpty]) 28 | .NotNull().WithMessage(_stringLocalizer[SharedResourcesKeys.Required]); 29 | 30 | RuleFor(x => x.Name) 31 | .NotEmpty().WithMessage(_stringLocalizer[SharedResourcesKeys.NotEmpty]) 32 | .NotNull().WithMessage(_stringLocalizer[SharedResourcesKeys.Required]); 33 | } 34 | 35 | public void ApplyCustomValidationsRules() 36 | { 37 | 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Handlers/ClaimsQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Bases; 5 | using SchoolProject.Core.Features.Authorization.Quaries.Models; 6 | using SchoolProject.Core.Resources; 7 | using SchoolProject.Data.Entities.Identity; 8 | using SchoolProject.Data.Results; 9 | using SchoolProject.Service.Abstracts; 10 | 11 | namespace SchoolProject.Core.Features.Authorization.Quaries.Handlers 12 | { 13 | public class ClaimsQueryHandler : ResponseHandler, 14 | IRequestHandler> 15 | { 16 | #region Fileds 17 | private readonly IAuthorizationService _authorizationService; 18 | private readonly UserManager _userManager; 19 | private readonly IStringLocalizer _stringLocalizer; 20 | #endregion 21 | #region Constructors 22 | public ClaimsQueryHandler(IStringLocalizer stringLocalizer, 23 | IAuthorizationService authorizationService, 24 | UserManager userManager) : base(stringLocalizer) 25 | { 26 | _authorizationService = authorizationService; 27 | _userManager = userManager; 28 | _stringLocalizer = stringLocalizer; 29 | } 30 | #endregion 31 | #region Handle Functions 32 | public async Task> Handle(ManageUserClaimsQuery request, CancellationToken cancellationToken) 33 | { 34 | var user = await _userManager.FindByIdAsync(request.UserId.ToString()); 35 | if (user==null) return NotFound(_stringLocalizer[SharedResourcesKeys.UserIsNotFound]); 36 | var result = await _authorizationService.ManageUserClaimData(user); 37 | return Success(result); 38 | } 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Handlers/RoleQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.AspNetCore.Identity; 4 | using Microsoft.Extensions.Localization; 5 | using SchoolProject.Core.Bases; 6 | using SchoolProject.Core.Features.Authorization.Quaries.Models; 7 | using SchoolProject.Core.Features.Authorization.Quaries.Results; 8 | using SchoolProject.Core.Resources; 9 | using SchoolProject.Data.Entities.Identity; 10 | using SchoolProject.Data.Results; 11 | using SchoolProject.Service.Abstracts; 12 | 13 | namespace SchoolProject.Core.Features.Authorization.Quaries.Handlers 14 | { 15 | public class RoleQueryHandler : ResponseHandler, 16 | IRequestHandler>>, 17 | IRequestHandler>, 18 | IRequestHandler> 19 | { 20 | #region Fields 21 | private readonly IAuthorizationService _authorizationService; 22 | private readonly IMapper _mapper; 23 | private readonly IStringLocalizer _stringLocalizer; 24 | private readonly UserManager _userManager; 25 | #endregion 26 | #region Constructors 27 | public RoleQueryHandler(IStringLocalizer stringLocalizer, 28 | IAuthorizationService authorizationService, 29 | IMapper mapper, 30 | UserManager userManager) : base(stringLocalizer) 31 | { 32 | _authorizationService=authorizationService; 33 | _mapper=mapper; 34 | _stringLocalizer=stringLocalizer; 35 | _userManager=userManager; 36 | } 37 | #endregion 38 | #region Handle Functions 39 | public async Task>> Handle(GetRolesListQuery request, CancellationToken cancellationToken) 40 | { 41 | var roles = await _authorizationService.GetRolesList(); 42 | var result = _mapper.Map>(roles); 43 | return Success(result); 44 | } 45 | 46 | public async Task> Handle(GetRoleByIdQuery request, CancellationToken cancellationToken) 47 | { 48 | var role = await _authorizationService.GetRoleById(request.Id); 49 | if (role==null) return NotFound(_stringLocalizer[SharedResourcesKeys.RoleNotExist]); 50 | var result = _mapper.Map(role); 51 | return Success(result); 52 | } 53 | 54 | public async Task> Handle(ManageUserRolesQuery request, CancellationToken cancellationToken) 55 | { 56 | var user = await _userManager.FindByIdAsync(request.UserId.ToString()); 57 | if (user==null) return NotFound(_stringLocalizer[SharedResourcesKeys.UserIsNotFound]); 58 | var result = await _authorizationService.ManageUserRolesData(user); 59 | return Success(result); 60 | } 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Models/GetRoleByIdQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Authorization.Quaries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Quaries.Models 6 | { 7 | public class GetRoleByIdQuery : IRequest> 8 | { 9 | public int Id { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Models/GetRolesListQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Authorization.Quaries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Quaries.Models 6 | { 7 | public class GetRolesListQuery : IRequest>> 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Models/ManageUserClaimsQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.Results; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Quaries.Models 6 | { 7 | public class ManageUserClaimsQuery : IRequest> 8 | { 9 | public int UserId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Models/ManageUserRolesQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Data.Results; 4 | 5 | namespace SchoolProject.Core.Features.Authorization.Quaries.Models 6 | { 7 | public class ManageUserRolesQuery : IRequest> 8 | { 9 | public int UserId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Results/GetRoleByIdResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Authorization.Quaries.Results 2 | { 3 | public class GetRoleByIdResult : GetRolesListResult 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Authorization/Quaries/Results/GetRolesListResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Authorization.Quaries.Results 2 | { 3 | public class GetRolesListResult 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Models/GetDepartmentByIDQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Department.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Department.Queries.Models 6 | { 7 | public class GetDepartmentByIDQuery : IRequest> 8 | { 9 | public int Id { get; set; } 10 | public int StudentPageNumber { get; set; } 11 | public int StudentPageSize { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Models/GetDepartmentStudentCountByIDQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Department.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Department.Queries.Models 6 | { 7 | public class GetDepartmentStudentCountByIDQuery : IRequest> 8 | { 9 | public int DID { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Models/GetDepartmentStudentListCountQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Department.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Department.Queries.Models 6 | { 7 | public class GetDepartmentStudentListCountQuery : IRequest>> 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Results/GetDepartmentByIDResponse.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Wrappers; 2 | 3 | namespace SchoolProject.Core.Features.Department.Queries.Results 4 | { 5 | public class GetDepartmentByIDResponse 6 | { 7 | public int Id { get; set; } 8 | public string Name { get; set; } 9 | public string ManagerName { get; set; } 10 | public PaginatedResult? StudentList { get; set; } 11 | public List? SubjectList { get; set; } 12 | public List? InstructorList { get; set; } 13 | } 14 | public class StudentResponse 15 | { 16 | public int Id { get; set; } 17 | public string Name { get; set; } 18 | public StudentResponse(int id, string name) 19 | { 20 | Id=id; 21 | Name=name; 22 | } 23 | } 24 | public class SubjectResponse 25 | { 26 | public int Id { get; set; } 27 | public string Name { get; set; } 28 | } 29 | public class InstructorResponse 30 | { 31 | public int Id { get; set; } 32 | public string Name { get; set; } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Results/GetDepartmentStudentCountByIDResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Department.Queries.Results 2 | { 3 | public class GetDepartmentStudentCountByIDResult : GetDepartmentStudentListCountResults 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Department/Queries/Results/GetDepartmentStudentListCountResults.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Department.Queries.Results 2 | { 3 | public class GetDepartmentStudentListCountResults 4 | { 5 | public string Name { get; set; } 6 | public int StudentCount { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Emails/Commands/Handlers/EmailsCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Bases; 4 | using SchoolProject.Core.Features.Emails.Commands.Models; 5 | using SchoolProject.Core.Resources; 6 | using SchoolProject.Service.Abstracts; 7 | namespace SchoolProject.Core.Features.Emails.Commands.Handlers 8 | { 9 | public class EmailsCommandHandler : ResponseHandler, 10 | IRequestHandler> 11 | { 12 | #region Fields 13 | private readonly IEmailsService _emailsService; 14 | private readonly IStringLocalizer _stringLocalizer; 15 | #endregion 16 | #region Constructors 17 | public EmailsCommandHandler(IStringLocalizer stringLocalizer, 18 | IEmailsService emailsService) : base(stringLocalizer) 19 | { 20 | _emailsService= emailsService; 21 | _stringLocalizer= stringLocalizer; 22 | } 23 | #endregion 24 | #region Handle Functions 25 | public async Task> Handle(SendEmailCommand request, CancellationToken cancellationToken) 26 | { 27 | var response = await _emailsService.SendEmail(request.Email, request.Message, null); 28 | if (response=="Success") 29 | return Success(""); 30 | return BadRequest(_stringLocalizer[SharedResourcesKeys.SendEmailFailed]); 31 | } 32 | #endregion 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Emails/Commands/Models/SendEmailCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Emails.Commands.Models 5 | { 6 | public class SendEmailCommand : IRequest> 7 | { 8 | public string Email { get; set; } 9 | public string Message { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Emails/Commands/Validators/SendEmailValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Emails.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | 6 | namespace SchoolProject.Core.Features.Emails.Commands.Validators 7 | { 8 | public class SendEmailValidator : AbstractValidator 9 | { 10 | #region Fields 11 | private readonly IStringLocalizer _localizer; 12 | #endregion 13 | #region Constructors 14 | public SendEmailValidator(IStringLocalizer localizer) 15 | { 16 | _localizer = localizer; 17 | ApplyValidationsRules(); 18 | } 19 | #endregion 20 | #region Actions 21 | public void ApplyValidationsRules() 22 | { 23 | RuleFor(x => x.Email) 24 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 25 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 26 | 27 | RuleFor(x => x.Message) 28 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 29 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 30 | } 31 | #endregion 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Instructors/Commands/Handlers/InstructorCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Bases; 5 | using SchoolProject.Core.Features.Instructors.Commands.Models; 6 | using SchoolProject.Core.Resources; 7 | using SchoolProject.Data.Entities; 8 | using SchoolProject.Service.Abstracts; 9 | 10 | namespace SchoolProject.Core.Features.Instructors.Commands.Handlers 11 | { 12 | public class InstructorCommandHandler : ResponseHandler, 13 | IRequestHandler> 14 | { 15 | 16 | #region Fileds 17 | private readonly IMapper _mapper; 18 | private readonly IStringLocalizer _localizer; 19 | private readonly IInstructorService _instructorService; 20 | #endregion 21 | #region Constructors 22 | public InstructorCommandHandler(IStringLocalizer stringLocalizer, 23 | IMapper mapper, 24 | IInstructorService instructorService) : base(stringLocalizer) 25 | { 26 | _instructorService = instructorService; 27 | _mapper = mapper; 28 | _localizer = stringLocalizer; 29 | } 30 | 31 | 32 | #endregion 33 | #region Handle Functions 34 | public async Task> Handle(AddInstructorCommand request, CancellationToken cancellationToken) 35 | { 36 | var instructor = _mapper.Map(request); 37 | var result = await _instructorService.AddInstructorAsync(instructor, request.Image); 38 | switch (result) 39 | { 40 | case "NoImage": return BadRequest(_localizer[SharedResourcesKeys.NoImage]); 41 | case "FailedToUploadImage": return BadRequest(_localizer[SharedResourcesKeys.FailedToUploadImage]); 42 | case "FailedInAdd": return BadRequest(_localizer[SharedResourcesKeys.AddFailed]); 43 | } 44 | return Success(""); 45 | } 46 | #endregion 47 | } 48 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Instructors/Commands/Models/AddInstructorCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Http; 3 | using SchoolProject.Core.Bases; 4 | 5 | namespace SchoolProject.Core.Features.Instructors.Commands.Models 6 | { 7 | public class AddInstructorCommand : IRequest> 8 | { 9 | public string? NameAr { get; set; } 10 | public string? NameEn { get; set; } 11 | public string? Address { get; set; } 12 | public string? Position { get; set; } 13 | public int? SupervisorId { get; set; } 14 | public decimal? Salary { get; set; } 15 | public int DID { get; set; } 16 | public IFormFile? Image { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Instructors/Commands/Validatior/AddInstructorValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Instructors.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | using SchoolProject.Service.Abstracts; 6 | 7 | namespace SchoolProject.Core.Features.Instructors.Commands.Validatior 8 | { 9 | public class AddInstructorValidator : AbstractValidator 10 | { 11 | #region Fields 12 | private readonly IStringLocalizer _localizer; 13 | private readonly IDepartmentService _departmentService; 14 | private readonly IInstructorService _instructorService; 15 | #endregion 16 | 17 | #region Constructors 18 | public AddInstructorValidator(IStringLocalizer localizer, 19 | IDepartmentService departmentService, 20 | IInstructorService instructorService) 21 | { 22 | _localizer = localizer; 23 | _instructorService = instructorService; 24 | _departmentService=departmentService; 25 | ApplyValidationsRules(); 26 | ApplyCustomValidationsRules(); 27 | 28 | } 29 | #endregion 30 | 31 | #region Actions 32 | public void ApplyValidationsRules() 33 | { 34 | RuleFor(x => x.NameAr) 35 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 36 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 37 | 38 | RuleFor(x => x.NameEn) 39 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 40 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 41 | 42 | RuleFor(x => x.DID) 43 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 44 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 45 | } 46 | 47 | public void ApplyCustomValidationsRules() 48 | { 49 | RuleFor(x => x.NameAr) 50 | .MustAsync(async (Key, CancellationToken) => !await _instructorService.IsNameArExist(Key)) 51 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 52 | RuleFor(x => x.NameEn) 53 | .MustAsync(async (Key, CancellationToken) => !await _instructorService.IsNameEnExist(Key)) 54 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 55 | 56 | RuleFor(x => x.DID) 57 | .MustAsync(async (Key, CancellationToken) => await _departmentService.IsDepartmentIdExist(Key)) 58 | .WithMessage(_localizer[SharedResourcesKeys.IsNotExist]); 59 | 60 | } 61 | 62 | #endregion 63 | 64 | } 65 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Instructors/Queries/Handlers/InstructorQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Bases; 5 | using SchoolProject.Core.Features.Instructors.Queries.Models; 6 | using SchoolProject.Core.Resources; 7 | using SchoolProject.Service.Abstracts; 8 | 9 | namespace SchoolProject.Core.Features.Instructors.Queries.Handlers 10 | { 11 | public class InstructorQueryHandler : ResponseHandler, 12 | IRequestHandler> 13 | { 14 | 15 | #region Fileds 16 | private readonly IMapper _mapper; 17 | private readonly IStringLocalizer _stringLocalizer; 18 | private readonly IInstructorService _instructorService; 19 | #endregion 20 | #region Constructors 21 | public InstructorQueryHandler(IStringLocalizer stringLocalizer, 22 | IMapper mapper, 23 | IInstructorService instructorService) : base(stringLocalizer) 24 | { 25 | _mapper = mapper; 26 | _stringLocalizer = stringLocalizer; 27 | _instructorService = instructorService; 28 | } 29 | 30 | #endregion 31 | #region Handle Functions 32 | public async Task> Handle(GetSummationSalaryOfInstructorQuery request, CancellationToken cancellationToken) 33 | { 34 | var result = await _instructorService.GetSalarySummationOfInstructor(); 35 | return Success(result); 36 | } 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Instructors/Queries/Models/GetSummationSalaryOfInstructorQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Instructors.Queries.Models 5 | { 6 | public class GetSummationSalaryOfInstructorQuery : IRequest> 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Handlers/StudentCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Bases; 5 | using SchoolProject.Core.Features.Students.Commands.Models; 6 | using SchoolProject.Core.Resources; 7 | using SchoolProject.Data.Entities; 8 | using SchoolProject.Service.Abstracts; 9 | 10 | namespace SchoolProject.Core.Features.Students.Commands.Handlers 11 | { 12 | public class StudentCommandHandler : ResponseHandler, 13 | IRequestHandler>, 14 | IRequestHandler>, 15 | IRequestHandler> 16 | { 17 | #region Fields 18 | private readonly IStudentService _studentService; 19 | private readonly IMapper _mapper; 20 | private readonly IStringLocalizer _localizer; 21 | #endregion 22 | 23 | #region Constructors 24 | public StudentCommandHandler(IStudentService studentService, 25 | IMapper mapper, 26 | IStringLocalizer localizer) : base(localizer) 27 | { 28 | _studentService= studentService; 29 | _mapper= mapper; 30 | _localizer= localizer; 31 | } 32 | #endregion 33 | 34 | 35 | #region Handle Functions 36 | 37 | public async Task> Handle(AddStudentCommand request, CancellationToken cancellationToken) 38 | { 39 | //mapping Between request and student 40 | var studentmapper = _mapper.Map(request); 41 | //add 42 | var result = await _studentService.AddAsync(studentmapper); 43 | //return response 44 | if (result=="Success") return Created(""); 45 | else return BadRequest(); 46 | } 47 | 48 | public async Task> Handle(EditStudentCommand request, CancellationToken cancellationToken) 49 | { 50 | //Check if the Id is Exist Or not 51 | var student = await _studentService.GetByIDAsync(request.Id); 52 | //return NotFound 53 | if (student==null) return NotFound(); 54 | //mapping Between request and student 55 | var studentmapper = _mapper.Map(request, student); 56 | //Call service that make Edit 57 | var result = await _studentService.EditAsync(studentmapper); 58 | //return response 59 | if (result=="Success") return Success((string)_localizer[SharedResourcesKeys.Updated]); 60 | else return BadRequest(); 61 | } 62 | 63 | public async Task> Handle(DeleteStudentCommand request, CancellationToken cancellationToken) 64 | { 65 | //Check if the Id is Exist Or not 66 | var student = await _studentService.GetByIDAsync(request.Id); 67 | //return NotFound 68 | if (student==null) return NotFound(); 69 | //Call service that make Delete 70 | var result = await _studentService.DeleteAsync(student); 71 | if (result=="Success") return Deleted(); 72 | else return BadRequest(); 73 | } 74 | #endregion 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Models/AddStudentCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Students.Commands.Models 5 | { 6 | public class AddStudentCommand : IRequest> 7 | { 8 | public string NameAr { get; set; } 9 | public string NameEn { get; set; } 10 | public string Address { get; set; } 11 | public string Phone { get; set; } 12 | public int DepartmementId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Models/DeleteStudentCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Students.Commands.Models 5 | { 6 | public class DeleteStudentCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public DeleteStudentCommand(int id) 10 | { 11 | Id=id; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Models/EditStudentCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | 4 | namespace SchoolProject.Core.Features.Students.Commands.Models 5 | { 6 | public class EditStudentCommand : IRequest> 7 | { 8 | public int Id { get; set; } 9 | public string NameAr { get; set; } 10 | public string NameEn { get; set; } 11 | public string Address { get; set; } 12 | public string? Phone { get; set; } 13 | public int DepartmementId { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Validatiors/AddStudentValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Students.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | using SchoolProject.Service.Abstracts; 6 | 7 | namespace SchoolProject.Core.Features.Students.Commands.Validatiors 8 | { 9 | public class AddStudentValidator : AbstractValidator 10 | { 11 | #region Fields 12 | private readonly IStudentService _studentService; 13 | private readonly IStringLocalizer _localizer; 14 | private readonly IDepartmentService _departmentService; 15 | #endregion 16 | 17 | #region Constructors 18 | public AddStudentValidator(IStudentService studentService, 19 | IStringLocalizer localizer, 20 | IDepartmentService departmentService) 21 | { 22 | _studentService = studentService; 23 | _localizer = localizer; 24 | ApplyValidationsRules(); 25 | ApplyCustomValidationsRules(); 26 | _departmentService=departmentService; 27 | } 28 | #endregion 29 | 30 | #region Actions 31 | public void ApplyValidationsRules() 32 | { 33 | RuleFor(x => x.NameAr) 34 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 35 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 36 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 37 | 38 | RuleFor(x => x.Address) 39 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 40 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 41 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 42 | 43 | RuleFor(x => x.DepartmementId) 44 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 45 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]); 46 | } 47 | 48 | public void ApplyCustomValidationsRules() 49 | { 50 | RuleFor(x => x.NameAr) 51 | .MustAsync(async (Key, CancellationToken) => !await _studentService.IsNameArExist(Key)) 52 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 53 | RuleFor(x => x.NameEn) 54 | .MustAsync(async (Key, CancellationToken) => !await _studentService.IsNameEnExist(Key)) 55 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 56 | 57 | 58 | 59 | RuleFor(x => x.DepartmementId) 60 | .MustAsync(async (Key, CancellationToken) => await _departmentService.IsDepartmentIdExist(Key)) 61 | .WithMessage(_localizer[SharedResourcesKeys.IsNotExist]); 62 | 63 | 64 | 65 | 66 | } 67 | 68 | #endregion 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Commands/Validatiors/EditStudentValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using Microsoft.Extensions.Localization; 3 | using SchoolProject.Core.Features.Students.Commands.Models; 4 | using SchoolProject.Core.Resources; 5 | using SchoolProject.Service.Abstracts; 6 | 7 | namespace SchoolProject.Core.Features.Students.Commands.Validatiors 8 | { 9 | public class EditStudentValidator : AbstractValidator 10 | { 11 | #region Fields 12 | private readonly IStudentService _studentService; 13 | private readonly IStringLocalizer _localizer; 14 | #endregion 15 | 16 | #region Constructors 17 | public EditStudentValidator(IStudentService studentService, 18 | IStringLocalizer localizer) 19 | { 20 | _studentService = studentService; 21 | _localizer=localizer; 22 | ApplyValidationsRules(); 23 | ApplyCustomValidationsRules(); 24 | } 25 | #endregion 26 | 27 | #region Actions 28 | public void ApplyValidationsRules() 29 | { 30 | RuleFor(x => x.NameAr) 31 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 32 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 33 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 34 | 35 | RuleFor(x => x.Address) 36 | .NotEmpty().WithMessage(_localizer[SharedResourcesKeys.NotEmpty]) 37 | .NotNull().WithMessage(_localizer[SharedResourcesKeys.Required]) 38 | .MaximumLength(100).WithMessage(_localizer[SharedResourcesKeys.MaxLengthis100]); 39 | } 40 | 41 | public void ApplyCustomValidationsRules() 42 | { 43 | RuleFor(x => x.NameAr) 44 | .MustAsync(async (model, Key, CancellationToken) => !await _studentService.IsNameArExistExcludeSelf(Key, model.Id)) 45 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 46 | RuleFor(x => x.NameEn) 47 | .MustAsync(async (model, Key, CancellationToken) => !await _studentService.IsNameEnExistExcludeSelf(Key, model.Id)) 48 | .WithMessage(_localizer[SharedResourcesKeys.IsExist]); 49 | } 50 | 51 | #endregion 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Handlers/StudentQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using MediatR; 3 | using Microsoft.Extensions.Localization; 4 | using SchoolProject.Core.Bases; 5 | using SchoolProject.Core.Features.Students.Queries.Models; 6 | using SchoolProject.Core.Features.Students.Queries.Results; 7 | using SchoolProject.Core.Resources; 8 | using SchoolProject.Core.Wrappers; 9 | using SchoolProject.Service.Abstracts; 10 | 11 | namespace SchoolProject.Core.Features.Students.Queries.Handlers 12 | { 13 | public class StudentQueryHandler : ResponseHandler, 14 | IRequestHandler>>, 15 | IRequestHandler>, 16 | IRequestHandler> 17 | { 18 | 19 | #region Fields 20 | private readonly IStudentService _studentService; 21 | private readonly IMapper _mapper; 22 | private readonly IStringLocalizer _stringLocalizer; 23 | #endregion 24 | #region Constructors 25 | public StudentQueryHandler(IStudentService studentService, 26 | IMapper mapper, 27 | IStringLocalizer stringLocalizer) : base(stringLocalizer) 28 | { 29 | _studentService=studentService; 30 | _mapper=mapper; 31 | _stringLocalizer=stringLocalizer; 32 | } 33 | #endregion 34 | 35 | 36 | #region Handle Functions 37 | 38 | public async Task>> Handle(GetStudentListQuery request, CancellationToken cancellationToken) 39 | { 40 | var studentList = await _studentService.GetStudentsListAsync(); 41 | var studentListMapper = _mapper.Map>(studentList); 42 | var result = Success(studentListMapper); 43 | result.Meta=new { Count = studentListMapper.Count() }; 44 | return result; 45 | } 46 | 47 | public async Task> Handle(GetStudentByIDQuery request, CancellationToken cancellationToken) 48 | { 49 | var student = await _studentService.GetStudentByIDWithIncludeAsync(request.Id); 50 | if (student==null) return NotFound(_stringLocalizer[SharedResourcesKeys.NotFound]); 51 | var result = _mapper.Map(student); 52 | return Success(result); 53 | } 54 | 55 | public async Task> Handle(GetStudentPaginatedListQuery request, CancellationToken cancellationToken) 56 | { 57 | //Expression> expression = e => new GetStudentPaginatedListResponse(e.StudID, e.Localize(e.NameAr, e.NameEn), e.Address, e.Department.Localize(e.Department.DNameAr, e.Department.DNameEn)); 58 | var FilterQuery = _studentService.FilterStudentPaginatedQuerable(request.OrderBy, request.Search); 59 | var PaginatedList = await _mapper.ProjectTo(FilterQuery).ToPaginatedListAsync(request.PageNumber, request.PageSize); 60 | PaginatedList.Meta=new { Count = PaginatedList.Data.Count() }; 61 | return PaginatedList; 62 | } 63 | 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Models/GetStudentByIDQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Students.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Students.Queries.Models 6 | { 7 | public class GetStudentByIDQuery : IRequest> 8 | { 9 | public int Id { get; set; } 10 | public GetStudentByIDQuery(int id) 11 | { 12 | Id=id; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Models/GetStudentListQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Bases; 3 | using SchoolProject.Core.Features.Students.Queries.Results; 4 | 5 | namespace SchoolProject.Core.Features.Students.Queries.Models 6 | { 7 | public class GetStudentListQuery : IRequest>> 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Models/GetStudentPaginatedListQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using SchoolProject.Core.Features.Students.Queries.Results; 3 | using SchoolProject.Core.Wrappers; 4 | using SchoolProject.Data.Enums; 5 | 6 | namespace SchoolProject.Core.Features.Students.Queries.Models 7 | { 8 | public class GetStudentPaginatedListQuery : IRequest> 9 | { 10 | public int PageNumber { get; set; } 11 | public int PageSize { get; set; } 12 | public StudentOrderingEnum OrderBy { get; set; } 13 | public string? Search { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Results/GetSingleStudentResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Students.Queries.Results 2 | { 3 | public class GetSingleStudentResponse 4 | { 5 | public int StudID { get; set; } 6 | public string? Name { get; set; } 7 | public string? Address { get; set; } 8 | public string? DepartmentName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Results/GetStudentListResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Students.Queries.Results 2 | { 3 | public class GetStudentListResponse 4 | { 5 | public int StudID { get; set; } 6 | public string? Name { get; set; } 7 | public string? Address { get; set; } 8 | public string? DepartmentName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Features/Students/Queries/Results/GetStudentPaginatedListResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Features.Students.Queries.Results 2 | { 3 | public class GetStudentPaginatedListResponse 4 | { 5 | public int StudID { get; set; } 6 | public string? Name { get; set; } 7 | public string? Address { get; set; } 8 | public string? DepartmentName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Core/Filters/AuthFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Filters; 5 | using SchoolProject.Data.Entities.Identity; 6 | using SchoolProject.Service.AuthServices.Interfaces; 7 | 8 | namespace SchoolProject.Core.Filters 9 | { 10 | public class AuthFilter : IAsyncActionFilter 11 | { 12 | private readonly ICurrentUserService _currentUserService; 13 | private readonly UserManager _userManager; 14 | public AuthFilter(ICurrentUserService currentUserService) 15 | { 16 | _currentUserService = currentUserService; 17 | } 18 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 19 | { 20 | if (context.HttpContext.User.Identity.IsAuthenticated==true) 21 | { 22 | var roles = await _currentUserService.GetCurrentUserRolesAsync(); 23 | if (roles.All(x => x!="User")) 24 | { 25 | context.Result=new ObjectResult("Forbidden") 26 | { 27 | StatusCode = StatusCodes.Status403Forbidden 28 | }; 29 | } 30 | else 31 | { 32 | await next(); 33 | } 34 | 35 | } 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/ApplicationUser/ApplicationUserProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SchoolProject.Core.Mapping.ApplicationUser 4 | { 5 | public partial class ApplicationUserProfile : Profile 6 | { 7 | public ApplicationUserProfile() 8 | { 9 | AddUserMapping(); 10 | GetUserPaginationMapping(); 11 | GetUserByIdMapping(); 12 | UpdateUserMapping(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/ApplicationUser/Commands/AddUserMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.ApplicationUser 5 | { 6 | public partial class ApplicationUserProfile 7 | { 8 | public void AddUserMapping() 9 | { 10 | CreateMap(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/ApplicationUser/Commands/UpdateUserMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.ApplicationUser.Commands.Models; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.ApplicationUser 5 | { 6 | public partial class ApplicationUserProfile 7 | { 8 | public void UpdateUserMapping() 9 | { 10 | CreateMap(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/ApplicationUser/Queries/GetUserByIdMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.ApplicationUser.Queries.Results; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.ApplicationUser 5 | { 6 | public partial class ApplicationUserProfile 7 | { 8 | public void GetUserByIdMapping() 9 | { 10 | CreateMap(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/ApplicationUser/Queries/GetUserPaginationMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.ApplicationUser.Queries.Results; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.ApplicationUser 5 | { 6 | public partial class ApplicationUserProfile 7 | { 8 | public void GetUserPaginationMapping() 9 | { 10 | CreateMap(); 11 | 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Departments/DepartmentProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SchoolProject.Core.Mapping.Departments 4 | { 5 | public partial class DepartmentProfile : Profile 6 | { 7 | public DepartmentProfile() 8 | { 9 | GetDepartmentByIdMapping(); 10 | GetDepartmentStudentCountMapping(); 11 | GetDepartmentStudentCountByIdMapping(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Departments/QueriesMapping/GetDepartmentByIdMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Department.Queries.Results; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Departments 5 | { 6 | public partial class DepartmentProfile 7 | { 8 | public void GetDepartmentByIdMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.DNameAr, src.DNameEn))) 12 | .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.DID)) 13 | .ForMember(dest => dest.ManagerName, opt => opt.MapFrom(src => src.Instructor.Localize(src.Instructor.ENameAr, src.Instructor.ENameEn))) 14 | .ForMember(dest => dest.SubjectList, opt => opt.MapFrom(src => src.DepartmentSubjects)) 15 | //.ForMember(dest => dest.StudentList, opt => opt.MapFrom(src => src.Students)) 16 | .ForMember(dest => dest.InstructorList, opt => opt.MapFrom(src => src.Instructors)); 17 | 18 | CreateMap() 19 | .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.SubID)) 20 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Subject.Localize(src.Subject.SubjectNameAr, src.Subject.SubjectNameEn))); 21 | 22 | //CreateMap() 23 | // .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.StudID)) 24 | // .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.NameAr, src.NameEn))); 25 | 26 | CreateMap() 27 | .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.InsId)) 28 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.ENameAr, src.ENameEn))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Departments/QueriesMapping/GetDepartmentStudentCountByIdMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Department.Queries.Models; 2 | using SchoolProject.Core.Features.Department.Queries.Results; 3 | using SchoolProject.Data.Entities.Procedures; 4 | 5 | namespace SchoolProject.Core.Mapping.Departments 6 | { 7 | public partial class DepartmentProfile 8 | { 9 | public void GetDepartmentStudentCountByIdMapping() 10 | { 11 | CreateMap(); 12 | 13 | CreateMap() 14 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.DNameAr, src.DNameEn))) 15 | .ForMember(dest => dest.StudentCount, opt => opt.MapFrom(src => src.StudentCount)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Departments/QueriesMapping/GetDepartmentStudentCountMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Department.Queries.Results; 2 | using SchoolProject.Data.Entities.Views; 3 | 4 | namespace SchoolProject.Core.Mapping.Departments 5 | { 6 | public partial class DepartmentProfile 7 | { 8 | public void GetDepartmentStudentCountMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.DNameAr, src.DNameEn))) 12 | .ForMember(dest => dest.StudentCount, opt => opt.MapFrom(src => src.StudentCount)); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Instructors/Commands/AddInstructorMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Instructors.Commands.Models; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Instructors 5 | { 6 | public partial class InstructorProfile 7 | { 8 | public void AddInstructorMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.Image, opt => opt.Ignore()) 12 | .ForMember(dest => dest.ENameAr, opt => opt.MapFrom(src => src.NameAr)) 13 | .ForMember(dest => dest.ENameEn, opt => opt.MapFrom(src => src.NameEn)); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Instructors/InstructorProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | namespace SchoolProject.Core.Mapping.Instructors 3 | { 4 | public partial class InstructorProfile : Profile 5 | { 6 | public InstructorProfile() 7 | { 8 | AddInstructorMapping(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Roles/Queries/GetRoleByIdMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Authorization.Quaries.Results; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.Roles 5 | { 6 | public partial class RoleProfile 7 | { 8 | public void GetRoleByIdMapping() 9 | { 10 | CreateMap(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Roles/Queries/GetRolesListMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Authorization.Quaries.Results; 2 | using SchoolProject.Data.Entities.Identity; 3 | 4 | namespace SchoolProject.Core.Mapping.Roles 5 | { 6 | public partial class RoleProfile 7 | { 8 | public void GetRolesListMapping() 9 | { 10 | CreateMap(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Roles/RoleProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SchoolProject.Core.Mapping.Roles 4 | { 5 | public partial class RoleProfile : Profile 6 | { 7 | public RoleProfile() 8 | { 9 | GetRolesListMapping(); 10 | GetRoleByIdMapping(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/CommandMapping/AddStudentCommandMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Students.Commands.Models; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Students 5 | { 6 | public partial class StudentProfile 7 | { 8 | public void AddStudentCommandMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.DID, opt => opt.MapFrom(src => src.DepartmementId)) 12 | .ForMember(dest => dest.NameEn, opt => opt.MapFrom(src => src.NameEn)) 13 | .ForMember(dest => dest.NameAr, opt => opt.MapFrom(src => src.NameAr)); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/CommandMapping/EditStudentCommandMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Students.Commands.Models; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Students 5 | { 6 | public partial class StudentProfile 7 | { 8 | public void EditStudentCommandMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.DID, opt => opt.MapFrom(src => src.DepartmementId)) 12 | .ForMember(dest => dest.NameEn, opt => opt.MapFrom(src => src.NameEn)) 13 | .ForMember(dest => dest.NameAr, opt => opt.MapFrom(src => src.NameAr)) 14 | .ForMember(dest => dest.StudID, opt => opt.MapFrom(src => src.Id)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/QueryMapping/GetStudentByIDMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Students.Queries.Results; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Students 5 | { 6 | public partial class StudentProfile 7 | { 8 | public void GetStudentByIDMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.DepartmentName, opt => opt.MapFrom(src => src.Department.Localize(src.Department.DNameAr, src.Department.DNameEn))) 12 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.NameAr, src.NameEn))); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/QueryMapping/GetStudentListMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Students.Queries.Results; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Students 5 | { 6 | public partial class StudentProfile 7 | { 8 | public void GetStudentListMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.DepartmentName, opt => opt.MapFrom(src => src.Department.Localize(src.Department.DNameAr, src.Department.DNameEn))) 12 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.NameAr, src.NameEn))); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/QueryMapping/GetStudentPaginationMapping.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Features.Students.Queries.Results; 2 | using SchoolProject.Data.Entities; 3 | 4 | namespace SchoolProject.Core.Mapping.Students 5 | { 6 | public partial class StudentProfile 7 | { 8 | public void GetStudentPaginationMapping() 9 | { 10 | CreateMap() 11 | .ForMember(dest => dest.DepartmentName, opt => opt.MapFrom(src => src.Department.Localize(src.Department.DNameAr, src.Department.DNameEn))) 12 | .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Localize(src.NameAr, src.NameEn))) 13 | .ForMember(dest => dest.StudID, opt => opt.MapFrom(src => src.StudID)) 14 | .ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.Address)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SchoolProject.Core/Mapping/Students/StudentProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SchoolProject.Core.Mapping.Students 4 | { 5 | public partial class StudentProfile : Profile 6 | { 7 | public StudentProfile() 8 | { 9 | GetStudentListMapping(); 10 | GetStudentByIDMapping(); 11 | AddStudentCommandMapping(); 12 | EditStudentCommandMapping(); 13 | GetStudentPaginationMapping(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SchoolProject.Core/ModuleCoreDependencies.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using MediatR; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using SchoolProject.Core.Behaviors; 5 | using System.Reflection; 6 | 7 | namespace SchoolProject.Core 8 | { 9 | public static class ModuleCoreDependencies 10 | { 11 | public static IServiceCollection AddCoreDependencies(this IServiceCollection services) 12 | { 13 | //Configuration Of Mediator 14 | services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly())); 15 | //Configuration Of Automapper 16 | services.AddAutoMapper(Assembly.GetExecutingAssembly()); 17 | // Get Validators 18 | services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); 19 | // 20 | services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); 21 | 22 | return services; 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /SchoolProject.Core/Resources/SharedResources.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Resources 2 | { 3 | public class SharedResources 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SchoolProject.Core/Resources/SharedResourcesKeys.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Resources 2 | { 3 | public static class SharedResourcesKeys 4 | { 5 | public const string Required = "Required"; 6 | public const string NotFound = "NotFound"; 7 | public const string Deleted = "Deleted"; 8 | public const string Created = "Created"; 9 | public const string Success = "Success"; 10 | public const string NotEmpty = "NotEmpty"; 11 | public const string Updated = "Updated"; 12 | public const string UnAuthorized = "UnAuthorized"; 13 | public const string BadRequest = "BadRequest"; 14 | public const string UnprocessableEntity = "UnprocessableEntity"; 15 | public const string MaxLengthis100 = "MaxLengthis100"; 16 | public const string IsExist = "IsExist"; 17 | public const string IsNotExist = "IsNotExist"; 18 | public const string DepartmementId = "DepartmementId"; 19 | public const string PasswordNotEqualConfirmPass = "PasswordNotEqualConfirmPass"; 20 | public const string EmailIsExist = "EmailIsExist"; 21 | public const string UserNameIsExist = "UserNameIsExist"; 22 | public const string FaildToAddUser = "FaildToAddUser"; 23 | public const string UpdateFailed = "UpdateFailed"; 24 | public const string DeletedFailed = "DeletedFailed"; 25 | public const string ChangePassFailed = "ChangePassFailed"; 26 | public const string UserName = "UserName"; 27 | public const string Password = "Password"; 28 | public const string UserNameIsNotExist = "UserNameIsNotExist"; 29 | public const string PasswordNotCorrect = "PasswordNotCorrect"; 30 | 31 | public const string AlgorithmIsWrong = "AlgorithmIsWrong"; 32 | public const string TokenIsNotExpired = "TokenIsNotExpired"; 33 | public const string RefreshTokenIsNotFound = "RefreshTokenIsNotFound"; 34 | public const string RefreshTokenIsExpired = "RefreshTokenIsExpired"; 35 | public const string TokenIsExpired = "TokenIsExpired"; 36 | public const string AddFailed = "AddFailed"; 37 | public const string RoleNotExist = "RoleNotExist"; 38 | public const string RoleIsUsed = "RoleIsUsed"; 39 | public const string UserIsNotFound = "UserIsNotFound"; 40 | public const string FailedToRemoveOldRoles = "FailedToRemoveOldRoles"; 41 | public const string FailedToUpdateUserRoles = "FailedToUpdateUserRoles"; 42 | public const string FailedToAddNewRoles = "FailedToAddNewRoles"; 43 | 44 | public const string FailedToUpdateClaims = "FailedToUpdateClaims"; 45 | public const string FailedToAddNewClaims = "FailedToAddNewClaims"; 46 | public const string FailedToRemoveOldClaims = "FailedToRemoveOldClaims"; 47 | public const string Email = "Email"; 48 | public const string Message = "Message"; 49 | public const string SendEmailFailed = "SendEmailFailed"; 50 | public const string EmailNotConfirmed = "EmailNotConfirmed"; 51 | public const string TryToRegisterAgain = "TryToRegisterAgain"; 52 | public const string ErrorWhenConfirmEmail = "ErrorWhenConfirmEmail"; 53 | public const string ConfirmEmailDone = "ConfirmEmailDone"; 54 | public const string TryAgainInAnotherTime = "TryAgainInAnotherTime"; 55 | public const string InvaildCode = "InvaildCode"; 56 | public const string NoImage = "NoImage"; 57 | public const string FailedToUploadImage = "FailedToUploadImage"; 58 | 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SchoolProject.Core/SchoolProject.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /SchoolProject.Core/Wrappers/PaginatedResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Core.Wrappers 2 | { 3 | public class PaginatedResult 4 | { 5 | public PaginatedResult(List data) 6 | { 7 | Data = data; 8 | } 9 | public List Data { get; set; } 10 | 11 | internal PaginatedResult(bool succeeded, List data = default, List messages = null, int count = 0, int page = 1, int pageSize = 10) 12 | { 13 | Data = data; 14 | CurrentPage = page; 15 | Succeeded = succeeded; 16 | PageSize = pageSize; 17 | TotalPages = (int)Math.Ceiling(count / (double)pageSize); 18 | TotalCount = count; 19 | } 20 | 21 | public static PaginatedResult Success(List data, int count, int page, int pageSize) 22 | { 23 | return new(true, data, null, count, page, pageSize); 24 | } 25 | 26 | public int CurrentPage { get; set; } 27 | 28 | public int TotalPages { get; set; } 29 | 30 | public int TotalCount { get; set; } 31 | 32 | public object Meta { get; set; } 33 | 34 | public int PageSize { get; set; } 35 | 36 | public bool HasPreviousPage => CurrentPage > 1; 37 | 38 | public bool HasNextPage => CurrentPage < TotalPages; 39 | 40 | public List Messages { get; set; } = new(); 41 | 42 | public bool Succeeded { get; set; } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /SchoolProject.Core/Wrappers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace SchoolProject.Core.Wrappers 4 | { 5 | public static class QueryableExtensions 6 | { 7 | public static async Task> ToPaginatedListAsync(this IQueryable source, int pageNumber, int pageSize) 8 | where T : class 9 | { 10 | if (source == null) 11 | { 12 | throw new Exception("Empty"); 13 | } 14 | 15 | pageNumber = pageNumber == 0 ? 1 : pageNumber; 16 | pageSize = pageSize == 0 ? 10 : pageSize; 17 | int count = await source.AsNoTracking().CountAsync(); 18 | if (count==0) return PaginatedResult.Success(new List(), count, pageNumber, pageSize); 19 | pageNumber = pageNumber <= 0 ? 1 : pageNumber; 20 | var items = await source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToListAsync(); 21 | return PaginatedResult.Success(items, count, pageNumber, pageSize); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SchoolProject.Data/Class1.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data 2 | { 3 | public class Class1 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /SchoolProject.Data/Commons/GeneralLocalizableEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace SchoolProject.Data.Commons 4 | { 5 | public class GeneralLocalizableEntity 6 | { 7 | public string Localize(string textAr, string textEN) 8 | { 9 | CultureInfo CultureInfo = Thread.CurrentThread.CurrentCulture; 10 | if (CultureInfo.TwoLetterISOLanguageName.ToLower().Equals("ar")) 11 | return textAr; 12 | return textEN; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SchoolProject.Data/Commons/LocalizableEntity.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace SchoolProject.Data.Commons 4 | { 5 | public class LocalizableEntity 6 | { 7 | public string NameAr { get; set; } 8 | public string NameEn { get; set; } 9 | 10 | public string GetLocalized() 11 | { 12 | CultureInfo culture = Thread.CurrentThread.CurrentCulture; 13 | if (culture.TwoLetterISOLanguageName.ToLower().Equals("ar")) 14 | return NameAr; 15 | return NameEn; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Department.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Commons; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace SchoolProject.Data.Entities 6 | { 7 | 8 | public partial class Department : GeneralLocalizableEntity 9 | { 10 | public Department() 11 | { 12 | Students = new HashSet(); 13 | DepartmentSubjects = new HashSet(); 14 | Instructors=new HashSet(); 15 | } 16 | [Key] 17 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 18 | public int DID { get; set; } 19 | //[StringLength(500)] 20 | public string? DNameAr { get; set; } 21 | [StringLength(200)] 22 | public string? DNameEn { get; set; } 23 | 24 | public int? InsManager { get; set; } 25 | 26 | [InverseProperty("Department")] 27 | public virtual ICollection Students { get; set; } 28 | [InverseProperty("Department")] 29 | public virtual ICollection DepartmentSubjects { get; set; } 30 | [InverseProperty("department")] 31 | public virtual ICollection Instructors { get; set; } 32 | 33 | [ForeignKey("InsManager")] 34 | [InverseProperty("departmentManager")] 35 | public virtual Instructor? Instructor { get; set; } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/DepartmetSubject.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace SchoolProject.Data.Entities 5 | { 6 | public class DepartmetSubject 7 | { 8 | [Key] 9 | public int DID { get; set; } 10 | [Key] 11 | public int SubID { get; set; } 12 | 13 | [ForeignKey("DID")] 14 | [InverseProperty("DepartmentSubjects")] 15 | public virtual Department? Department { get; set; } 16 | 17 | [ForeignKey("SubID")] 18 | [InverseProperty("DepartmetsSubjects")] 19 | public virtual Subjects? Subject { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Identity/Role.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | 3 | namespace SchoolProject.Data.Entities.Identity 4 | { 5 | public class Role : IdentityRole 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Identity/User.cs: -------------------------------------------------------------------------------- 1 | using EntityFrameworkCore.EncryptColumn.Attribute; 2 | using Microsoft.AspNetCore.Identity; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace SchoolProject.Data.Entities.Identity 6 | { 7 | public class User : IdentityUser 8 | { 9 | public User() 10 | { 11 | UserRefreshTokens=new HashSet(); 12 | } 13 | public string FullName { get; set; } 14 | public string? Address { get; set; } 15 | public string? Country { get; set; } 16 | [EncryptColumn] 17 | public string? Code { get; set; } 18 | [InverseProperty(nameof(UserRefreshToken.user))] 19 | public virtual ICollection UserRefreshTokens { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Identity/UserRefreshToken.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace SchoolProject.Data.Entities.Identity 5 | { 6 | public class UserRefreshToken 7 | { 8 | [Key] 9 | public int Id { get; set; } 10 | public int UserId { get; set; } 11 | public string? Token { get; set; } 12 | public string? RefreshToken { get; set; } 13 | public string? JwtId { get; set; } 14 | public bool IsUsed { get; set; } 15 | public bool IsRevoked { get; set; } 16 | public DateTime AddedTime { get; set; } 17 | public DateTime ExpiryDate { get; set; } 18 | [ForeignKey(nameof(UserId))] 19 | [InverseProperty(nameof(User.UserRefreshTokens))] 20 | public virtual User? user { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Ins_Subject.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace SchoolProject.Data.Entities 5 | { 6 | public class Ins_Subject 7 | { 8 | [Key] 9 | public int InsId { get; set; } 10 | [Key] 11 | public int SubId { get; set; } 12 | [ForeignKey(nameof(InsId))] 13 | [InverseProperty("Ins_Subjects")] 14 | public Instructor? instructor { get; set; } 15 | [ForeignKey(nameof(SubId))] 16 | [InverseProperty("Ins_Subjects")] 17 | public Subjects? Subject { get; set; } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Instructor.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Commons; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace SchoolProject.Data.Entities 6 | { 7 | public class Instructor : GeneralLocalizableEntity 8 | { 9 | public Instructor() 10 | { 11 | Instructors=new HashSet(); 12 | Ins_Subjects=new HashSet(); 13 | } 14 | [Key] 15 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 16 | public int InsId { get; set; } 17 | public string? ENameAr { get; set; } 18 | public string? ENameEn { get; set; } 19 | public string? Address { get; set; } 20 | public string? Position { get; set; } 21 | public int? SupervisorId { get; set; } 22 | public decimal? Salary { get; set; } 23 | public string? Image { get; set; } 24 | public int DID { get; set; } 25 | [ForeignKey(nameof(DID))] 26 | [InverseProperty("Instructors")] 27 | public Department? department { get; set; } 28 | 29 | [InverseProperty("Instructor")] 30 | public Department? departmentManager { get; set; } 31 | 32 | 33 | [ForeignKey(nameof(SupervisorId))] 34 | [InverseProperty("Instructors")] 35 | public Instructor? Supervisor { get; set; } 36 | [InverseProperty("Supervisor")] 37 | public virtual ICollection Instructors { get; set; } 38 | 39 | [InverseProperty("instructor")] 40 | public virtual ICollection Ins_Subjects { get; set; } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Procedures/DepartmentStudentCountProc.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Commons; 2 | 3 | namespace SchoolProject.Data.Entities.Procedures 4 | { 5 | public class DepartmentStudentCountProc : GeneralLocalizableEntity 6 | { 7 | public int DID { get; set; } 8 | public string? DNameAr { get; set; } 9 | public string? DNameEn { get; set; } 10 | public int StudentCount { get; set; } 11 | } 12 | public class DepartmentStudentCountProcParameters 13 | { 14 | public int DID { get; set; } = 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Student.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Commons; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace SchoolProject.Data.Entities 6 | { 7 | public class Student : GeneralLocalizableEntity 8 | { 9 | public Student() 10 | { 11 | StudentSubject=new HashSet(); 12 | } 13 | [Key] 14 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 15 | public int StudID { get; set; } 16 | public string? NameAr { get; set; } 17 | public string? NameEn { get; set; } 18 | [StringLength(500)] 19 | public string? Address { get; set; } 20 | [StringLength(500)] 21 | public string? Phone { get; set; } 22 | public int? DID { get; set; } 23 | 24 | [ForeignKey("DID")] 25 | [InverseProperty("Students")] 26 | public virtual Department? Department { get; set; } 27 | [InverseProperty("Student")] 28 | public virtual ICollection StudentSubject { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/StudentSubject.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace SchoolProject.Data.Entities 5 | { 6 | public class StudentSubject 7 | { 8 | [Key] 9 | public int StudID { get; set; } 10 | [Key] 11 | public int SubID { get; set; } 12 | public decimal? grade { get; set; } 13 | 14 | [ForeignKey("StudID")] 15 | [InverseProperty("StudentSubject")] 16 | public virtual Student? Student { get; set; } 17 | 18 | [ForeignKey("SubID")] 19 | [InverseProperty("StudentsSubjects")] 20 | public virtual Subjects? Subject { get; set; } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Subject.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Commons; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | 5 | namespace SchoolProject.Data.Entities 6 | { 7 | public class Subjects : GeneralLocalizableEntity 8 | { 9 | public Subjects() 10 | { 11 | StudentsSubjects = new HashSet(); 12 | DepartmetsSubjects = new HashSet(); 13 | Ins_Subjects=new HashSet(); 14 | } 15 | [Key] 16 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 17 | public int SubID { get; set; } 18 | [StringLength(500)] 19 | public string? SubjectNameAr { get; set; } 20 | public string? SubjectNameEn { get; set; } 21 | public int? Period { get; set; } 22 | [InverseProperty("Subject")] 23 | public virtual ICollection StudentsSubjects { get; set; } 24 | [InverseProperty("Subject")] 25 | public virtual ICollection DepartmetsSubjects { get; set; } 26 | [InverseProperty("Subject")] 27 | public virtual ICollection Ins_Subjects { get; set; } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /SchoolProject.Data/Entities/Views/ViewDepartment.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Commons; 3 | 4 | namespace SchoolProject.Data.Entities.Views 5 | { 6 | [Keyless] 7 | public class ViewDepartment : GeneralLocalizableEntity 8 | { 9 | public int DID { get; set; } 10 | public string? DNameAr { get; set; } 11 | public string? DNameEn { get; set; } 12 | public int StudentCount { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Data/Enums/StudentOrderingEnum.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Enums 2 | { 3 | public enum StudentOrderingEnum 4 | { 5 | StudID = 0, 6 | Name = 1, 7 | Address = 2, 8 | DepartmentName = 3 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Data/Helpers/ClaimsStore.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | 3 | namespace SchoolProject.Data.Helpers 4 | { 5 | public static class ClaimsStore 6 | { 7 | public static List claims = new() 8 | { 9 | new Claim("Create Student","false"), 10 | new Claim("Edit Student","false"), 11 | new Claim("Delete Student","false"), 12 | }; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Data/Helpers/EmailSettings.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Helpers 2 | { 3 | public class EmailSettings 4 | { 5 | public int Port { get; set; } 6 | public string Host { get; set; } 7 | public string FromEmail { get; set; } 8 | public string Password { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Data/Helpers/JwtSettings.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Helpers 2 | { 3 | public class JwtSettings 4 | { 5 | public string Secret { get; set; } 6 | public string Issuer { get; set; } 7 | public string Audience { get; set; } 8 | public bool ValidateIssuer { get; set; } 9 | public bool ValidateAudience { get; set; } 10 | public bool ValidateLifeTime { get; set; } 11 | public bool ValidateIssuerSigningKey { get; set; } 12 | public int AccessTokenExpireDate { get; set; } 13 | public int RefreshTokenExpireDate { get; set; } 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /SchoolProject.Data/Helpers/UserClaimModel.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Helpers 2 | { 3 | public class UserClaimModel 4 | { 5 | public int Id { get; set; } 6 | public string UserName { get; set; } 7 | public string Email { get; set; } 8 | public string PhoneNumber { get; set; } 9 | public string Role { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Data/Requests/EditRoleRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.DTOs 2 | { 3 | public class EditRoleRequest 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Data/Requests/UpdateUserClaimsRequest.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Results; 2 | 3 | namespace SchoolProject.Data.Requests 4 | { 5 | public class UpdateUserClaimsRequest : ManageUserClaimsResult 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Data/Requests/UpdateUserRolesRequest.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Results; 2 | 3 | namespace SchoolProject.Data.DTOs 4 | { 5 | public class UpdateUserRolesRequest : ManageUserRolesResult 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Data/Results/GetInstructorFunctionResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Results 2 | { 3 | public class GetInstructorFunctionResult 4 | { 5 | public int Id { get; set; } 6 | public string? ENameAr { get; set; } 7 | public string? ENameEn { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Data/Results/JwtAuthResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Results 2 | { 3 | public class JwtAuthResult 4 | { 5 | public string AccessToken { get; set; } 6 | public RefreshToken refreshToken { get; set; } 7 | } 8 | public class RefreshToken 9 | { 10 | public string UserName { get; set; } 11 | public string TokenString { get; set; } 12 | public DateTime ExpireAt { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Data/Results/ManageUserClaimsResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Results 2 | { 3 | public class ManageUserClaimsResult 4 | { 5 | public int UserId { get; set; } 6 | public List userClaims { get; set; } 7 | } 8 | public class UserClaims 9 | { 10 | public string Type { get; set; } 11 | public bool Value { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SchoolProject.Data/Results/ManageUserRolesResult.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Data.Results 2 | { 3 | public class ManageUserRolesResult 4 | { 5 | public int UserId { get; set; } 6 | public List userRoles { get; set; } 7 | } 8 | public class UserRoles 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public bool HasRole { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Data/SchoolProject.Data.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/Functions/IInstructorFunctionsRepository.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Infrustructure.Abstracts.Functions 2 | { 3 | public interface IInstructorFunctionsRepository 4 | { 5 | public decimal GetSalarySummationOfInstructor(string query); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/IDepartmentRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Infrustructure.InfrastructureBases; 3 | 4 | namespace SchoolProject.Infrustructure.Abstracts 5 | { 6 | public interface IDepartmentRepository : IGenericRepositoryAsync 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/IInstructorsRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Infrustructure.InfrastructureBases; 3 | 4 | namespace SchoolProject.Infrustructure.Abstracts 5 | { 6 | public interface IInstructorsRepository : IGenericRepositoryAsync 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/IRefreshTokenRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Identity; 2 | using SchoolProject.Infrustructure.InfrastructureBases; 3 | 4 | namespace SchoolProject.Infrustructure.Abstracts 5 | { 6 | public interface IRefreshTokenRepository : IGenericRepositoryAsync 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/IStudentRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Infrustructure.InfrastructureBases; 3 | 4 | namespace SchoolProject.Infrustructure.Abstracts 5 | { 6 | public interface IStudentRepository : IGenericRepositoryAsync 7 | { 8 | public Task> GetStudentsListAsync(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/ISubjectRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Infrustructure.InfrastructureBases; 3 | 4 | namespace SchoolProject.Infrustructure.Abstracts 5 | { 6 | public interface ISubjectRepository : IGenericRepositoryAsync 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/Procedures/IDepartmentStudentCountProcRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Procedures; 2 | 3 | namespace SchoolProject.Infrustructure.Abstracts.Procedures 4 | { 5 | public interface IDepartmentStudentCountProcRepository 6 | { 7 | public Task> GetDepartmentStudentCountProcs(DepartmentStudentCountProcParameters parameters); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Abstracts/Views/IViewRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Infrustructure.InfrastructureBases; 2 | 3 | namespace SchoolProject.Infrustructure.Abstracts.Views 4 | { 5 | public interface IViewRepository : IGenericRepositoryAsync where T : class 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Configurations/DepartmentConfigurations.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using SchoolProject.Data.Entities; 4 | 5 | namespace SchoolProject.Infrustructure.Configurations 6 | { 7 | public class DepartmentConfigurations : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | 12 | builder.HasKey(x => x.DID); 13 | builder.Property(x => x.DNameAr).HasMaxLength(500); 14 | 15 | builder.HasMany(x => x.Students) 16 | .WithOne(x => x.Department) 17 | .HasForeignKey(x => x.DID) 18 | .OnDelete(DeleteBehavior.Restrict); 19 | 20 | builder.HasOne(x => x.Instructor) 21 | .WithOne(x => x.departmentManager) 22 | .HasForeignKey(x => x.InsManager) 23 | .OnDelete(DeleteBehavior.Restrict); 24 | 25 | 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Configurations/DepartmentSubjectConfigurations.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using SchoolProject.Data.Entities; 4 | 5 | namespace SchoolProject.Infrustructure.Configurations 6 | { 7 | public class DepartmentSubjectConfigurations : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder.HasKey(x => new { x.SubID, x.DID }); 12 | 13 | builder.HasOne(ds => ds.Department) 14 | .WithMany(d => d.DepartmentSubjects) 15 | .HasForeignKey(ds => ds.DID); 16 | 17 | builder.HasOne(ds => ds.Subject) 18 | .WithMany(d => d.DepartmetsSubjects) 19 | .HasForeignKey(ds => ds.SubID); 20 | 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Configurations/Ins_SubjectConfigurations.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using SchoolProject.Data.Entities; 4 | 5 | namespace SchoolProject.Infrustructure.Configurations 6 | { 7 | public class Ins_SubjectConfigurations : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder 12 | .HasKey(x => new { x.SubId, x.InsId }); 13 | 14 | 15 | builder.HasOne(ds => ds.instructor) 16 | .WithMany(d => d.Ins_Subjects) 17 | .HasForeignKey(ds => ds.InsId); 18 | 19 | builder.HasOne(ds => ds.Subject) 20 | .WithMany(d => d.Ins_Subjects) 21 | .HasForeignKey(ds => ds.SubId); 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Configurations/InstructorConfigurations.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using SchoolProject.Data.Entities; 4 | 5 | namespace SchoolProject.Infrustructure.Configurations 6 | { 7 | public class InstructorConfigurations : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder 12 | .HasOne(x => x.Supervisor) 13 | .WithMany(x => x.Instructors) 14 | .HasForeignKey(x => x.SupervisorId) 15 | .OnDelete(DeleteBehavior.Restrict); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Configurations/StudentSubjectConfigurations.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using SchoolProject.Data.Entities; 4 | 5 | namespace SchoolProject.Infrustructure.Configurations 6 | { 7 | public class StudentSubjectConfigurations : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | builder 12 | .HasKey(x => new { x.SubID, x.StudID }); 13 | 14 | 15 | builder.HasOne(ds => ds.Student) 16 | .WithMany(d => d.StudentSubject) 17 | .HasForeignKey(ds => ds.StudID); 18 | 19 | builder.HasOne(ds => ds.Subject) 20 | .WithMany(d => d.StudentsSubjects) 21 | .HasForeignKey(ds => ds.SubID); 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Context/ApplicationDBContext.cs: -------------------------------------------------------------------------------- 1 | using EntityFrameworkCore.EncryptColumn.Extension; 2 | using EntityFrameworkCore.EncryptColumn.Interfaces; 3 | using EntityFrameworkCore.EncryptColumn.Util; 4 | using Microsoft.AspNetCore.Identity; 5 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 6 | using Microsoft.EntityFrameworkCore; 7 | using SchoolProject.Data.Entities; 8 | using SchoolProject.Data.Entities.Identity; 9 | using SchoolProject.Data.Entities.Views; 10 | using System.Reflection; 11 | 12 | namespace SchoolProject.Infrustructure.Data 13 | { 14 | public class ApplicationDBContext : IdentityDbContext, IdentityUserRole, IdentityUserLogin, IdentityRoleClaim, IdentityUserToken> 15 | { 16 | private readonly IEncryptionProvider _encryptionProvider; 17 | public ApplicationDBContext() 18 | { 19 | 20 | } 21 | public ApplicationDBContext(DbContextOptions options) : base(options) 22 | { 23 | _encryptionProvider=new GenerateEncryptionProvider("8a4dcaaec64d412380fe4b02193cd26f"); 24 | } 25 | public DbSet User { get; set; } 26 | public DbSet departments { get; set; } 27 | public DbSet students { get; set; } 28 | public DbSet departmetSubjects { get; set; } 29 | public DbSet subjects { get; set; } 30 | public DbSet studentSubjects { get; set; } 31 | public DbSet UserRefreshToken { get; set; } 32 | 33 | #region Views 34 | public DbSet ViewDepartment { get; set; } 35 | #endregion 36 | 37 | protected override void OnModelCreating(ModelBuilder modelBuilder) 38 | { 39 | base.OnModelCreating(modelBuilder); 40 | modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); 41 | modelBuilder.UseEncryption(_encryptionProvider); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/InfrastructureBases/IGenericRepositoryAsync.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Storage; 2 | 3 | namespace SchoolProject.Infrustructure.InfrastructureBases 4 | { 5 | public interface IGenericRepositoryAsync where T : class 6 | { 7 | Task DeleteRangeAsync(ICollection entities); 8 | Task GetByIdAsync(int id); 9 | Task SaveChangesAsync(); 10 | IDbContextTransaction BeginTransaction(); 11 | void Commit(); 12 | void RollBack(); 13 | IQueryable GetTableNoTracking(); 14 | IQueryable GetTableAsTracking(); 15 | Task AddAsync(T entity); 16 | Task AddRangeAsync(ICollection entities); 17 | Task UpdateAsync(T entity); 18 | Task UpdateRangeAsync(ICollection entities); 19 | Task DeleteAsync(T entity); 20 | 21 | Task BeginTransactionAsync(); 22 | Task CommitAsync(); 23 | Task RollBackAsync(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Migrations/20230805113940_AddImageFieldInInstructortable.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace SchoolProject.Infrustructure.Migrations 6 | { 7 | /// 8 | public partial class AddImageFieldInInstructortable : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "Image", 15 | table: "Instructor", 16 | type: "nvarchar(max)", 17 | nullable: true); 18 | } 19 | 20 | /// 21 | protected override void Down(MigrationBuilder migrationBuilder) 22 | { 23 | migrationBuilder.DropColumn( 24 | name: "Image", 25 | table: "Instructor"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/ModuleInfrastructureDependencies.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using SchoolProject.Data.Entities.Views; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Abstracts.Functions; 5 | using SchoolProject.Infrustructure.Abstracts.Procedures; 6 | using SchoolProject.Infrustructure.Abstracts.Views; 7 | using SchoolProject.Infrustructure.InfrastructureBases; 8 | using SchoolProject.Infrustructure.Repositories; 9 | using SchoolProject.Infrustructure.Repositories.Functions; 10 | using SchoolProject.Infrustructure.Repositories.Procedures; 11 | using SchoolProject.Infrustructure.Repositories.Views; 12 | 13 | namespace SchoolProject.Infrustructure 14 | { 15 | public static class ModuleInfrastructureDependencies 16 | { 17 | public static IServiceCollection AddInfrastructureDependencies(this IServiceCollection services) 18 | { 19 | services.AddTransient(); 20 | services.AddTransient(); 21 | services.AddTransient(); 22 | services.AddTransient(); 23 | services.AddTransient(); 24 | services.AddTransient(typeof(IGenericRepositoryAsync<>), typeof(GenericRepositoryAsync<>)); 25 | 26 | //views 27 | services.AddTransient, ViewDepartmentRepository>(); 28 | 29 | //Procedure 30 | services.AddTransient(); 31 | 32 | //functions 33 | services.AddTransient(); 34 | 35 | return services; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/DepartmentRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories 8 | { 9 | public class DepartmentRepository : GenericRepositoryAsync, IDepartmentRepository 10 | { 11 | #region Fields 12 | private DbSet departments; 13 | #endregion 14 | 15 | #region Constructors 16 | public DepartmentRepository(ApplicationDBContext dbContext) : base(dbContext) 17 | { 18 | departments=dbContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handle Functions 23 | 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/Functions/InstructorFunctionsRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Infrustructure.Abstracts.Functions; 3 | using SchoolProject.Infrustructure.Data; 4 | using System.Data; 5 | 6 | namespace SchoolProject.Infrustructure.Repositories.Functions 7 | { 8 | public class InstructorFunctionsRepository : IInstructorFunctionsRepository 9 | { 10 | #region Fileds 11 | private readonly ApplicationDBContext _dbContext; 12 | #endregion 13 | #region Constructors 14 | public InstructorFunctionsRepository(ApplicationDBContext dbContext) 15 | { 16 | _dbContext = dbContext; 17 | } 18 | 19 | #endregion 20 | #region Handle Functions 21 | public decimal GetSalarySummationOfInstructor(string query) 22 | { 23 | using (var cmd = _dbContext.Database.GetDbConnection().CreateCommand()) 24 | { 25 | if (cmd.Connection.State!=ConnectionState.Open) 26 | { 27 | cmd.Connection.Open(); 28 | } 29 | 30 | //read From List 31 | 32 | // var reader = await cmd.ExecuteReaderAsync(); 33 | // var value = await reader.ToListAsync(); 34 | 35 | decimal response = 0; 36 | cmd.CommandText = query; 37 | var value = cmd.ExecuteScalar(); 38 | var result = value.ToString(); 39 | if (decimal.TryParse(result, out decimal d)) 40 | { 41 | response= d; 42 | } 43 | cmd.Connection.Close(); 44 | return response; 45 | } 46 | } 47 | #endregion 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/InstructorsRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories 8 | { 9 | public class InstructorsRepository : GenericRepositoryAsync, IInstructorsRepository 10 | { 11 | #region Fields 12 | private DbSet instructors; 13 | #endregion 14 | 15 | #region Constructors 16 | public InstructorsRepository(ApplicationDBContext dbContext) : base(dbContext) 17 | { 18 | instructors=dbContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handle Functions 23 | 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/Procedures/DepartmentStudentCountProcRepository.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Procedures; 2 | using SchoolProject.Infrustructure.Abstracts.Procedures; 3 | using SchoolProject.Infrustructure.Data; 4 | using StoredProcedureEFCore; 5 | 6 | namespace SchoolProject.Infrustructure.Repositories.Procedures 7 | { 8 | public class DepartmentStudentCountProcRepository : IDepartmentStudentCountProcRepository 9 | { 10 | #region Fields 11 | private readonly ApplicationDBContext _context; 12 | #endregion 13 | #region Constructors 14 | public DepartmentStudentCountProcRepository(ApplicationDBContext context) 15 | { 16 | _context = context; 17 | } 18 | #endregion 19 | #region Handle Functions 20 | public async Task> GetDepartmentStudentCountProcs(DepartmentStudentCountProcParameters parameters) 21 | { 22 | var rows = new List(); 23 | await _context.LoadStoredProc(nameof(DepartmentStudentCountProc)) 24 | .AddParam(nameof(DepartmentStudentCountProcParameters.DID), parameters.DID) 25 | .ExecAsync(async r => rows=await r.ToListAsync()); 26 | return rows; 27 | } 28 | #endregion 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/RefreshTokenRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities.Identity; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories 8 | { 9 | public class RefreshTokenRepository : GenericRepositoryAsync, IRefreshTokenRepository 10 | { 11 | #region Fields 12 | private DbSet userRefreshToken; 13 | #endregion 14 | 15 | #region Constructors 16 | public RefreshTokenRepository(ApplicationDBContext dbContext) : base(dbContext) 17 | { 18 | userRefreshToken=dbContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handle Functions 23 | 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/StudentRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories 8 | { 9 | public class StudentRepository : GenericRepositoryAsync, IStudentRepository 10 | { 11 | #region Fields 12 | private readonly DbSet _students; 13 | #endregion 14 | 15 | #region Constructors 16 | public StudentRepository(ApplicationDBContext dBContext) : base(dBContext) 17 | { 18 | _students=dBContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handles Functions 23 | public async Task> GetStudentsListAsync() 24 | { 25 | return await _students.Include(x => x.Department).ToListAsync(); 26 | } 27 | #endregion 28 | 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/SubjectRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.Infrustructure.Abstracts; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories 8 | { 9 | public class SubjectRepository : GenericRepositoryAsync, ISubjectRepository 10 | { 11 | #region Fields 12 | private DbSet subjects; 13 | #endregion 14 | 15 | #region Constructors 16 | public SubjectRepository(ApplicationDBContext dbContext) : base(dbContext) 17 | { 18 | subjects=dbContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handle Functions 23 | 24 | #endregion 25 | } 26 | } -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Repositories/Views/ViewDepartmentRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities.Views; 3 | using SchoolProject.Infrustructure.Abstracts.Views; 4 | using SchoolProject.Infrustructure.Data; 5 | using SchoolProject.Infrustructure.InfrastructureBases; 6 | 7 | namespace SchoolProject.Infrustructure.Repositories.Views 8 | { 9 | public class ViewDepartmentRepository : GenericRepositoryAsync, IViewRepository 10 | { 11 | #region Fields 12 | private DbSet viewDepartment; 13 | #endregion 14 | 15 | #region Constructors 16 | public ViewDepartmentRepository(ApplicationDBContext dbContext) : base(dbContext) 17 | { 18 | viewDepartment=dbContext.Set(); 19 | } 20 | #endregion 21 | 22 | #region Handle Functions 23 | 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/SchoolProject.Infrustructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Seeder/RoleSeeder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using SchoolProject.Data.Entities.Identity; 4 | 5 | 6 | namespace SchoolProject.Infrustructure.Seeder 7 | { 8 | public static class RoleSeeder 9 | { 10 | public static async Task SeedAsync(RoleManager _roleManager) 11 | { 12 | var rolesCount = await _roleManager.Roles.CountAsync(); 13 | if (rolesCount<=0) 14 | { 15 | 16 | await _roleManager.CreateAsync(new Role() 17 | { 18 | Name="Admin" 19 | }); 20 | await _roleManager.CreateAsync(new Role() 21 | { 22 | Name="User" 23 | }); 24 | } 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SchoolProject.Infrustructure/Seeder/UserSeeder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using SchoolProject.Data.Entities.Identity; 4 | 5 | namespace SchoolProject.Infrustructure.Seeder 6 | { 7 | public static class UserSeeder 8 | { 9 | public static async Task SeedAsync(UserManager _userManager) 10 | { 11 | var usersCount = await _userManager.Users.CountAsync(); 12 | if (usersCount <= 0) 13 | { 14 | var defaultuser = new User() 15 | { 16 | UserName = "admin", 17 | Email = "admin@project.com", 18 | FullName="schoolProject", 19 | Country="Egypt", 20 | PhoneNumber="123456", 21 | Address="Egypt", 22 | EmailConfirmed = true, 23 | PhoneNumberConfirmed = true 24 | }; 25 | await _userManager.CreateAsync(defaultuser, "M123_m"); 26 | await _userManager.AddToRoleAsync(defaultuser, "Admin"); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IApplicationUserService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Identity; 2 | 3 | namespace SchoolProject.Service.Abstracts 4 | { 5 | public interface IApplicationUserService 6 | { 7 | public Task AddUserAsync(User user, string password); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IAuthenticationService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Identity; 2 | using SchoolProject.Data.Results; 3 | using System.IdentityModel.Tokens.Jwt; 4 | namespace SchoolProject.Service.Abstracts 5 | { 6 | public interface IAuthenticationService 7 | { 8 | public Task GetJWTToken(User user); 9 | public JwtSecurityToken ReadJWTToken(string accessToken); 10 | public Task<(string, DateTime?)> ValidateDetails(JwtSecurityToken jwtToken, string AccessToken, string RefreshToken); 11 | public Task GetRefreshToken(User user, JwtSecurityToken jwtToken, DateTime? expiryDate, string refreshToken); 12 | public Task ValidateToken(string AccessToken); 13 | public Task ConfirmEmail(int? userId, string? code); 14 | public Task SendResetPasswordCode(string Email); 15 | public Task ConfirmResetPassword(string Code, string Email); 16 | public Task ResetPassword(string Email, string Password); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IAuthorizationService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.DTOs; 2 | using SchoolProject.Data.Entities.Identity; 3 | using SchoolProject.Data.Requests; 4 | using SchoolProject.Data.Results; 5 | namespace SchoolProject.Service.Abstracts 6 | { 7 | public interface IAuthorizationService 8 | { 9 | public Task AddRoleAsync(string roleName); 10 | public Task IsRoleExistByName(string roleName); 11 | public Task EditRoleAsync(EditRoleRequest request); 12 | public Task DeleteRoleAsync(int roleId); 13 | public Task IsRoleExistById(int roleId); 14 | public Task> GetRolesList(); 15 | public Task GetRoleById(int id); 16 | public Task ManageUserRolesData(User user); 17 | public Task UpdateUserRoles(UpdateUserRolesRequest request); 18 | public Task ManageUserClaimData(User user); 19 | public Task UpdateUserClaims(UpdateUserClaimsRequest request); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IDepartmentService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Data.Entities.Procedures; 3 | using SchoolProject.Data.Entities.Views; 4 | 5 | namespace SchoolProject.Service.Abstracts 6 | { 7 | public interface IDepartmentService 8 | { 9 | public Task GetDepartmentById(int id); 10 | public Task IsDepartmentIdExist(int departmentId); 11 | public Task> GetViewDepartmentDataAsync(); 12 | public Task> GetDepartmentStudentCountProcs(DepartmentStudentCountProcParameters parameters); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IEmailsService.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.Service.Abstracts 2 | { 3 | public interface IEmailsService 4 | { 5 | public Task SendEmail(string email, string Message, string? reason); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IFileService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | 3 | namespace SchoolProject.Service.Abstracts 4 | { 5 | public interface IFileService 6 | { 7 | public Task UploadImage(string Location, IFormFile file); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IInstructorService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using SchoolProject.Data.Entities; 3 | namespace SchoolProject.Service.Abstracts 4 | { 5 | public interface IInstructorService 6 | { 7 | public Task GetSalarySummationOfInstructor(); 8 | public Task IsNameArExist(string nameAr); 9 | public Task IsNameEnExist(string nameEn); 10 | public Task IsNameArExistExcludeSelf(string nameAr, int id); 11 | public Task IsNameEnExistExcludeSelf(string nameEn, int id); 12 | public Task AddInstructorAsync(Instructor instructor, IFormFile file); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.Service/Abstracts/IStudentService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities; 2 | using SchoolProject.Data.Enums; 3 | 4 | namespace SchoolProject.Service.Abstracts 5 | { 6 | public interface IStudentService 7 | { 8 | public Task> GetStudentsListAsync(); 9 | public Task GetStudentByIDWithIncludeAsync(int id); 10 | public Task GetByIDAsync(int id); 11 | public Task AddAsync(Student student); 12 | public Task IsNameArExist(string nameAr); 13 | public Task IsNameEnExist(string nameEn); 14 | public Task IsNameArExistExcludeSelf(string nameAr, int id); 15 | public Task IsNameEnExistExcludeSelf(string nameEn, int id); 16 | public Task EditAsync(Student student); 17 | public Task DeleteAsync(Student student); 18 | public IQueryable GetStudentsQuerable(); 19 | public IQueryable GetStudentsByDepartmentIDQuerable(int DID); 20 | public IQueryable FilterStudentPaginatedQuerable(StudentOrderingEnum orderingEnum, string search); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SchoolProject.Service/AuthServices/Implementations/CurrentUserService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Identity; 3 | using SchoolProject.Data.Entities.Identity; 4 | using SchoolProject.Data.Helpers; 5 | using SchoolProject.Service.AuthServices.Interfaces; 6 | 7 | namespace SchoolProject.Service.AuthServices.Implementations 8 | { 9 | public class CurrentUserService : ICurrentUserService 10 | { 11 | 12 | #region Fields 13 | private readonly IHttpContextAccessor _httpContextAccessor; 14 | private readonly UserManager _userManager; 15 | #endregion 16 | #region Constructors 17 | public CurrentUserService(IHttpContextAccessor httpContextAccessor, UserManager userManager) 18 | { 19 | _httpContextAccessor = httpContextAccessor; 20 | _userManager = userManager; 21 | } 22 | #endregion 23 | #region Functions 24 | public int GetUserId() 25 | { 26 | var userId = _httpContextAccessor.HttpContext.User.Claims.SingleOrDefault(claim => claim.Type==nameof(UserClaimModel.Id)).Value; 27 | if (userId == null) 28 | { 29 | throw new UnauthorizedAccessException(); 30 | } 31 | return int.Parse(userId); 32 | } 33 | 34 | public async Task GetUserAsync() 35 | { 36 | var userId = GetUserId(); 37 | var user = await _userManager.FindByIdAsync(userId.ToString()); 38 | if (user == null) 39 | { throw new UnauthorizedAccessException(); } 40 | return user; 41 | } 42 | 43 | public async Task> GetCurrentUserRolesAsync() 44 | { 45 | var user = await GetUserAsync(); 46 | var roles = await _userManager.GetRolesAsync(user); 47 | return roles.ToList(); 48 | } 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SchoolProject.Service/AuthServices/Interfaces/ICurrentUserService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Data.Entities.Identity; 2 | 3 | namespace SchoolProject.Service.AuthServices.Interfaces 4 | { 5 | public interface ICurrentUserService 6 | { 7 | public Task GetUserAsync(); 8 | public int GetUserId(); 9 | public Task> GetCurrentUserRolesAsync(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.Service/Implementations/ApplicationUserService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Identity; 3 | using Microsoft.AspNetCore.Mvc; 4 | using SchoolProject.Data.Entities.Identity; 5 | using SchoolProject.Infrustructure.Data; 6 | using SchoolProject.Service.Abstracts; 7 | 8 | namespace SchoolProject.Service.Implementations 9 | { 10 | public class ApplicationUserService : IApplicationUserService 11 | { 12 | #region Fields 13 | private readonly UserManager _userManager; 14 | private readonly IHttpContextAccessor _httpContextAccessor; 15 | private readonly IEmailsService _emailsService; 16 | private readonly ApplicationDBContext _applicationDBContext; 17 | private readonly IUrlHelper _urlHelper; 18 | #endregion 19 | #region Constructors 20 | public ApplicationUserService(UserManager userManager, 21 | IHttpContextAccessor httpContextAccessor, 22 | IEmailsService emailsService, 23 | ApplicationDBContext applicationDBContext, 24 | IUrlHelper urlHelper) 25 | { 26 | _userManager = userManager; 27 | _httpContextAccessor = httpContextAccessor; 28 | _emailsService = emailsService; 29 | _applicationDBContext = applicationDBContext; 30 | _urlHelper = urlHelper; 31 | } 32 | #endregion 33 | #region Handle Functions 34 | public async Task AddUserAsync(User user, string password) 35 | { 36 | var trans = await _applicationDBContext.Database.BeginTransactionAsync(); 37 | try 38 | { 39 | //if Email is Exist 40 | var existUser = await _userManager.FindByEmailAsync(user.Email); 41 | //email is Exist 42 | if (existUser != null) return "EmailIsExist"; 43 | 44 | //if username is Exist 45 | var userByUserName = await _userManager.FindByNameAsync(user.UserName); 46 | //username is Exist 47 | if (userByUserName != null) return "UserNameIsExist"; 48 | //Create 49 | var createResult = await _userManager.CreateAsync(user, password); 50 | //Failed 51 | if (!createResult.Succeeded) 52 | return string.Join(",", createResult.Errors.Select(x => x.Description).ToList()); 53 | 54 | await _userManager.AddToRoleAsync(user, "User"); 55 | 56 | //Send Confirm Email 57 | var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); 58 | var resquestAccessor = _httpContextAccessor.HttpContext.Request; 59 | var returnUrl = resquestAccessor.Scheme + "://" + resquestAccessor.Host + _urlHelper.Action("ConfirmEmail", "Authentication", new { userId = user.Id, code = code }); 60 | var message = $"To Confirm Email Click Link: Link Of Confirmation"; 61 | //$"/Api/V1/Authentication/ConfirmEmail?userId={user.Id}&code={code}"; 62 | //message or body 63 | await _emailsService.SendEmail(user.Email, message, "ConFirm Email"); 64 | 65 | await trans.CommitAsync(); 66 | return "Success"; 67 | } 68 | catch (Exception ex) 69 | { 70 | await trans.RollbackAsync(); 71 | return "Failed"; 72 | } 73 | 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SchoolProject.Service/Implementations/DepartmentService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.Data.Entities.Procedures; 4 | using SchoolProject.Data.Entities.Views; 5 | using SchoolProject.Infrustructure.Abstracts; 6 | using SchoolProject.Infrustructure.Abstracts.Procedures; 7 | using SchoolProject.Infrustructure.Abstracts.Views; 8 | using SchoolProject.Service.Abstracts; 9 | 10 | namespace SchoolProject.Service.Implementations 11 | { 12 | public class DepartmentService : IDepartmentService 13 | { 14 | #region Fields 15 | private readonly IDepartmentRepository _departmentRepository; 16 | private readonly IViewRepository _viewDepartmentRepository; 17 | private readonly IDepartmentStudentCountProcRepository _departmentStudentCountProcRepository; 18 | #endregion 19 | 20 | #region Constructors 21 | public DepartmentService(IDepartmentRepository departmentRepository, 22 | IViewRepository viewDepartmentRepository, 23 | IDepartmentStudentCountProcRepository departmentStudentCountProcRepository) 24 | { 25 | _departmentRepository= departmentRepository; 26 | _viewDepartmentRepository= viewDepartmentRepository; 27 | _departmentStudentCountProcRepository= departmentStudentCountProcRepository; 28 | } 29 | 30 | 31 | #endregion 32 | 33 | #region Handle Functions 34 | public async Task GetDepartmentById(int id) 35 | { 36 | var student = await _departmentRepository.GetTableNoTracking().Where(x => x.DID.Equals(id)) 37 | .Include(x => x.DepartmentSubjects).ThenInclude(x => x.Subject) 38 | .Include(x => x.Instructors) 39 | .Include(x => x.Instructor).FirstOrDefaultAsync(); 40 | return student; 41 | } 42 | 43 | public async Task IsDepartmentIdExist(int departmentId) 44 | { 45 | return await _departmentRepository.GetTableNoTracking().AnyAsync(x => x.DID.Equals(departmentId)); 46 | } 47 | public async Task> GetViewDepartmentDataAsync() 48 | { 49 | var viewDepartment = await _viewDepartmentRepository.GetTableNoTracking().ToListAsync(); 50 | return viewDepartment; 51 | } 52 | 53 | public async Task> GetDepartmentStudentCountProcs(DepartmentStudentCountProcParameters parameters) 54 | { 55 | return await _departmentStudentCountProcRepository.GetDepartmentStudentCountProcs(parameters); 56 | } 57 | #endregion 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SchoolProject.Service/Implementations/EmailsService.cs: -------------------------------------------------------------------------------- 1 |  2 | using MailKit.Net.Smtp; 3 | using MimeKit; 4 | using SchoolProject.Data.Helpers; 5 | using SchoolProject.Service.Abstracts; 6 | namespace SchoolProject.Service.Implementations 7 | { 8 | public class EmailsService : IEmailsService 9 | { 10 | #region Fields 11 | private readonly EmailSettings _emailSettings; 12 | #endregion 13 | #region Constructors 14 | public EmailsService(EmailSettings emailSettings) 15 | { 16 | _emailSettings = emailSettings; 17 | } 18 | 19 | #endregion 20 | #region Handle Functions 21 | public async Task SendEmail(string email, string Message, string? reason) 22 | { 23 | try 24 | { 25 | //sending the Message of passwordResetLink 26 | using (var client = new SmtpClient()) 27 | { 28 | await client.ConnectAsync(_emailSettings.Host, _emailSettings.Port, true); 29 | client.Authenticate(_emailSettings.FromEmail, _emailSettings.Password); 30 | var bodybuilder = new BodyBuilder 31 | { 32 | HtmlBody = $"{Message}", 33 | TextBody = "wellcome", 34 | }; 35 | var message = new MimeMessage 36 | { 37 | Body = bodybuilder.ToMessageBody() 38 | }; 39 | message.From.Add(new MailboxAddress("Future Team", _emailSettings.FromEmail)); 40 | message.To.Add(new MailboxAddress("testing", email)); 41 | message.Subject = reason==null ? "No Submitted" : reason; 42 | await client.SendAsync(message); 43 | await client.DisconnectAsync(true); 44 | } 45 | //end of sending email 46 | return "Success"; 47 | } 48 | catch (Exception ex) 49 | { 50 | return "Failed"; 51 | } 52 | } 53 | #endregion 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SchoolProject.Service/Implementations/FileService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.AspNetCore.Http; 3 | using SchoolProject.Service.Abstracts; 4 | 5 | namespace SchoolProject.Service.Implementations 6 | { 7 | public class FileService : IFileService 8 | { 9 | #region Fileds 10 | private readonly IWebHostEnvironment _webHostEnvironment; 11 | #endregion 12 | #region Constructors 13 | public FileService(IWebHostEnvironment webHostEnvironment) 14 | { 15 | _webHostEnvironment = webHostEnvironment; 16 | } 17 | #endregion 18 | #region Handle Functions 19 | public async Task UploadImage(string Location, IFormFile file) 20 | { 21 | var path = _webHostEnvironment.WebRootPath+"/"+Location+"/"; 22 | var extention = Path.GetExtension(file.FileName); 23 | var fileName = Guid.NewGuid().ToString().Replace("-", string.Empty)+extention; 24 | if (file.Length > 0) 25 | { 26 | try 27 | { 28 | if (!Directory.Exists(path)) 29 | { 30 | Directory.CreateDirectory(path); 31 | } 32 | using (FileStream filestreem = File.Create(path+fileName)) 33 | { 34 | await file.CopyToAsync(filestreem); 35 | await filestreem.FlushAsync(); 36 | return $"/{Location}/{fileName}"; 37 | } 38 | } 39 | catch (Exception) 40 | { 41 | return "FailedToUploadImage"; 42 | } 43 | } 44 | else 45 | { 46 | return "NoImage"; 47 | } 48 | } 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SchoolProject.Service/ModuleServiceDependencies.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using SchoolProject.Service.Abstracts; 3 | using SchoolProject.Service.AuthServices.Implementations; 4 | using SchoolProject.Service.AuthServices.Interfaces; 5 | using SchoolProject.Service.Implementations; 6 | namespace SchoolProject.Service 7 | { 8 | public static class ModuleServiceDependencies 9 | { 10 | public static IServiceCollection AddServiceDependencies(this IServiceCollection services) 11 | { 12 | services.AddTransient(); 13 | services.AddTransient(); 14 | services.AddTransient(); 15 | services.AddTransient(); 16 | services.AddTransient(); 17 | services.AddTransient(); 18 | services.AddTransient(); 19 | services.AddTransient(); 20 | services.AddTransient(); 21 | return services; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SchoolProject.Service/SchoolProject.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/AssertTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | namespace SchoolProject.XUnitTest 3 | { 4 | public class AssertTest 5 | { 6 | [Fact] 7 | public void calculate_2_sum_3_shoud_be_5_Without_fluentAssertion() 8 | { 9 | //Arrange 10 | int x = 2; 11 | int y = 3; 12 | int z; 13 | //Act 14 | z = x+y; 15 | //Assert 16 | Assert.Equal(5, z); 17 | } 18 | [Fact] 19 | public void calculate_2_sum_3_shoud_be_5_With_fluentAssertion() 20 | { 21 | //Arrange 22 | int x = 2; 23 | int y = 3; 24 | int z; 25 | //Act 26 | z = x+y; 27 | //Assert 28 | z.Should().Be(5, "sum 2 with 5 not equal 5"); 29 | } 30 | [Fact] 31 | public void string_should_be_startwith_we() 32 | { 33 | string word = "wellcome"; 34 | word.Should().StartWith("we"); 35 | } 36 | [Fact] 37 | public void string_should_be_endWith_me() 38 | { 39 | string word = "wellcome"; 40 | word.Should().EndWith("me"); 41 | } 42 | [Fact] 43 | public void string_should_Lenght_be_8() 44 | { 45 | string word = "wellcome"; 46 | word.Should().HaveLength(8); 47 | } 48 | [Fact] 49 | public void string_should_startwith_we_and_endWith_me_and_Lenght_be_8() 50 | { 51 | string word = "wellcome"; 52 | word.Should().StartWith("we").And.EndWith("me").And.HaveLength(8); 53 | } 54 | [Fact] 55 | public void string_should_be_wellcome() 56 | { 57 | string word = "wellcome"; 58 | word.Should().Be("wellcome"); 59 | } 60 | [Fact] 61 | public void string_should_be_not_null() 62 | { 63 | string word = "wellcome"; 64 | word.Should().NotBeNullOrWhiteSpace(); 65 | } 66 | [Fact] 67 | public void string_should_be_type_of_string() 68 | { 69 | string word = "wellcome"; 70 | word.Should().BeOfType(); 71 | } 72 | [Fact] 73 | public void verify_value_is_true() 74 | { 75 | bool first = true; 76 | first.Should().BeTrue(); 77 | first.Should().NotBe(false); 78 | } 79 | [Fact] 80 | public void verify_number_is_Positive() 81 | { 82 | int x = 5; 83 | x.Should().BePositive(); 84 | x.Should().BeGreaterThanOrEqualTo(5); 85 | x.Should().BeGreaterThan(4); 86 | x.Should().BeInRange(4, 6); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/MoqOperationTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using Moq; 3 | using SchoolProject.XUnitTest.MoqTest; 4 | using SchoolProject.XUnitTest.TestModels; 5 | 6 | namespace SchoolProject.XUnitTest 7 | { 8 | public class MoqOperationTest 9 | { 10 | private readonly Mock> _mockService = new(); 11 | [Fact] 12 | public void Add_Car() 13 | { 14 | //Arrange 15 | var car = new Car() { Id=2, Name="Toyota", Color="Red" }; 16 | var carmoqService = new CarMoqService(_mockService.Object); 17 | //act 18 | var addResult = carmoqService.AddCar(car); 19 | var carList = carmoqService.GetAll(); 20 | //Assert 21 | addResult.Should().BeTrue(); 22 | carList.Should().NotBeNull(); 23 | carList.Should().HaveCount(1); 24 | } 25 | //[Fact] 26 | //public void Remove_Car() 27 | //{ 28 | // //Arrange 29 | // var car = new Car() { Id=2, Name="Toyota", Color="Red" }; 30 | // //act 31 | // var removeResult = _carMoqService.RemoveCar(2); 32 | // var carList = _carMoqService.GetAll(); 33 | // //Assert 34 | // carList.Should().HaveCount(1); 35 | //} 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/MoqTest/CarMoqService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.XUnitTest.TestModels; 2 | 3 | namespace SchoolProject.XUnitTest.MoqTest 4 | { 5 | public class CarMoqService : ICarMoqService 6 | { 7 | public List carList; 8 | 9 | public CarMoqService(List cars) 10 | { 11 | carList = cars; 12 | } 13 | public bool AddCar(Car car) 14 | { 15 | carList.Add(car); 16 | return true; 17 | } 18 | 19 | public List GetAll() 20 | { 21 | return carList; 22 | } 23 | 24 | public bool RemoveCar(int? id) 25 | { 26 | if (id == null) return false; 27 | var car = carList.Find(x => x.Id == id); 28 | if (car == null) return false; 29 | return carList.Remove(car); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/MoqTest/ICarMoqService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.XUnitTest.TestModels; 2 | 3 | namespace SchoolProject.XUnitTest.MoqTest 4 | { 5 | public interface ICarMoqService 6 | { 7 | public bool AddCar(Car car); 8 | public bool RemoveCar(int? id); 9 | public List GetAll(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/SchoolProject.XUnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | all 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Always 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/ServicesTest/ExtensionMethod/ExtensionMethodTest.cs: -------------------------------------------------------------------------------- 1 |  2 | using EntityFrameworkCore.Testing.Common; 3 | using FluentAssertions; 4 | using Moq; 5 | using SchoolProject.Core.Wrappers; 6 | using SchoolProject.Data.Entities; 7 | using SchoolProject.XUnitTest.Wrappers.Interfaces; 8 | 9 | namespace SchoolProject.XUnitTest.ServicesTest.ExtensionMethod 10 | { 11 | public class ExtensionMethodTest 12 | { 13 | private readonly Mock> _paginatedServiceMock; 14 | public ExtensionMethodTest() 15 | { 16 | _paginatedServiceMock=new(); 17 | } 18 | [Theory] 19 | [InlineData(1, 10)] 20 | public async Task ToPaginatedListAsync_Should_Return_List(int pageNumber, int pageSize) 21 | { 22 | //Arrange 23 | 24 | var department = new Department() { DID=1, DNameAr="هندسة البرمجيات", DNameEn="SE" }; 25 | 26 | var studentList = new AsyncEnumerable(new List 27 | { 28 | new Student(){ StudID=1, Address="Alex", DID=1, NameAr="محمد",NameEn="mohamed",Department=department} 29 | }); 30 | var paginatedResult = new PaginatedResult(studentList.ToList()); 31 | _paginatedServiceMock.Setup(x => x.ReturnPaginatedResult(studentList, pageNumber, pageSize)).Returns(Task.FromResult(paginatedResult)); 32 | //Act 33 | var result = await _paginatedServiceMock.Object.ReturnPaginatedResult(studentList, pageNumber, pageSize); 34 | //Assert 35 | result.Data.Should().NotBeNullOrEmpty(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/TestModels/Car.cs: -------------------------------------------------------------------------------- 1 | namespace SchoolProject.XUnitTest.TestModels 2 | { 3 | public class Car 4 | { 5 | public int Id { get; set; } 6 | public string? Name { get; set; } 7 | public string? Color { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/TestModels/PassDataToParamUsingMemberData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | 3 | namespace SchoolProject.XUnitTest.TestModels 4 | { 5 | public class PassDataToParamUsingMemberData : IEnumerable 6 | { 7 | public static IEnumerable GetParamData() 8 | { 9 | return new List 10 | { 11 | new object[]{1}, 12 | new object[]{2} 13 | }; 14 | } 15 | public IEnumerator GetEnumerator() 16 | { 17 | return (IEnumerator)GetParamData(); 18 | } 19 | 20 | IEnumerator IEnumerable.GetEnumerator() 21 | { 22 | return GetEnumerator(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/TestModels/PassDataUsingClassData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | 3 | namespace SchoolProject.XUnitTest.TestModels 4 | { 5 | public class PassDataUsingClassData : IEnumerable 6 | { 7 | private readonly List data = new List() 8 | { 9 | new object[] {1}, 10 | new object[] {2} 11 | }; 12 | public IEnumerator GetEnumerator() 13 | { 14 | return data.GetEnumerator(); 15 | } 16 | 17 | IEnumerator IEnumerable.GetEnumerator() 18 | { 19 | return GetEnumerator(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/Wrappers/Implementations/PaginatedService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Wrappers; 2 | using SchoolProject.Data.Entities; 3 | using SchoolProject.XUnitTest.Wrappers.Interfaces; 4 | 5 | namespace SchoolProject.XUnitTest.Wrappers.Implementations 6 | { 7 | public class PaginatedService : IPaginatedService 8 | { 9 | public async Task> ReturnPaginatedResult(IQueryable source, int pageNumber, int pageSize) 10 | { 11 | return await source.ToPaginatedListAsync(pageNumber, pageSize); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/Wrappers/Interfaces/IPaginatedService.cs: -------------------------------------------------------------------------------- 1 | using SchoolProject.Core.Wrappers; 2 | 3 | namespace SchoolProject.XUnitTest.Wrappers.Interfaces 4 | { 5 | public interface IPaginatedService 6 | { 7 | public Task> ReturnPaginatedResult(IQueryable source, int pageNumber, int pageSize); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SchoolProject.XUnitTest/xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "parallelizeAssembly": true, 3 | "parallelizeTestCollections": true 4 | } 5 | --------------------------------------------------------------------------------