From c5701b04a62a2485208cb770fc84e63876bd1ce0 Mon Sep 17 00:00:00 2001 From: Vladislav Quilin Date: Mon, 19 Aug 2024 13:49:03 +0200 Subject: [PATCH 1/4] [DM.CA] Solution folder restructure --- DM.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DM.sln b/DM.sln index c8f3d377..98081eef 100644 --- a/DM.sln +++ b/DM.sln @@ -209,8 +209,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {37EE71A5-6F98-42E7-B92F-3E2B65C67850} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} - {28709B36-C22C-4EB9-906F-19CDCC769338} = {37EE71A5-6F98-42E7-B92F-3E2B65C67850} - {6DD9DA97-AAFF-46D4-9313-367998B98CF9} = {37EE71A5-6F98-42E7-B92F-3E2B65C67850} {755C13DD-F19B-450A-BC2D-5C195545DCE8} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} {2672341A-1DFD-4FDF-8D36-BFF07177C7DB} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} {74044CFF-FF4E-4604-AB39-018D19914357} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} @@ -246,5 +244,7 @@ Global {456E0B6D-8774-443B-B395-D8B6F16EF71C} = {DB521FBE-9B99-4349-9736-6C3E6E418964} {550DC966-8960-4F98-BA6B-BEDBA73BB431} = {37EE71A5-6F98-42E7-B92F-3E2B65C67850} {EAA9F9E3-2684-4C5C-BC70-403F8CE1C4A1} = {60E4E464-934E-42F0-8137-3F2BA8E3063B} + {6DD9DA97-AAFF-46D4-9313-367998B98CF9} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} + {28709B36-C22C-4EB9-906F-19CDCC769338} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} EndGlobalSection EndGlobal From baa3deed903f5e81387b60838d4e72b83697674a Mon Sep 17 00:00:00 2001 From: Vladislav Quilin Date: Mon, 19 Aug 2024 19:51:22 +0200 Subject: [PATCH 2/4] [DM.CA] Bypass cancellation tokens from controller endpoints --- .../Factories/SessionFactory.cs | 16 +-- .../Implementation/AuthenticationService.cs | 85 ++++++--------- .../Implementation/IAuthenticationService.cs | 14 ++- .../Security/ISymmetricCryptoService.cs | 7 +- .../Security/SecurityManager.cs | 16 +-- .../TripleDesSymmetricCryptoService.cs | 9 +- .../Repositories/AuthenticationRepository.cs | 61 +++++------ .../Repositories/IAuthenticationRepository.cs | 28 +++-- .../Likes/ILikeRepository.cs | 7 +- .../BusinessProcesses/Likes/LikeRepository.cs | 24 ++--- .../Likes/LikeServiceBase.cs | 35 +++--- .../IUnreadCountersRepository.cs | 43 +++++--- .../UnreadCountersRepository.cs | 91 ++++++++-------- .../EntitiesCounterFillExtensions.cs | 37 +++++-- .../Activation/ActivationRepository.cs | 23 ++-- .../Account/Activation/ActivationService.cs | 32 ++---- .../Activation/IActivationRepository.cs | 8 +- .../Account/Activation/IActivationService.cs | 4 +- .../Confirmation/EmailChangeMailSender.cs | 5 +- .../Confirmation/IEmailChangeMailSender.cs | 4 +- .../EmailChange/EmailChangeRepository.cs | 25 ++--- .../Account/EmailChange/EmailChangeService.cs | 39 +++---- .../EmailChange/IEmailChangeRepository.cs | 7 +- .../EmailChange/IEmailChangeService.cs | 4 +- .../EmailChange/UserEmailChangeValidator.cs | 4 +- .../IPasswordChangeRepository.cs | 11 +- .../PasswordChange/IPasswordChangeService.cs | 4 +- .../PasswordChangeRepository.cs | 14 +-- .../PasswordChange/PasswordChangeService.cs | 43 +++----- .../UserPasswordChangeValidator.cs | 2 +- .../Confirmation/IPasswordResetEmailSender.cs | 4 +- .../Confirmation/PasswordResetEmailSender.cs | 25 ++--- .../PasswordReset/IPasswordResetRepository.cs | 4 +- .../PasswordReset/IPasswordResetService.cs | 4 +- .../PasswordReset/PasswordResetRepository.cs | 17 +-- .../PasswordReset/PasswordResetService.cs | 39 +++---- .../UserPasswordResetValidator.cs | 4 +- .../Confirmation/IRegistrationMailSender.cs | 4 +- .../Confirmation/RegistrationMailSender.cs | 3 +- .../Registration/IRegistrationRepository.cs | 3 +- .../Registration/IRegistrationService.cs | 4 +- .../Registration/RegistrationRepository.cs | 24 ++--- .../Registration/RegistrationService.cs | 45 +++----- .../ITokenVerificationRepository.cs | 4 +- .../Verification/ITokenVerificationService.cs | 4 +- .../TokenVerificationRepository.cs | 21 ++-- .../Verification/TokenVerificationService.cs | 17 +-- .../Chat/Creating/ChatCreatingRepository.cs | 24 ++--- .../Chat/Creating/ChatCreatingService.cs | 39 ++----- .../Chat/Creating/IChatCreatingRepository.cs | 4 +- .../Chat/Creating/IChatCreatingService.cs | 4 +- .../Chat/Reading/ChatReadingRepository.cs | 41 +++---- .../Chat/Reading/ChatReadingService.cs | 31 +++--- .../Chat/Reading/IChatReadingRepository.cs | 13 ++- .../Chat/Reading/IChatReadingService.cs | 10 +- .../Creating/IMessageCreatingRepository.cs | 5 +- .../Creating/IMessageCreatingService.cs | 4 +- .../Creating/MessageCreatingRepository.cs | 24 ++--- .../Creating/MessageCreatingService.cs | 55 +++------- .../Deleting/IMessageDeletingService.cs | 4 +- .../Deleting/MessageDeletingService.cs | 3 +- .../Reading/ConversationReadingRepository.cs | 44 ++++---- .../Reading/ConversationReadingService.cs | 60 +++++------ .../Reading/IConversationReadingRepository.cs | 20 ++-- .../Reading/IConversationReadingService.cs | 16 ++- .../Reading/IMessageReadingRepository.cs | 10 +- .../Reading/IMessageReadingService.cs | 8 +- .../Reading/MessageReadingRepository.cs | 30 ++---- .../Reading/MessageReadingService.cs | 33 ++---- .../Polls/Creating/IPollCreatingRepository.cs | 4 +- .../Polls/Creating/IPollCreatingService.cs | 4 +- .../Polls/Creating/PollCreatingRepository.cs | 16 ++- .../Polls/Creating/PollCreatingService.cs | 35 ++---- .../Polls/Reading/IPollReadingRepository.cs | 10 +- .../Polls/Reading/IPollReadingService.cs | 8 +- .../Polls/Reading/PollReadingRepository.cs | 23 ++-- .../Polls/Reading/PollReadingService.cs | 32 ++---- .../Polls/Voting/IPollVotingRepository.cs | 4 +- .../Polls/Voting/IPollVotingService.cs | 4 +- .../Polls/Voting/PollVotingRepository.cs | 14 ++- .../Polls/Voting/PollVotingService.cs | 31 ++---- .../Creating/IReviewCreatingRepository.cs | 4 +- .../Creating/IReviewCreatingService.cs | 4 +- .../Creating/ReviewCreatingRepository.cs | 24 ++--- .../Reviews/Creating/ReviewCreatingService.cs | 35 ++---- .../Deleting/IReviewDeletingService.cs | 4 +- .../Reviews/Deleting/ReviewDeletingService.cs | 31 ++---- .../Reading/IReviewReadingRepository.cs | 10 +- .../Reviews/Reading/IReviewReadingService.cs | 8 +- .../Reading/ReviewReadingRepository.cs | 47 ++++---- .../Reviews/Reading/ReviewReadingService.cs | 32 ++---- .../Updating/IReviewUpdatingRepository.cs | 4 +- .../Updating/IReviewUpdatingService.cs | 4 +- .../Updating/ReviewUpdatingRepository.cs | 24 ++--- .../Reviews/Updating/ReviewUpdatingService.cs | 37 ++----- .../Users/Reading/IUserReadingRepository.cs | 13 ++- .../Users/Reading/IUserReadingService.cs | 11 +- .../Users/Reading/UserReadingRepository.cs | 41 +++---- .../Users/Reading/UserReadingService.cs | 31 ++---- .../Users/Updating/IUserUpdatingRepository.cs | 5 +- .../Users/Updating/IUserUpdatingService.cs | 8 +- .../Users/Updating/UserUpdatingRepository.cs | 24 ++--- .../Users/Updating/UserUpdatingService.cs | 55 ++++------ .../RelationalStorage/IUpdateBuilder.cs | 3 +- .../RelationalStorage/UpdateBuilder.cs | 3 +- .../Authorization/ForumIntentionResolver.cs | 12 +-- .../Creating/CommentaryCreatingRepository.cs | 20 ++-- .../Creating/CommentaryCreatingService.cs | 55 +++------- .../Creating/ICommentaryCreatingRepository.cs | 5 +- .../Creating/ICommentaryCreatingService.cs | 4 +- .../Deleting/CommentaryDeletingRepository.cs | 30 ++---- .../Deleting/CommentaryDeletingService.cs | 40 +++---- .../Deleting/ICommentaryDeletingRepository.cs | 11 +- .../Deleting/ICommentaryDeletingService.cs | 4 +- .../Reading/CommentaryReadingRepository.cs | 30 ++---- .../Reading/CommentaryReadingService.cs | 53 ++++----- .../Reading/ICommentaryReadingRepository.cs | 10 +- .../Reading/ICommentaryReadingService.cs | 14 ++- .../Updating/CommentaryUpdatingRepository.cs | 24 ++--- .../Updating/CommentaryUpdatingService.cs | 46 +++----- .../Updating/ICommentaryUpdatingRepository.cs | 4 +- .../Updating/ICommentaryUpdatingService.cs | 4 +- .../Common/AccessPolicyConverter.cs | 8 +- .../Fora/ForumReadingService.cs | 47 ++++---- .../BusinessProcesses/Fora/ForumRepository.cs | 6 +- .../Fora/IForumReadingService.cs | 10 +- .../Fora/IForumRepository.cs | 4 +- .../BusinessProcesses/Likes/ILikeService.cs | 13 ++- .../BusinessProcesses/Likes/LikeService.cs | 55 ++++------ .../Moderation/IModeratorRepository.cs | 4 +- .../Moderation/IModeratorsReadingService.cs | 4 +- .../Moderation/ModeratorRepository.cs | 21 ++-- .../Moderation/ModeratorsReadingService.cs | 23 ++-- .../Creating/ITopicCreatingRepository.cs | 4 +- .../Topics/Creating/ITopicCreatingService.cs | 4 +- .../Creating/TopicCreatingRepository.cs | 23 ++-- .../Topics/Creating/TopicCreatingService.cs | 51 +++------ .../Topics/Deleting/ITopicDeletingService.cs | 4 +- .../Topics/Deleting/TopicDeletingService.cs | 42 +++----- .../Topics/Reading/ITopicReadingRepository.cs | 8 +- .../Topics/Reading/ITopicReadingService.cs | 11 +- .../Topics/Reading/TopicReadingRepository.cs | 6 +- .../Topics/Reading/TopicReadingService.cs | 54 ++++------ .../Updating/ITopicUpdatingRepository.cs | 4 +- .../Topics/Updating/ITopicUpdatingService.cs | 4 +- .../Updating/TopicUpdatingRepository.cs | 23 ++-- .../Topics/Updating/TopicUpdatingService.cs | 54 +++------- .../Creating/BlacklistCreatingRepository.cs | 23 ++-- .../Creating/BlacklistCreatingService.cs | 48 +++------ .../Creating/IBlacklistCreatingRepository.cs | 4 +- .../Creating/IBlacklistCreatingService.cs | 4 +- .../Deleting/BlacklistDeletingRepository.cs | 3 +- .../Deleting/BlacklistDeletingService.cs | 47 +++----- .../Deleting/IBlacklistDeletingRepository.cs | 4 +- .../Deleting/IBlacklistDeletingService.cs | 4 +- .../Reading/BlacklistReadingRepository.cs | 12 ++- .../Reading/BlacklistReadingService.cs | 29 ++--- .../Reading/IBlacklistReadingRepository.cs | 4 +- .../Reading/IBlacklistReadingService.cs | 4 +- .../Creating/CharacterCreatingRepository.cs | 24 ++--- .../Creating/CharacterCreatingService.cs | 51 +++------ .../Creating/ICharacterCreatingRepository.cs | 5 +- .../Creating/ICharacterCreatingService.cs | 4 +- .../Deleting/CharacterDeletingService.cs | 40 +++---- .../Deleting/ICharacterDeletingService.cs | 4 +- .../Reading/CharacterReadingRepository.cs | 33 ++---- .../Reading/CharacterReadingService.cs | 51 ++++----- .../Reading/ICharacterReadingRepository.cs | 7 +- .../Reading/ICharacterReadingService.cs | 10 +- .../Shared/CharacterAttributeValueFiller.cs | 21 ++-- .../Shared/CharacterValidationRepository.cs | 30 ++---- .../Shared/ICharacterAttributeValueFiller.cs | 4 +- .../Shared/ICharacterValidationRepository.cs | 6 +- .../Updating/CharacterUpdatingRepository.cs | 42 +++----- .../Updating/CharacterUpdatingService.cs | 51 +++------ .../Updating/ICharacterUpdatingRepository.cs | 10 +- .../Updating/ICharacterUpdatingService.cs | 4 +- .../Claims/Creating/CharacterClaimApprove.cs | 17 +-- .../Claims/Creating/ICharacterClaimApprove.cs | 4 +- .../Claims/Creating/IReaderClaimApprove.cs | 4 +- .../Creating/IRoomClaimsCreatingRepository.cs | 10 +- .../Creating/IRoomClaimsCreatingService.cs | 4 +- .../Claims/Creating/ReaderClaimApprove.cs | 17 +-- .../Creating/RoomClaimsCreatingRepository.cs | 31 ++---- .../Creating/RoomClaimsCreatingService.cs | 60 ++++------- .../Deleting/IRoomClaimsDeletingRepository.cs | 4 +- .../Deleting/IRoomClaimsDeletingService.cs | 4 +- .../Deleting/RoomClaimsDeletingRepository.cs | 17 +-- .../Deleting/RoomClaimsDeletingService.cs | 45 +++----- .../Reading/IRoomClaimsReadingRepository.cs | 10 +- .../Reading/IRoomClaimsReadingService.cs | 12 ++- .../Reading/RoomClaimsReadingRepository.cs | 57 ++++------ .../Reading/RoomClaimsReadingService.cs | 29 ++--- .../Updating/IRoomClaimsUpdatingRepository.cs | 4 +- .../Updating/IRoomClaimsUpdatingService.cs | 4 +- .../Updating/RoomClaimsUpdatingRepository.cs | 23 ++-- .../Updating/RoomClaimsUpdatingService.cs | 47 +++----- .../Creating/CommentaryCreatingRepository.cs | 23 ++-- .../Creating/CommentaryCreatingService.cs | 51 +++------ .../Creating/ICommentaryCreatingRepository.cs | 4 +- .../Creating/ICommentaryCreatingService.cs | 4 +- .../Deleting/CommentaryDeletingService.cs | 42 +++----- .../Deleting/ICommentaryDeletingService.cs | 4 +- .../Reading/CommentaryReadingRepository.cs | 37 +++---- .../Reading/CommentaryReadingService.cs | 47 +++----- .../Reading/ICommentaryReadingRepository.cs | 10 +- .../Reading/ICommentaryReadingService.cs | 11 +- .../Updating/CommentaryUpdatingRepository.cs | 23 ++-- .../Updating/CommentaryUpdatingService.cs | 45 +++----- .../Updating/ICommentaryUpdatingRepository.cs | 4 +- .../Updating/ICommentaryUpdatingService.cs | 4 +- .../AssistantAssignment/AssignmentService.cs | 3 +- .../AssistantAssignment/IAssignmentService.cs | 4 +- .../Games/Creating/GameCreatingRepository.cs | 29 ++--- .../Games/Creating/GameCreatingService.cs | 82 +++++--------- .../Games/Creating/IGameCreatingRepository.cs | 4 +- .../Games/Creating/IGameCreatingService.cs | 3 +- .../Games/Deleting/GameDeletingService.cs | 35 ++---- .../Games/Deleting/IGameDeletingService.cs | 4 +- .../Games/Reading/GameReadingRepository.cs | 89 ++++++--------- .../Games/Reading/GameReadingService.cs | 95 +++++++--------- .../Games/Reading/IGameReadingRepository.cs | 29 +++-- .../Games/Reading/IGameReadingService.cs | 19 ++-- .../Games/Shared/IUserRepository.cs | 3 +- .../Games/Shared/UserRepository.cs | 16 +-- .../Games/Updating/GameUpdatingRepository.cs | 26 ++--- .../Games/Updating/GameUpdatingService.cs | 66 ++++-------- .../Games/Updating/IGameUpdatingRepository.cs | 4 +- .../Games/Updating/IGameUpdatingService.cs | 4 +- .../BusinessProcesses/Likes/ILikeService.cs | 7 +- .../BusinessProcesses/Likes/LikeService.cs | 39 +++---- .../IPendingPostCreatingRepository.cs | 4 +- .../Creating/IPendingPostCreatingService.cs | 4 +- .../Creating/PendingPostCreatingRepository.cs | 24 ++--- .../Creating/PendingPostCreatingService.cs | 51 +++------ .../IPendingPostDeletingRepository.cs | 7 +- .../Deleting/IPendingPostDeletingService.cs | 4 +- .../Deleting/PendingPostDeletingRepository.cs | 29 ++--- .../Deleting/PendingPostDeletingService.cs | 27 ++--- .../Posts/Creating/IPostCreatingRepository.cs | 5 +- .../Posts/Creating/IPostCreatingService.cs | 4 +- .../Posts/Creating/PostCreatingRepository.cs | 24 ++--- .../Posts/Creating/PostCreatingService.cs | 55 +++------- .../Posts/Deleting/IPostDeletingService.cs | 4 +- .../Posts/Deleting/PostDeletingService.cs | 42 +++----- .../Posts/Reading/IPostReadingRepository.cs | 10 +- .../Posts/Reading/IPostReadingService.cs | 11 +- .../Posts/Reading/PostReadingRepository.cs | 42 +++----- .../Posts/Reading/PostReadingService.cs | 48 +++------ .../Posts/Updating/IPostUpdatingRepository.cs | 4 +- .../Posts/Updating/IPostUpdatingService.cs | 4 +- .../Posts/Updating/PostUpdatingRepository.cs | 23 ++-- .../Posts/Updating/PostUpdatingService.cs | 55 +++------- .../Reading/IReadersReadingRepository.cs | 4 +- .../Readers/Reading/IReadersReadingService.cs | 4 +- .../Reading/ReadersReadingRepository.cs | 25 ++--- .../Readers/Reading/ReadersReadingService.cs | 27 ++--- .../IReadingSubscribingRepository.cs | 10 +- .../Subscribing/IReadingSubscribingService.cs | 7 +- .../ReadingSubscribingRepository.cs | 28 ++--- .../Subscribing/ReadingSubscribingService.cs | 45 +++----- .../Rooms/Creating/IRoomCreatingRepository.cs | 7 +- .../Rooms/Creating/IRoomCreatingService.cs | 4 +- .../Rooms/Creating/RoomCreatingRepository.cs | 32 ++---- .../Rooms/Creating/RoomCreatingService.cs | 53 +++------ .../Rooms/Deleting/IRoomDeletingService.cs | 4 +- .../Rooms/Deleting/RoomDeletingService.cs | 46 +++----- .../Rooms/Reading/IRoomReadingRepository.cs | 7 +- .../Rooms/Reading/IRoomReadingService.cs | 7 +- .../Rooms/Reading/RoomReadingRepository.cs | 33 ++---- .../Rooms/Reading/RoomReadingService.cs | 40 +++---- .../Rooms/Updating/IRoomUpdatingRepository.cs | 27 +++-- .../Rooms/Updating/IRoomUpdatingService.cs | 4 +- .../Rooms/Updating/RoomUpdatingRepository.cs | 48 +++------ .../Rooms/Updating/RoomUpdatingService.cs | 65 +++++------ .../Creating/ISchemaCreatingRepository.cs | 3 +- .../Creating/ISchemaCreatingService.cs | 4 +- .../Creating/SchemaCreatingRepository.cs | 27 ++--- .../Schemas/Creating/SchemaCreatingService.cs | 33 ++---- .../Deleting/ISchemaDeletingRepository.cs | 4 +- .../Deleting/ISchemaDeletingService.cs | 4 +- .../Deleting/SchemaDeletingRepository.cs | 12 +-- .../Schemas/Deleting/SchemaDeletingService.cs | 27 ++--- .../Reading/ISchemaReadingRepository.cs | 7 +- .../Schemas/Reading/ISchemaReadingService.cs | 7 +- .../Reading/SchemaReadingRepository.cs | 43 +++----- .../Schemas/Reading/SchemaReadingService.cs | 26 ++--- .../Updating/ISchemaUpdatingRepository.cs | 4 +- .../Updating/ISchemaUpdatingService.cs | 4 +- .../Updating/SchemaUpdatingRepository.cs | 16 ++- .../Schemas/Updating/SchemaUpdatingService.cs | 43 +++----- .../Dto/Input/CreateCharacterValidator.cs | 8 +- .../Dto/Input/UpdateCharacterValidator.cs | 4 +- .../PublicImage/IPublicImageService.cs | 8 +- .../PublicImage/PublicImageService.cs | 6 +- src/DM.Web.API/BbRendering/BbConverter.cs | 25 ++--- .../v1/Account/AccountController.cs | 44 +++----- .../Controllers/v1/Account/LoginController.cs | 12 +-- .../Controllers/v1/Common/SearchController.cs | 12 +-- .../v1/Community/ChatController.cs | 20 ++-- .../v1/Community/MessagingController.cs | 41 +++---- .../v1/Community/PollController.cs | 26 ++--- .../v1/Community/ReviewController.cs | 30 +++--- .../v1/Community/UserController.cs | 22 ++-- .../v1/Community/UserUploadController.cs | 14 +-- .../Controllers/v1/Fora/CommentController.cs | 39 +++---- .../Controllers/v1/Fora/ForumController.cs | 39 +++---- .../Controllers/v1/Fora/TopicController.cs | 62 +++++------ .../v1/Gaming/AttributeSchemaController.cs | 30 +++--- .../v1/Gaming/CharacterController.cs | 41 +++---- .../v1/Gaming/CommentController.cs | 49 ++++----- .../Controllers/v1/Gaming/GameController.cs | 83 +++++++------- .../Controllers/v1/Gaming/PostController.cs | 44 ++++---- .../Controllers/v1/Gaming/RoomController.cs | 70 +++++------- .../Notifications/NotificationHub.cs | 8 +- .../Services/Community/ChatApiService.cs | 36 +++---- .../Services/Community/IChatApiService.cs | 10 +- .../Community/IMessagingApiService.cs | 27 +++-- .../Services/Community/IPollApiService.cs | 13 ++- .../Services/Community/IReviewApiService.cs | 16 ++- .../Services/Community/MessagingApiService.cs | 64 +++++------ .../Services/Community/PollApiService.cs | 41 +++---- .../Services/Community/ReviewApiService.cs | 48 +++------ .../Services/Fora/CommentApiService.cs | 57 +++++----- .../Services/Fora/ForumApiService.cs | 26 ++--- .../Services/Fora/ICommentApiService.cs | 22 ++-- .../Services/Fora/IForumApiService.cs | 7 +- .../Services/Fora/ILikeApiService.cs | 13 ++- .../Services/Fora/IModeratorsApiService.cs | 4 +- .../Services/Fora/ITopicApiService.cs | 16 ++- .../Services/Fora/LikeApiService.cs | 31 +++--- .../Services/Fora/ModeratorsApiService.cs | 21 ++-- .../Services/Fora/TopicApiService.cs | 51 ++++----- .../Services/Gaming/BlacklistApiService.cs | 37 +++---- .../Services/Gaming/CharacterApiService.cs | 53 ++++----- .../Services/Gaming/CommentApiService.cs | 54 ++++------ .../Services/Gaming/GameApiService.cs | 67 +++++------- .../Services/Gaming/IBlacklistApiService.cs | 10 +- .../Services/Gaming/ICharacterApiService.cs | 19 ++-- .../Services/Gaming/ICommentApiService.cs | 19 ++-- .../Services/Gaming/IGameApiService.cs | 28 +++-- .../Services/Gaming/ILikeApiService.cs | 7 +- .../Services/Gaming/IPostApiService.cs | 18 ++-- .../Services/Gaming/IReaderApiService.cs | 9 +- .../Services/Gaming/ISchemaApiService.cs | 17 ++- .../Services/Gaming/LikeApiService.cs | 24 ++--- .../Services/Gaming/PostApiService.cs | 52 ++++----- .../Services/Gaming/ReaderApiService.cs | 32 ++---- .../Gaming/Rooms/IPendingPostApiService.cs | 8 +- .../Services/Gaming/Rooms/IRoomApiService.cs | 16 ++- .../Gaming/Rooms/IRoomClaimApiService.cs | 10 +- .../Gaming/Rooms/PendingPostApiService.cs | 29 ++--- .../Services/Gaming/Rooms/RoomApiService.cs | 48 +++------ .../Gaming/Rooms/RoomClaimApiService.cs | 38 +++---- .../Services/Gaming/SchemaApiService.cs | 51 ++++----- .../Services/Users/ActivationApiService.cs | 27 ++--- .../Services/Users/EmailChangeApiService.cs | 21 ++-- .../Services/Users/IActivationApiService.cs | 4 +- .../Services/Users/IEmailChangeApiService.cs | 4 +- .../Services/Users/ILoginApiService.cs | 4 +- .../Users/IPasswordResetApiService.cs | 7 +- .../Services/Users/IRegistrationApiService.cs | 4 +- .../Services/Users/IUserApiService.cs | 17 ++- .../Services/Users/LoginApiService.cs | 33 ++---- .../Services/Users/PasswordResetApiService.cs | 29 ++--- .../Services/Users/RegistrationApiService.cs | 21 ++-- .../Services/Users/UserApiService.cs | 44 ++++---- .../WebAuthenticationService.cs | 22 ++-- .../Hubs/IUserConnectionService.cs | 7 +- src/DM.Web.Core/Hubs/UserConnectionService.cs | 11 +- .../AuthenticationServiceLoginShould.cs | 37 +++---- .../AuthenticationServiceLogoutShould.cs | 17 +-- .../AuthenticationServiceTokenShould.cs | 101 +++++++++--------- .../SymmetricCryptoServiceShould.cs | 5 +- .../ActivationServiceShould.cs | 25 ++--- .../RegistrationServiceShould.cs | 18 ++-- .../UserReadingServiceShould.cs | 46 ++++---- .../RegistrationMailSenderShould.cs | 5 +- .../CommentaryCreatingServiceShould.cs | 18 ++-- .../CommentaryDeletingServiceShould.cs | 24 +++-- .../CommentaryReadingServiceShould.cs | 29 ++--- .../CommentaryUpdatingServiceShould.cs | 12 +-- .../Likes/LikeServiceForCommentsShould.cs | 27 ++--- .../Likes/LikeServiceForTopicsShould.cs | 27 ++--- .../Topics/TopicCreatingServiceShould.cs | 18 ++-- .../Topics/TopicDeletingServiceShould.cs | 19 ++-- .../Topics/TopicReadingServiceShould.cs | 15 +-- .../GameCreatingServiceShould.cs | 40 +++---- 388 files changed, 3621 insertions(+), 5041 deletions(-) diff --git a/src/DM.Services.Authentication/Factories/SessionFactory.cs b/src/DM.Services.Authentication/Factories/SessionFactory.cs index 3443534d..6183578a 100644 --- a/src/DM.Services.Authentication/Factories/SessionFactory.cs +++ b/src/DM.Services.Authentication/Factories/SessionFactory.cs @@ -4,20 +4,10 @@ namespace DM.Services.Authentication.Factories; /// -internal class SessionFactory : ISessionFactory +internal class SessionFactory( + IGuidFactory guidFactory, + IDateTimeProvider dateTimeProvider) : ISessionFactory { - private readonly IGuidFactory guidFactory; - private readonly IDateTimeProvider dateTimeProvider; - - /// - public SessionFactory( - IGuidFactory guidFactory, - IDateTimeProvider dateTimeProvider) - { - this.guidFactory = guidFactory; - this.dateTimeProvider = dateTimeProvider; - } - /// public Session Create(bool persistent, bool invisible) { diff --git a/src/DM.Services.Authentication/Implementation/AuthenticationService.cs b/src/DM.Services.Authentication/Implementation/AuthenticationService.cs index 4e63e231..59ed9bd1 100644 --- a/src/DM.Services.Authentication/Implementation/AuthenticationService.cs +++ b/src/DM.Services.Authentication/Implementation/AuthenticationService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.Json; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Factories; @@ -16,42 +17,23 @@ namespace DM.Services.Authentication.Implementation; /// -internal class AuthenticationService : IAuthenticationService +internal class AuthenticationService( + ISecurityManager securityManager, + ISymmetricCryptoService cryptoService, + IAuthenticationRepository repository, + ISessionFactory sessionFactory, + IDateTimeProvider dateTimeProvider, + IIdentityProvider identityProvider, + IUpdateBuilderFactory updateBuilderFactory) : IAuthenticationService { - private readonly ISecurityManager securityManager; - private readonly ISymmetricCryptoService cryptoService; - private readonly IAuthenticationRepository repository; - private readonly ISessionFactory sessionFactory; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IIdentityProvider identityProvider; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private const string UserIdKey = "userId"; private const string SessionIdKey = "sessionId"; /// - public AuthenticationService( - ISecurityManager securityManager, - ISymmetricCryptoService cryptoService, - IAuthenticationRepository repository, - ISessionFactory sessionFactory, - IDateTimeProvider dateTimeProvider, - IIdentityProvider identityProvider, - IUpdateBuilderFactory updateBuilderFactory) - { - this.securityManager = securityManager; - this.cryptoService = cryptoService; - this.repository = repository; - this.sessionFactory = sessionFactory; - this.dateTimeProvider = dateTimeProvider; - this.identityProvider = identityProvider; - this.updateBuilderFactory = updateBuilderFactory; - } - - /// - public async Task Authenticate(string login, string password, bool persistent) + public async Task Authenticate( + string login, string password, bool persistent, CancellationToken cancellationToken) { - var (userFound, user) = await repository.TryFindUser(login); + var (userFound, user) = await repository.TryFindUser(login, cancellationToken); switch (userFound) { case false: @@ -68,20 +50,20 @@ public async Task Authenticate(string login, string password, bool pe default: var session = sessionFactory.Create(persistent, false); - var settings = await repository.FindUserSettings(user.UserId); - return await CreateAuthenticationResult(user, session, settings); + var settings = await repository.FindUserSettings(user.UserId, cancellationToken); + return await CreateAuthenticationResult(user, session, settings, cancellationToken); } } /// - public async Task Authenticate(string authToken) + public async Task Authenticate(string authToken, CancellationToken cancellationToken) { Guid userId; Guid sessionId; try { - var decryptedString = await cryptoService.Decrypt(authToken); + var decryptedString = await cryptoService.Decrypt(authToken, cancellationToken); var authData = JsonSerializer.Deserialize>(decryptedString); userId = authData[UserIdKey]; sessionId = authData[SessionIdKey]; @@ -91,9 +73,9 @@ public async Task Authenticate(string authToken) return Identity.Fail(AuthenticationError.ForgedToken); } - var fetchUser = repository.FindUser(userId); - var fetchSession = repository.FindUserSession(sessionId); - var fetchSettings = repository.FindUserSettings(userId); + var fetchUser = repository.FindUser(userId, cancellationToken); + var fetchSession = repository.FindUserSession(sessionId, cancellationToken); + var fetchSettings = repository.FindUserSettings(userId, cancellationToken); await Task.WhenAll(fetchUser, fetchSession, fetchSettings); @@ -109,7 +91,7 @@ public async Task Authenticate(string authToken) if (!session.Persistent && session.ExpirationDate < dateTimeProvider.Now) { - await repository.RemoveSession(userId, sessionId); + await repository.RemoveSession(userId, sessionId, cancellationToken); return Identity.Fail(AuthenticationError.SessionExpired); } @@ -117,7 +99,8 @@ public async Task Authenticate(string authToken) if (!session.Persistent && session.ExpirationDate < dateTimeProvider.Now + sessionRefreshDelta) { - await repository.RefreshSession(userId, sessionId, session.ExpirationDate + sessionRefreshDelta); + await repository.RefreshSession( + userId, sessionId, session.ExpirationDate + sessionRefreshDelta, cancellationToken); } if (!session.Invisible && ( @@ -126,47 +109,47 @@ public async Task Authenticate(string authToken) { var userUpdate = updateBuilderFactory.Create(user.UserId) .Field(u => u.LastVisitDate, dateTimeProvider.Now); - await repository.UpdateActivity(userUpdate); + await repository.UpdateActivity(userUpdate, cancellationToken); } return Identity.Success(user, session, settings, authToken); } /// - public async Task Authenticate(Guid userId) + public async Task Authenticate(Guid userId, CancellationToken cancellationToken) { - var user = await repository.FindUser(userId); + var user = await repository.FindUser(userId, cancellationToken); var session = sessionFactory.Create(false, true); - var settings = await repository.FindUserSettings(userId); - return await CreateAuthenticationResult(user, session, settings); + var settings = await repository.FindUserSettings(userId, cancellationToken); + return await CreateAuthenticationResult(user, session, settings, cancellationToken); } /// - public async Task Logout() + public async Task Logout(CancellationToken cancellationToken) { var identity = identityProvider.Current; - await repository.RemoveSession(identity.User.UserId, identity.Session.Id); + await repository.RemoveSession(identity.User.UserId, identity.Session.Id, cancellationToken); return Identity.Guest(); } /// - public async Task LogoutElsewhere() + public async Task LogoutElsewhere(CancellationToken cancellationToken) { var identity = identityProvider.Current; - await repository.RemoveSessionsExcept(identity.User.UserId, identity.Session.Id); + await repository.RemoveSessionsExcept(identity.User.UserId, identity.Session.Id, cancellationToken); return identity; } private async Task CreateAuthenticationResult( - AuthenticatedUser user, DbSession session, UserSettings settings) + AuthenticatedUser user, DbSession session, UserSettings settings, CancellationToken cancellationToken) { - var newSession = await repository.AddSession(user.UserId, session); + var newSession = await repository.AddSession(user.UserId, session, cancellationToken); var authData = new Dictionary { [UserIdKey] = user.UserId, [SessionIdKey] = session.Id }; - var token = await cryptoService.Encrypt(JsonSerializer.Serialize(authData)); + var token = await cryptoService.Encrypt(JsonSerializer.Serialize(authData), cancellationToken); return Identity.Success(user, newSession, settings, token); } } \ No newline at end of file diff --git a/src/DM.Services.Authentication/Implementation/IAuthenticationService.cs b/src/DM.Services.Authentication/Implementation/IAuthenticationService.cs index c11a9a4b..cd1576e6 100644 --- a/src/DM.Services.Authentication/Implementation/IAuthenticationService.cs +++ b/src/DM.Services.Authentication/Implementation/IAuthenticationService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; @@ -15,32 +16,35 @@ public interface IAuthenticationService /// User login /// User password /// Persistence flag + /// /// Authentication identity - Task Authenticate(string login, string password, bool persistent); + Task Authenticate(string login, string password, bool persistent, CancellationToken cancellationToken); /// /// Authenticate via token credentials /// /// Authentication token + /// /// Authentication identity - Task Authenticate(string authToken); + Task Authenticate(string authToken, CancellationToken cancellationToken); /// /// Authenticate unconditionally /// /// User identifier + /// /// Authentication identity - Task Authenticate(Guid userId); + Task Authenticate(Guid userId, CancellationToken cancellationToken); /// /// Logout as a current user /// /// Guest identity - Task Logout(); + Task Logout(CancellationToken cancellationToken); /// /// Logout from all devices except this /// /// Newly created authentication identity - Task LogoutElsewhere(); + Task LogoutElsewhere(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Authentication/Implementation/Security/ISymmetricCryptoService.cs b/src/DM.Services.Authentication/Implementation/Security/ISymmetricCryptoService.cs index 95a2781a..b56bbea9 100644 --- a/src/DM.Services.Authentication/Implementation/Security/ISymmetricCryptoService.cs +++ b/src/DM.Services.Authentication/Implementation/Security/ISymmetricCryptoService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Authentication.Implementation.Security; @@ -11,13 +12,15 @@ public interface ISymmetricCryptoService /// Encrypts value for storage /// /// Given value + /// /// - Task Encrypt(string valueToEncrypt); + Task Encrypt(string valueToEncrypt, CancellationToken cancellationToken); /// /// Decrypts stored value /// /// Stored value + /// /// - Task Decrypt(string valueToDecrypt); + Task Decrypt(string valueToDecrypt, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Authentication/Implementation/Security/SecurityManager.cs b/src/DM.Services.Authentication/Implementation/Security/SecurityManager.cs index 08236131..d410b8ec 100644 --- a/src/DM.Services.Authentication/Implementation/Security/SecurityManager.cs +++ b/src/DM.Services.Authentication/Implementation/Security/SecurityManager.cs @@ -4,20 +4,10 @@ namespace DM.Services.Authentication.Implementation.Security; /// -internal class SecurityManager : ISecurityManager +internal class SecurityManager( + ISaltFactory saltFactory, + IHashProvider hashProvider) : ISecurityManager { - private readonly ISaltFactory saltFactory; - private readonly IHashProvider hashProvider; - - /// - public SecurityManager( - ISaltFactory saltFactory, - IHashProvider hashProvider) - { - this.saltFactory = saltFactory; - this.hashProvider = hashProvider; - } - /// public (string Hash, string Salt) GeneratePassword(string password) { diff --git a/src/DM.Services.Authentication/Implementation/Security/TripleDesSymmetricCryptoService.cs b/src/DM.Services.Authentication/Implementation/Security/TripleDesSymmetricCryptoService.cs index 9ba03ee3..dea95eae 100644 --- a/src/DM.Services.Authentication/Implementation/Security/TripleDesSymmetricCryptoService.cs +++ b/src/DM.Services.Authentication/Implementation/Security/TripleDesSymmetricCryptoService.cs @@ -2,6 +2,7 @@ using System.IO; using System.Security.Cryptography; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Authentication.Implementation.Security; @@ -14,7 +15,7 @@ internal class TripleDesSymmetricCryptoService : ISymmetricCryptoService private readonly Lazy tripleDesService = new(TripleDES.Create); /// - public async Task Encrypt(string valueToEncrypt) + public async Task Encrypt(string valueToEncrypt, CancellationToken cancellationToken) { using var encryptedStream = new MemoryStream(); var key = Convert.FromBase64String(Key); @@ -24,14 +25,14 @@ public async Task Encrypt(string valueToEncrypt) CryptoStreamMode.Write)) { var data = Encoding.UTF8.GetBytes(valueToEncrypt); - await stream.WriteAsync(data); + await stream.WriteAsync(data, cancellationToken); } return Convert.ToBase64String(encryptedStream.ToArray()); } /// - public async Task Decrypt(string valueToDecrypt) + public async Task Decrypt(string valueToDecrypt, CancellationToken cancellationToken) { using var decryptedStream = new MemoryStream(); var key = Convert.FromBase64String(Key); @@ -41,7 +42,7 @@ public async Task Decrypt(string valueToDecrypt) CryptoStreamMode.Write)) { var encryptedData = Convert.FromBase64String(valueToDecrypt); - await stream.WriteAsync(encryptedData); + await stream.WriteAsync(encryptedData, cancellationToken); } return Encoding.UTF8.GetString(decryptedStream.ToArray()); diff --git a/src/DM.Services.Authentication/Repositories/AuthenticationRepository.cs b/src/DM.Services.Authentication/Repositories/AuthenticationRepository.cs index fb6fd6b7..3a29630d 100644 --- a/src/DM.Services.Authentication/Repositories/AuthenticationRepository.cs +++ b/src/DM.Services.Authentication/Repositories/AuthenticationRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -17,47 +18,38 @@ namespace DM.Services.Authentication.Repositories; /// -internal class AuthenticationRepository : MongoRepository, IAuthenticationRepository +internal class AuthenticationRepository( + DmDbContext dbContext, + DmMongoClient mongoClient, + IMapper mapper) : MongoRepository(mongoClient), IAuthenticationRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public AuthenticationRepository( - DmDbContext dbContext, - DmMongoClient mongoClient, - IMapper mapper) : base(mongoClient) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task<(bool Success, AuthenticatedUser User)> TryFindUser(string login) + public async Task<(bool Success, AuthenticatedUser User)> TryFindUser( + string login, CancellationToken cancellationToken) { var result = await dbContext.Users .Where(u => u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return (result != null, result); } /// - public Task FindUser(Guid userId) + public Task FindUser(Guid userId, CancellationToken cancellationToken) { return dbContext.Users .Where(u => u.UserId == userId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } /// - public async Task FindUserSession(Guid sessionId) + public async Task FindUserSession(Guid sessionId, CancellationToken cancellationToken) { var userSessions = await Collection() .Find(Filter() .ElemMatch(u => u.Sessions, s => s.Id == sessionId)) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); var matchingSession = userSessions?.Sessions.FirstOrDefault(s => s.Id == sessionId); return matchingSession == null ? null @@ -65,7 +57,7 @@ public async Task FindUserSession(Guid sessionId) } /// - public async Task FindUserSettings(Guid userId) + public async Task FindUserSettings(Guid userId, CancellationToken cancellationToken) { var settings = await Collection() .Find(Filter() @@ -85,50 +77,55 @@ public async Task FindUserSettings(Guid userId) }, NannyGreetingsMessage = s.NannyGreetingsMessage })) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return settings ?? UserSettings.Default; } /// - public Task RemoveSession(Guid userId, Guid sessionId) + public Task RemoveSession(Guid userId, Guid sessionId, CancellationToken cancellationToken) { return Collection().FindOneAndUpdateAsync( Filter().Eq(u => u.Id, userId), - Update().PullFilter(s => s.Sessions, s => s.Id == sessionId)); + Update().PullFilter(s => s.Sessions, s => s.Id == sessionId), + cancellationToken: cancellationToken); } /// - public Task RefreshSession(Guid userId, Guid sessionId, DateTimeOffset expirationDate) + public Task RefreshSession( + Guid userId, Guid sessionId, DateTimeOffset expirationDate, CancellationToken cancellationToken) { return Collection().FindOneAndUpdateAsync( Filter().Eq(u => u.Id, userId) & Filter().ElemMatch(u => u.Sessions, s => s.Id == sessionId), - Update().Set(u => u.Sessions[-1].ExpirationDate, expirationDate.UtcDateTime)); + Update().Set(u => u.Sessions[-1].ExpirationDate, expirationDate.UtcDateTime), + cancellationToken: cancellationToken); } /// - public async Task AddSession(Guid userId, DbSession session) + public async Task AddSession(Guid userId, DbSession session, CancellationToken cancellationToken) { await Collection().FindOneAndUpdateAsync( Filter().Eq(u => u.Id, userId), Update().Push(s => s.Sessions, session), - new FindOneAndUpdateOptions {IsUpsert = true}); + new FindOneAndUpdateOptions {IsUpsert = true}, + cancellationToken); return mapper.Map(session); } /// - public Task RemoveSessionsExcept(Guid userId, Guid sessionId) + public Task RemoveSessionsExcept(Guid userId, Guid sessionId, CancellationToken cancellationToken) { return Collection().FindOneAndUpdateAsync( Filter().Eq(u => u.Id, userId), Update().PullFilter(s => s.Sessions, s => s.Id != sessionId), - new FindOneAndUpdateOptions{IsUpsert = true}); + new FindOneAndUpdateOptions{IsUpsert = true}, + cancellationToken); } /// - public Task UpdateActivity(IUpdateBuilder userUpdate) + public Task UpdateActivity(IUpdateBuilder userUpdate, CancellationToken cancellationToken) { userUpdate.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Authentication/Repositories/IAuthenticationRepository.cs b/src/DM.Services.Authentication/Repositories/IAuthenticationRepository.cs index c2ba97b5..f790ee76 100644 --- a/src/DM.Services.Authentication/Repositories/IAuthenticationRepository.cs +++ b/src/DM.Services.Authentication/Repositories/IAuthenticationRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.DataAccess.BusinessObjects.Users; @@ -17,37 +18,42 @@ internal interface IAuthenticationRepository /// Search for user by its login /// /// User login + /// /// Pair of operation success flag and the user data. If no user is found, the user will be null - Task<(bool Success, AuthenticatedUser User)> TryFindUser(string login); + Task<(bool Success, AuthenticatedUser User)> TryFindUser(string login, CancellationToken cancellationToken); /// /// Search for user by its id /// /// User id + /// /// User data - Task FindUser(Guid userId); + Task FindUser(Guid userId, CancellationToken cancellationToken); /// /// Search for authentication session by its id /// /// Authentication session id + /// /// Session - Task FindUserSession(Guid sessionId); + Task FindUserSession(Guid sessionId, CancellationToken cancellationToken); /// /// Search for user settings by user id /// /// User id + /// /// User settings - Task FindUserSettings(Guid userId); + Task FindUserSettings(Guid userId, CancellationToken cancellationToken); /// /// Remove authentication session /// /// Authenticated user id /// Authentication session id + /// /// - Task RemoveSession(Guid userId, Guid sessionId); + Task RemoveSession(Guid userId, Guid sessionId, CancellationToken cancellationToken); /// /// Update authentication session that is about to expire @@ -55,29 +61,33 @@ internal interface IAuthenticationRepository /// Authenticated user id /// Authentication session id /// New expiration date + /// /// - Task RefreshSession(Guid userId, Guid sessionId, DateTimeOffset expirationDate); + Task RefreshSession(Guid userId, Guid sessionId, DateTimeOffset expirationDate, CancellationToken cancellationToken); /// /// Append new session to user authentication sessions /// /// Authenticated user id /// Authentication session + /// /// - Task AddSession(Guid userId, DbSession session); + Task AddSession(Guid userId, DbSession session, CancellationToken cancellationToken); /// /// Remove all sessions from the user except one /// /// Authenticated user id /// Session id + /// /// - Task RemoveSessionsExcept(Guid userId, Guid sessionId); + Task RemoveSessionsExcept(Guid userId, Guid sessionId, CancellationToken cancellationToken); /// /// Update user last activity date /// /// + /// /// - Task UpdateActivity(IUpdateBuilder userUpdate); + Task UpdateActivity(IUpdateBuilder userUpdate, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Common/BusinessProcesses/Likes/ILikeRepository.cs b/src/DM.Services.Common/BusinessProcesses/Likes/ILikeRepository.cs index c67cf9b4..1dc0c472 100644 --- a/src/DM.Services.Common/BusinessProcesses/Likes/ILikeRepository.cs +++ b/src/DM.Services.Common/BusinessProcesses/Likes/ILikeRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Common; @@ -13,14 +14,16 @@ public interface ILikeRepository /// Store new like /// /// Like DAL model + /// /// - Task Add(Like like); + Task Add(Like like, CancellationToken cancellationToken); /// /// Delete like from storage /// /// Topic identifier /// User identifier + /// /// - Task Delete(Guid topicId, Guid userId); + Task Delete(Guid topicId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Common/BusinessProcesses/Likes/LikeRepository.cs b/src/DM.Services.Common/BusinessProcesses/Likes/LikeRepository.cs index b75e15cc..baa46edf 100644 --- a/src/DM.Services.Common/BusinessProcesses/Likes/LikeRepository.cs +++ b/src/DM.Services.Common/BusinessProcesses/Likes/LikeRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Common; @@ -7,29 +8,22 @@ namespace DM.Services.Common.BusinessProcesses.Likes; /// -internal class LikeRepository : ILikeRepository +internal class LikeRepository( + DmDbContext dbContext) : ILikeRepository { - private readonly DmDbContext dbContext; - - /// - public LikeRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public Task Add(Like like) + public Task Add(Like like, CancellationToken cancellationToken) { dbContext.Likes.Add(like); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } /// - public async Task Delete(Guid topicId, Guid userId) + public async Task Delete(Guid topicId, Guid userId, CancellationToken cancellationToken) { - var like = await dbContext.Likes.FirstAsync(l => l.UserId == userId && l.EntityId == topicId); + var like = await dbContext.Likes + .FirstAsync(l => l.UserId == userId && l.EntityId == topicId, cancellationToken); dbContext.Likes.Remove(like); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Common/BusinessProcesses/Likes/LikeServiceBase.cs b/src/DM.Services.Common/BusinessProcesses/Likes/LikeServiceBase.cs index 1cb46387..e16c1e76 100644 --- a/src/DM.Services.Common/BusinessProcesses/Likes/LikeServiceBase.cs +++ b/src/DM.Services.Common/BusinessProcesses/Likes/LikeServiceBase.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Dto; @@ -13,33 +14,20 @@ namespace DM.Services.Common.BusinessProcesses.Likes; /// /// Common part of like service /// -public abstract class LikeServiceBase +public abstract class LikeServiceBase( + IIdentityProvider identityProvider, + ILikeFactory likeFactory, + ILikeRepository likeRepository, + IInvokedEventProducer producer) { - private readonly IIdentityProvider identityProvider; - private readonly ILikeFactory likeFactory; - private readonly ILikeRepository likeRepository; - private readonly IInvokedEventProducer producer; - - /// - protected LikeServiceBase( - IIdentityProvider identityProvider, - ILikeFactory likeFactory, - ILikeRepository likeRepository, - IInvokedEventProducer producer) - { - this.identityProvider = identityProvider; - this.likeFactory = likeFactory; - this.likeRepository = likeRepository; - this.producer = producer; - } - /// /// Like certain entity /// /// Likable entity /// Event type to generate after like + /// /// Person who liked - protected async Task Like(ILikable entity, EventType eventType) + protected async Task Like(ILikable entity, EventType eventType, CancellationToken cancellationToken) { var currentUser = identityProvider.Current.User; if (entity.Likes.Any(l => l.UserId == currentUser.UserId)) @@ -49,7 +37,7 @@ protected async Task Like(ILikable entity, EventType eventType) } var like = likeFactory.Create(entity.Id, currentUser.UserId); - await likeRepository.Add(like); + await likeRepository.Add(like, cancellationToken); await producer.Send(eventType, like.LikeId); return currentUser; } @@ -58,8 +46,9 @@ protected async Task Like(ILikable entity, EventType eventType) /// Dislike certain entity /// /// Likable entity + /// /// - protected async Task Dislike(ILikable entity) + protected async Task Dislike(ILikable entity, CancellationToken cancellationToken) { var currentUser = identityProvider.Current.User; if (entity.Likes.All(l => l.UserId != currentUser.UserId)) @@ -68,6 +57,6 @@ protected async Task Dislike(ILikable entity) $"User never liked this {entity.GetType().Name.ToLower()} in the first place"); } - await likeRepository.Delete(entity.Id, currentUser.UserId); + await likeRepository.Delete(entity.Id, currentUser.UserId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Common/BusinessProcesses/UnreadCounters/IUnreadCountersRepository.cs b/src/DM.Services.Common/BusinessProcesses/UnreadCounters/IUnreadCountersRepository.cs index a7f78a3a..973dfa11 100644 --- a/src/DM.Services.Common/BusinessProcesses/UnreadCounters/IUnreadCountersRepository.cs +++ b/src/DM.Services.Common/BusinessProcesses/UnreadCounters/IUnreadCountersRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Common; @@ -16,33 +17,38 @@ public interface IUnreadCountersRepository /// Entity Id /// Entry type /// User Ids + /// /// - Task Create(Guid entityId, UnreadEntryType entryType, IEnumerable userIds); - + Task Create(Guid entityId, UnreadEntryType entryType, + IReadOnlyCollection userIds, CancellationToken cancellationToken); + /// /// Create a counter for the entity /// /// Entity Id /// Parent entity Id /// Entry type + /// /// - Task Create(Guid entityId, Guid parentId, UnreadEntryType entryType); + Task Create(Guid entityId, Guid parentId, UnreadEntryType entryType, CancellationToken cancellationToken); /// /// Create a counter for the entity without parent /// /// Entity id /// Entry type + /// /// - Task Create(Guid entityId, UnreadEntryType entryType); + Task Create(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken); /// /// Increment counter of the entity for every user /// /// Entity Id /// Entry type + /// /// - Task Increment(Guid entityId, UnreadEntryType entryType); + Task Increment(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken); /// /// Decrement counter for users who hasn't read the entry since given time @@ -50,16 +56,19 @@ public interface IUnreadCountersRepository /// Entity Id /// Entry type /// Given time + /// /// - Task Decrement(Guid entityId, UnreadEntryType entryType, DateTimeOffset createDate); + Task Decrement(Guid entityId, UnreadEntryType entryType, DateTimeOffset createDate, + CancellationToken cancellationToken); /// /// Remove counter for everyone /// /// Entity Id /// Entry type + /// /// - Task Delete(Guid entityId, UnreadEntryType entryType); + Task Delete(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken); /// /// Get count of entities that have unread entries by parent entity ids @@ -67,9 +76,10 @@ public interface IUnreadCountersRepository /// User Id /// Entry type /// Parent entity Ids + /// /// List of pairs of parent entity Id and number of according entities that have unread entries - Task> SelectByParents( - Guid userId, UnreadEntryType entryType, params Guid[] parentIds); + Task> SelectByParents(Guid userId, UnreadEntryType entryType, + IReadOnlyCollection parentIds, CancellationToken cancellationToken); /// /// Get count of unread entries by entry ids @@ -77,9 +87,10 @@ Task> SelectByParents( /// User Id /// Entry type /// Entity Ids + /// /// List of pairs of entity Id and number of entries unread - Task> SelectByEntities( - Guid userId, UnreadEntryType entryType, params Guid[] entityIds); + Task> SelectByEntities(Guid userId, UnreadEntryType entryType, + IReadOnlyCollection entityIds, CancellationToken cancellationToken); /// /// Mark entity as read @@ -87,8 +98,9 @@ Task> SelectByEntities( /// User Id /// Entry type /// Entity Id + /// /// - Task Flush(Guid userId, UnreadEntryType entryType, Guid entityId); + Task Flush(Guid userId, UnreadEntryType entryType, Guid entityId, CancellationToken cancellationToken); /// /// Mark all according entities as read @@ -96,8 +108,9 @@ Task> SelectByEntities( /// User Id /// Entry type /// Parent entity Id + /// /// - Task FlushAll(Guid userId, UnreadEntryType entryType, Guid parentId); + Task FlushAll(Guid userId, UnreadEntryType entryType, Guid parentId, CancellationToken cancellationToken); /// /// Move unread counters to new parent @@ -105,6 +118,8 @@ Task> SelectByEntities( /// Parent Id /// Entry type /// New parent Id + /// /// - Task ChangeParent(Guid parentId, UnreadEntryType entryType, Guid newParentId); + Task ChangeParent(Guid parentId, UnreadEntryType entryType, + Guid newParentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Common/BusinessProcesses/UnreadCounters/UnreadCountersRepository.cs b/src/DM.Services.Common/BusinessProcesses/UnreadCounters/UnreadCountersRepository.cs index d3eeeeab..d9fbd159 100644 --- a/src/DM.Services.Common/BusinessProcesses/UnreadCounters/UnreadCountersRepository.cs +++ b/src/DM.Services.Common/BusinessProcesses/UnreadCounters/UnreadCountersRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Implementation; using DM.Services.DataAccess.BusinessObjects.Common; @@ -10,19 +11,13 @@ namespace DM.Services.Common.BusinessProcesses.UnreadCounters; /// -internal class UnreadCountersRepository : MongoCollectionRepository, IUnreadCountersRepository +internal class UnreadCountersRepository( + DmMongoClient client, + IDateTimeProvider dateTimeProvider) : MongoCollectionRepository(client), IUnreadCountersRepository { - private readonly IDateTimeProvider dateTimeProvider; - - /// - public UnreadCountersRepository(DmMongoClient client, - IDateTimeProvider dateTimeProvider) : base(client) - { - this.dateTimeProvider = dateTimeProvider; - } - /// - public Task Create(Guid entityId, UnreadEntryType entryType, IEnumerable userIds) + public Task Create(Guid entityId, UnreadEntryType entryType, + IReadOnlyCollection userIds, CancellationToken cancellationToken) { return Collection.InsertManyAsync(userIds.Select(id => new UnreadCounter { @@ -32,11 +27,11 @@ public Task Create(Guid entityId, UnreadEntryType entryType, IEnumerable u EntryType = entryType, LastRead = dateTimeProvider.Now.UtcDateTime, Counter = 0 - })); + }), cancellationToken: cancellationToken); } /// - public Task Create(Guid entityId, Guid parentId, UnreadEntryType entryType) + public Task Create(Guid entityId, Guid parentId, UnreadEntryType entryType, CancellationToken cancellationToken) { return Collection.InsertOneAsync(new UnreadCounter { @@ -46,44 +41,50 @@ public Task Create(Guid entityId, Guid parentId, UnreadEntryType entryType) EntryType = entryType, LastRead = dateTimeProvider.Now.UtcDateTime, Counter = 0 - }); + }, cancellationToken: cancellationToken); } /// - public Task Create(Guid entityId, UnreadEntryType entryType) => Create(entityId, entityId, entryType); + public Task Create(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken) => + Create(entityId, entityId, entryType, cancellationToken); /// - public Task Increment(Guid entityId, UnreadEntryType entryType) + public Task Increment(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken) { return Collection.UpdateManyAsync( Filter.Eq(c => c.EntityId, entityId) & Filter.Eq(c => c.EntryType, entryType), - Update.Inc(c => c.Counter, 1)); + Update.Inc(c => c.Counter, 1), + cancellationToken: cancellationToken); } /// - public Task Decrement(Guid entityId, UnreadEntryType entryType, DateTimeOffset createDate) + public Task Decrement(Guid entityId, UnreadEntryType entryType, + DateTimeOffset createDate, CancellationToken cancellationToken) { - return Collection.UpdateManyAsync(Filter.Eq(c => c.EntityId, entityId) & - Filter.Eq(c => c.EntryType, entryType) & - Filter.Lt(c => c.LastRead, createDate.UtcDateTime), - Update.Inc(c => c.Counter, -1)); + return Collection.UpdateManyAsync( + Filter.Eq(c => c.EntityId, entityId) & + Filter.Eq(c => c.EntryType, entryType) & + Filter.Lt(c => c.LastRead, createDate.UtcDateTime), + Update.Inc(c => c.Counter, -1), + cancellationToken: cancellationToken); } /// - public Task Delete(Guid entityId, UnreadEntryType entryType) + public Task Delete(Guid entityId, UnreadEntryType entryType, CancellationToken cancellationToken) { return Collection.UpdateManyAsync( Filter.Eq(c => c.EntityId, entityId) & Filter.Eq(c => c.EntryType, entryType), - Update.Set(c => c.IsRemoved, true)); + Update.Set(c => c.IsRemoved, true), + cancellationToken: cancellationToken); } /// - public async Task> SelectByParents( - Guid userId, UnreadEntryType entryType, params Guid[] parentIds) + public async Task> SelectByParents(Guid userId, UnreadEntryType entryType, + IReadOnlyCollection parentIds, CancellationToken cancellationToken) { - var userIds = new[] {userId, Guid.Empty}.Distinct(); + var userIds = new[] { userId, Guid.Empty }.Distinct(); var counters = (await Collection.Aggregate() .Match( Filter.In(c => c.UserId, userIds) & @@ -103,16 +104,16 @@ public async Task> SelectByParents( EntityId = g.First().ParentId, Counter = g.Sum(c => c.Counter > 0 ? 1 : 0) }) - .ToListAsync()) + .ToListAsync(cancellationToken)) .ToDictionary(c => c.EntityId, c => c.Counter); return parentIds.ToDictionary(id => id, id => counters.TryGetValue(id, out var counter) ? counter : 0); } /// - public async Task> SelectByEntities( - Guid userId, UnreadEntryType entryType, params Guid[] entityIds) + public async Task> SelectByEntities(Guid userId, UnreadEntryType entryType, + IReadOnlyCollection entityIds, CancellationToken cancellationToken) { - var userIds = new[] {userId, Guid.Empty}.Distinct(); + var userIds = new[] { userId, Guid.Empty }.Distinct(); var counters = (await Collection.Aggregate() .Match( Filter.In(c => c.UserId, userIds) & @@ -125,18 +126,18 @@ public async Task> SelectByEntities( EntityId = g.First().EntityId, Counter = g.Min(c => c.Counter) }) - .ToListAsync()) + .ToListAsync(cancellationToken)) .ToDictionary(c => c.EntityId, c => c.Counter); return entityIds.ToDictionary(id => id, id => counters.TryGetValue(id, out var counter) ? counter : 0); } /// - public async Task Flush(Guid userId, UnreadEntryType entryType, Guid entityId) + public async Task Flush(Guid userId, UnreadEntryType entryType, Guid entityId, CancellationToken cancellationToken) { var counter = await Collection.Find( Filter.Eq(c => c.EntityId, entityId) & Filter.Eq(c => c.EntryType, entryType)) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); await Collection .ReplaceOneAsync( @@ -152,16 +153,20 @@ await Collection LastRead = dateTimeProvider.Now.UtcDateTime, Counter = 0 }, - new ReplaceOptions {IsUpsert = true}); + new ReplaceOptions { IsUpsert = true }, + cancellationToken); } /// - public async Task FlushAll(Guid userId, UnreadEntryType entryType, Guid parentId) + public async Task FlushAll(Guid userId, UnreadEntryType entryType, Guid parentId, + CancellationToken cancellationToken) { - var entityIds = await Collection.Distinct(c => c.EntityId, + var entityIds = await Collection.Distinct( + c => c.EntityId, Filter.Eq(c => c.ParentId, parentId) & - Filter.Eq(c => c.EntryType, entryType)) - .ToListAsync(); + Filter.Eq(c => c.EntryType, entryType), + cancellationToken: cancellationToken) + .ToListAsync(cancellationToken); var rightNow = dateTimeProvider.Now.UtcDateTime; await Collection.BulkWriteAsync(entityIds @@ -178,15 +183,17 @@ await Collection.BulkWriteAsync(entityIds LastRead = rightNow, Counter = 0 }) - {IsUpsert = true})); + { IsUpsert = true }), cancellationToken: cancellationToken); } /// - public async Task ChangeParent(Guid parentId, UnreadEntryType entryType, Guid newParentId) + public async Task ChangeParent(Guid parentId, UnreadEntryType entryType, + Guid newParentId, CancellationToken cancellationToken) { await Collection.UpdateManyAsync( Filter.Eq(c => c.ParentId, parentId) & Filter.Eq(c => c.EntryType, entryType), - Update.Set(c => c.ParentId, newParentId)); + Update.Set(c => c.ParentId, newParentId), + cancellationToken: cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Common/Extensions/EntitiesCounterFillExtensions.cs b/src/DM.Services.Common/Extensions/EntitiesCounterFillExtensions.cs index 34425432..f55d8d94 100644 --- a/src/DM.Services.Common/Extensions/EntitiesCounterFillExtensions.cs +++ b/src/DM.Services.Common/Extensions/EntitiesCounterFillExtensions.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.BusinessProcesses.UnreadCounters; using DM.Services.DataAccess.BusinessObjects.Common; @@ -22,12 +23,17 @@ public static class EntitiesCounterFillExtensions /// Reading user identifier /// Entity identifier mapper /// Expression of the field to fill counter in + /// /// /// public static Task FillParentCounters(this IUnreadCountersRepository repository, - ICollection entities, Guid userId, - Func getId, Expression> counterField) => - FillCounters(entities, userId, getId, repository.SelectByParents, counterField); + ICollection entities, + Guid userId, + Func getId, + Expression> counterField, + CancellationToken cancellationToken) => + FillCounters(entities, userId, getId, repository.SelectByParents, + counterField, UnreadEntryType.Message, cancellationToken); /// /// Fill counters fields for passed entities @@ -38,21 +44,30 @@ public static Task FillParentCounters(this IUnreadCountersRepository re /// Entity identifier mapper /// Expression of the field to fill counter in /// Unread entry type + /// /// /// public static Task FillEntityCounters(this IUnreadCountersRepository repository, - ICollection entities, Guid userId, - Func getId, Expression> counterField, - UnreadEntryType entryType = UnreadEntryType.Message) => - FillCounters(entities, userId, getId, repository.SelectByEntities, counterField, entryType); + ICollection entities, + Guid userId, + Func getId, + Expression> counterField, + UnreadEntryType entryType, + CancellationToken cancellationToken) => + FillCounters(entities, userId, getId, repository.SelectByEntities, counterField, entryType, cancellationToken); - private static async Task FillCounters(ICollection entities, Guid userId, - Func getId, Func>> getCounters, - Expression> counterField, UnreadEntryType entryType = UnreadEntryType.Message) + private static async Task FillCounters( + ICollection entities, + Guid userId, + Func getId, + Func>> getCounters, + Expression> counterField, + UnreadEntryType entryType, + CancellationToken cancellationToken) { if (counterField.Body is MemberExpression {Member: PropertyInfo property}) { - var counters = await getCounters(userId, entryType, entities.Select(getId).ToArray()); + var counters = await getCounters(userId, entryType, entities.Select(getId).ToArray(), cancellationToken); foreach (var entity in entities) { property.SetValue(entity, counters[getId(entity)]); diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs index 23421682..5ce6ede3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; @@ -9,31 +10,25 @@ namespace DM.Services.Community.BusinessProcesses.Account.Activation; /// -internal class ActivationRepository : IActivationRepository +internal class ActivationRepository( + DmDbContext dbContext) : IActivationRepository { - private readonly DmDbContext dbContext; - - /// - public ActivationRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public async Task FindUserToActivate(Guid tokenId, DateTimeOffset createdSince) + public async Task FindUserToActivate(Guid tokenId, DateTimeOffset createdSince, + CancellationToken cancellationToken) { return (await dbContext.Tokens .Where(t => t.TokenId == tokenId && t.CreateDate > createdSince) .Select(t => new {t.UserId}) - .FirstOrDefaultAsync())?.UserId; + .FirstOrDefaultAsync(cancellationToken))?.UserId; } /// - public Task ActivateUser(IUpdateBuilder updateUser, IUpdateBuilder updateToken) + public Task ActivateUser(IUpdateBuilder updateUser, IUpdateBuilder updateToken, + CancellationToken cancellationToken) { updateUser.AttachTo(dbContext); updateToken.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationService.cs index 531bff53..9670947f 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationService.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto.Enums; using DM.Services.Core.Exceptions; @@ -11,30 +12,17 @@ namespace DM.Services.Community.BusinessProcesses.Account.Activation; /// -internal class ActivationService : IActivationService +internal class ActivationService( + IDateTimeProvider dateTimeProvider, + IUpdateBuilderFactory updateBuilderFactory, + IActivationRepository repository, + IInvokedEventProducer producer) : IActivationService { - private readonly IDateTimeProvider dateTimeProvider; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IActivationRepository repository; - private readonly IInvokedEventProducer producer; - - /// - public ActivationService( - IDateTimeProvider dateTimeProvider, - IUpdateBuilderFactory updateBuilderFactory, - IActivationRepository repository, - IInvokedEventProducer producer) - { - this.dateTimeProvider = dateTimeProvider; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.producer = producer; - } - /// - public async Task Activate(Guid tokenId) + public async Task Activate(Guid tokenId, CancellationToken cancellationToken) { - var userId = await repository.FindUserToActivate(tokenId, dateTimeProvider.Now - TimeSpan.FromDays(2)); + var userId = await repository.FindUserToActivate( + tokenId, dateTimeProvider.Now - TimeSpan.FromDays(2), cancellationToken); if (!userId.HasValue) { throw new HttpException(HttpStatusCode.Gone, @@ -43,7 +31,7 @@ public async Task Activate(Guid tokenId) var updateUser = updateBuilderFactory.Create(userId.Value).Field(u => u.Activated, true); var updateToken = updateBuilderFactory.Create(tokenId).Field(t => t.IsRemoved, true); - await repository.ActivateUser(updateUser, updateToken); + await repository.ActivateUser(updateUser, updateToken, cancellationToken); await producer.Send(EventType.ActivatedUser, userId.Value); return userId.Value; diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs index 3f06d805..8117bf2d 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Users; using DM.Services.DataAccess.RelationalStorage; @@ -15,14 +16,17 @@ internal interface IActivationRepository /// /// Token identifier /// Created since + /// /// - Task FindUserToActivate(Guid tokenId, DateTimeOffset createdSince); + Task FindUserToActivate(Guid tokenId, DateTimeOffset createdSince, CancellationToken cancellationToken); /// /// Update user and its token /// /// User update /// Token update + /// /// - Task ActivateUser(IUpdateBuilder updateUser, IUpdateBuilder updateToken); + Task ActivateUser(IUpdateBuilder updateUser, IUpdateBuilder updateToken, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationService.cs index b9debd08..49c99f95 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Account.Activation; @@ -12,6 +13,7 @@ public interface IActivationService /// Activate user by token identifier /// /// Activation token identifier + /// /// Activated user identifier - Task Activate(Guid tokenId); + Task Activate(Guid tokenId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/EmailChangeMailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/EmailChangeMailSender.cs index daa28221..aa86c349 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/EmailChangeMailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/EmailChangeMailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Account.Registration.Confirmation; using DM.Services.Core.Configuration; @@ -27,7 +28,7 @@ public EmailChangeMailSender( } /// - public async Task Send(string email, string login, Guid token) + public async Task Send(string email, string login, Guid token, CancellationToken cancellationToken) { var confirmationLinkUri = new Uri(new Uri(integrationSettings.WebUrl), $"activate/{token}"); var emailBody = await renderer.Render("RegistrationLetter", new RegistrationConfirmationViewModel @@ -39,7 +40,7 @@ await mailSender.Send(new MailLetter { Address = email, Subject = $"Подтверждение смены адреса электронной почты на DM.AM для {login}", - Body = emailBody + Body = emailBody, }); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/IEmailChangeMailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/IEmailChangeMailSender.cs index 6f220720..153ffb1f 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/IEmailChangeMailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/Confirmation/IEmailChangeMailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Account.EmailChange.Confirmation; @@ -14,6 +15,7 @@ internal interface IEmailChangeMailSender /// User email /// User login /// Confirmation token + /// /// - Task Send(string email, string login, Guid token); + Task Send(string email, string login, Guid token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs index 05b65c88..d6f68bd0 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,31 +12,21 @@ namespace DM.Services.Community.BusinessProcesses.Account.EmailChange; /// -internal class EmailChangeRepository : IEmailChangeRepository +internal class EmailChangeRepository( + DmDbContext dbContext, + IMapper mapper) : IEmailChangeRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public EmailChangeRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task FindUser(string login) => dbContext.Users + public Task FindUser(string login, CancellationToken cancellationToken) => dbContext.Users .Where(u => u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// - public Task Update(IUpdateBuilder updateUser, Token token) + public Task Update(IUpdateBuilder updateUser, Token token, CancellationToken cancellationToken) { updateUser.AttachTo(dbContext); dbContext.Tokens.Add(token); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeService.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeService.cs index 43731ed4..62a20a3b 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Account.Activation; using DM.Services.Community.BusinessProcesses.Account.EmailChange.Confirmation; @@ -9,42 +10,26 @@ namespace DM.Services.Community.BusinessProcesses.Account.EmailChange; /// -internal class EmailChangeService : IEmailChangeService +internal class EmailChangeService( + IValidator validator, + IUpdateBuilderFactory updateBuilderFactory, + IActivationTokenFactory tokenFactory, + IEmailChangeRepository repository, + IEmailChangeMailSender mailSender) : IEmailChangeService { - private readonly IValidator validator; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IActivationTokenFactory tokenFactory; - private readonly IEmailChangeRepository repository; - private readonly IEmailChangeMailSender mailSender; - - /// - public EmailChangeService( - IValidator validator, - IUpdateBuilderFactory updateBuilderFactory, - IActivationTokenFactory tokenFactory, - IEmailChangeRepository repository, - IEmailChangeMailSender mailSender) - { - this.validator = validator; - this.updateBuilderFactory = updateBuilderFactory; - this.tokenFactory = tokenFactory; - this.repository = repository; - this.mailSender = mailSender; - } - /// - public async Task Change(UserEmailChange emailChange) + public async Task Change(UserEmailChange emailChange, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(emailChange); - var user = await repository.FindUser(emailChange.Login); + await validator.ValidateAndThrowAsync(emailChange, cancellationToken); + var user = await repository.FindUser(emailChange.Login, cancellationToken); var updateUser = updateBuilderFactory.Create(user.UserId) .Field(u => u.Email, emailChange.Email) .Field(u => u.Activated, false); var token = tokenFactory.Create(user.UserId); - await repository.Update(updateUser, token); - await mailSender.Send(emailChange.Email, emailChange.Login, token.TokenId); + await repository.Update(updateUser, token, cancellationToken); + await mailSender.Send(emailChange.Email, emailChange.Login, token.TokenId, cancellationToken); return user; } diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs index 5f319f5e..7aab154e 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.DataAccess.BusinessObjects.Users; @@ -14,14 +15,16 @@ internal interface IEmailChangeRepository /// Find user by login /// /// + /// /// - Task FindUser(string login); + Task FindUser(string login, CancellationToken cancellationToken); /// /// Update user email /// /// /// + /// /// - Task Update(IUpdateBuilder updateUser, Token token); + Task Update(IUpdateBuilder updateUser, Token token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeService.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeService.cs index 5564dc88..2eb270f0 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -12,6 +13,7 @@ public interface IEmailChangeService /// Change user email /// /// + /// /// - Task Change(UserEmailChange emailChange); + Task Change(UserEmailChange emailChange, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/UserEmailChangeValidator.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/UserEmailChangeValidator.cs index 0ecd65f2..fb7cea3e 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/UserEmailChangeValidator.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/UserEmailChangeValidator.cs @@ -17,9 +17,9 @@ public UserEmailChangeValidator( { RuleFor(u => u.Login) .NotEmpty().WithMessage(ValidationError.Empty) - .MustAsync(async (model, login, context, _) => + .MustAsync(async (_, login, context, ct) => { - var user = await repository.FindUser(login); + var user = await repository.FindUser(login, ct); if (user == null) { return false; diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs index 65330246..ba28df51 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.DataAccess.BusinessObjects.Users; @@ -15,15 +16,17 @@ internal interface IPasswordChangeRepository /// Find existing user /// /// + /// /// - Task FindUser(string login); + Task FindUser(string login, CancellationToken cancellationToken); /// /// Find token user /// /// + /// /// - Task FindUser(Guid tokenId); + Task FindUser(Guid tokenId, CancellationToken cancellationToken); /// /// Check if token is valid @@ -38,6 +41,8 @@ internal interface IPasswordChangeRepository /// /// /// + /// /// - Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate); + Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeService.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeService.cs index 9c036c00..1f445de7 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -12,6 +13,7 @@ public interface IPasswordChangeService /// Change user password /// /// + /// /// - Task Change(UserPasswordChange passwordChange); + Task Change(UserPasswordChange passwordChange, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs index ae348e77..05efab7a 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -27,17 +28,17 @@ public PasswordChangeRepository( } /// - public Task FindUser(string login) => dbContext.Users + public Task FindUser(string login, CancellationToken cancellationToken) => dbContext.Users .Where(u => u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// - public Task FindUser(Guid tokenId) => dbContext.Tokens + public Task FindUser(Guid tokenId, CancellationToken cancellationToken) => dbContext.Tokens .Where(u => u.TokenId == tokenId) .Select(u => u.User) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// public Task TokenValid(Guid tokenId, DateTimeOffset createdSince) => dbContext.Tokens @@ -45,10 +46,11 @@ public Task TokenValid(Guid tokenId, DateTimeOffset createdSince) => dbCon t.Type == TokenType.PasswordChange && t.CreateDate > createdSince); /// - public Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate) + public Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate, + CancellationToken cancellationToken) { userUpdate.AttachTo(dbContext); tokenUpdate?.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeService.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeService.cs index da654035..f67e3120 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation; using DM.Services.Authentication.Implementation.Security; @@ -10,38 +11,20 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordChange; /// -internal class PasswordChangeService : IPasswordChangeService +internal class PasswordChangeService( + IValidator validator, + ISecurityManager securityManager, + IUpdateBuilderFactory updateBuilderFactory, + IPasswordChangeRepository repository, + IAuthenticationService authenticationService, + IIdentityProvider identityProvider) : IPasswordChangeService { - private readonly IValidator validator; - private readonly IPasswordChangeRepository repository; - private readonly IAuthenticationService authenticationService; - private readonly IIdentityProvider identityProvider; - private readonly ISecurityManager securityManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - - /// - public PasswordChangeService( - IValidator validator, - ISecurityManager securityManager, - IUpdateBuilderFactory updateBuilderFactory, - IPasswordChangeRepository repository, - IAuthenticationService authenticationService, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.repository = repository; - this.authenticationService = authenticationService; - this.identityProvider = identityProvider; - this.securityManager = securityManager; - this.updateBuilderFactory = updateBuilderFactory; - } - /// - public async Task Change(UserPasswordChange passwordChange) + public async Task Change(UserPasswordChange passwordChange, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(passwordChange); + await validator.ValidateAndThrowAsync(passwordChange, cancellationToken); var user = passwordChange.Token.HasValue - ? await repository.FindUser(passwordChange.Token.Value) + ? await repository.FindUser(passwordChange.Token.Value, cancellationToken) : identityProvider.Current.User; var (hash, salt) = securityManager.GeneratePassword(passwordChange.NewPassword); @@ -53,8 +36,8 @@ public async Task Change(UserPasswordChange passwordChange) .Field(t => t.IsRemoved, true) : null; - await repository.UpdatePassword(userUpdate, tokenUpdate); - await authenticationService.LogoutElsewhere(); + await repository.UpdatePassword(userUpdate, tokenUpdate, cancellationToken); + await authenticationService.LogoutElsewhere(cancellationToken); return user; } diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs index 570df341..313dd7d1 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs @@ -31,7 +31,7 @@ public UserPasswordChangeValidator( { RuleFor(c => c.OldPassword) .NotEmpty().WithMessage(ValidationError.Empty) - .Must((model, password, context) => + .Must((_, password, _) => identityProvider.Current.User.IsAuthenticated && securityManager.ComparePasswords(password, identityProvider.Current.User.Salt, identityProvider.Current.User.PasswordHash)) diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/IPasswordResetEmailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/IPasswordResetEmailSender.cs index fca304ed..6148c860 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/IPasswordResetEmailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/IPasswordResetEmailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset.Confirmation; @@ -14,6 +15,7 @@ internal interface IPasswordResetEmailSender /// User email /// User login /// Confirmation token + /// /// - Task Send(string email, string login, Guid token); + Task Send(string email, string login, Guid token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/PasswordResetEmailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/PasswordResetEmailSender.cs index 4ce71028..9104dbea 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/PasswordResetEmailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/Confirmation/PasswordResetEmailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Configuration; using DM.Services.Mail.Rendering.Rendering; @@ -8,25 +9,15 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset.Confirmation; /// -internal class PasswordResetEmailSender : IPasswordResetEmailSender +internal class PasswordResetEmailSender( + IRenderer renderer, + IMailSender mailSender, + IOptions options) : IPasswordResetEmailSender { - private readonly IRenderer renderer; - private readonly IMailSender mailSender; - private readonly IntegrationSettings integrationSettings; - - /// - public PasswordResetEmailSender( - IRenderer renderer, - IMailSender mailSender, - IOptions integrationOptions) - { - this.renderer = renderer; - this.mailSender = mailSender; - integrationSettings = integrationOptions.Value; - } - + private readonly IntegrationSettings integrationSettings = options.Value; + /// - public async Task Send(string email, string login, Guid token) + public async Task Send(string email, string login, Guid token, CancellationToken cancellationToken) { var confirmationLinkUri = new Uri(new Uri(integrationSettings.WebUrl), $"password/{token}"); var emailBody = await renderer.Render("PasswordResetLetter", new PasswordResetConfirmationViewModel diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs index 47eee0b0..77797310 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Users; @@ -12,6 +13,7 @@ internal interface IPasswordResetRepository /// Create password restoration token /// /// + /// /// - Task CreateToken(Token token); + Task CreateToken(Token token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetService.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetService.cs index 79b0c22b..61e0fcb9 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -12,6 +13,7 @@ public interface IPasswordResetService /// Reset user password /// /// + /// /// - Task Reset(UserPasswordReset passwordReset); + Task Reset(UserPasswordReset passwordReset, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs index 921c4572..db9c39e1 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; @@ -5,21 +6,13 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset; /// -internal class PasswordResetRepository : IPasswordResetRepository +internal class PasswordResetRepository( + DmDbContext dbContext) : IPasswordResetRepository { - private readonly DmDbContext dbContext; - - /// - public PasswordResetRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public Task CreateToken(Token token) + public Task CreateToken(Token token, CancellationToken cancellationToken) { dbContext.Tokens.Add(token); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetService.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetService.cs index 0b124dfc..ef414797 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Account.PasswordReset.Confirmation; using DM.Services.Community.BusinessProcesses.Users.Reading; @@ -7,39 +8,23 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset; /// -internal class PasswordResetService : IPasswordResetService +internal class PasswordResetService( + IValidator validator, + IPasswordResetTokenFactory tokenFactory, + IUserReadingRepository userReadingRepository, + IPasswordResetRepository repository, + IPasswordResetEmailSender emailSender) : IPasswordResetService { - private readonly IValidator validator; - private readonly IPasswordResetTokenFactory tokenFactory; - private readonly IUserReadingRepository userReadingRepository; - private readonly IPasswordResetRepository repository; - private readonly IPasswordResetEmailSender emailSender; - - /// - public PasswordResetService( - IValidator validator, - IPasswordResetTokenFactory tokenFactory, - IUserReadingRepository userReadingRepository, - IPasswordResetRepository repository, - IPasswordResetEmailSender emailSender) - { - this.validator = validator; - this.tokenFactory = tokenFactory; - this.userReadingRepository = userReadingRepository; - this.repository = repository; - this.emailSender = emailSender; - } - /// - public async Task Reset(UserPasswordReset passwordReset) + public async Task Reset(UserPasswordReset passwordReset, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(passwordReset); - var user = await userReadingRepository.GetUserDetails(passwordReset.Login); + await validator.ValidateAndThrowAsync(passwordReset, cancellationToken); + var user = await userReadingRepository.GetUserDetails(passwordReset.Login, cancellationToken); var token = tokenFactory.Create(user.UserId); - await repository.CreateToken(token); + await repository.CreateToken(token, cancellationToken); - await emailSender.Send(user.Email, user.Login, token.TokenId); + await emailSender.Send(user.Email, user.Login, token.TokenId, cancellationToken); return user; } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/UserPasswordResetValidator.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/UserPasswordResetValidator.cs index d91fca74..57ad1f71 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/UserPasswordResetValidator.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/UserPasswordResetValidator.cs @@ -16,9 +16,9 @@ public UserPasswordResetValidator( { RuleFor(r => r.Login) .NotEmpty().WithMessage(ValidationError.Empty) - .MustAsync(async (_, login, context, _) => + .MustAsync(async (_, login, context, ct) => { - var user = await repository.GetUserDetails(login); + var user = await repository.GetUserDetails(login, ct); if (user == null) { return false; diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/IRegistrationMailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/IRegistrationMailSender.cs index d80661f3..bab3d1d3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/IRegistrationMailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/IRegistrationMailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Account.Registration.Confirmation; @@ -14,6 +15,7 @@ internal interface IRegistrationMailSender /// User email /// User login /// Confirmation token + /// /// - Task Send(string email, string login, Guid token); + Task Send(string email, string login, Guid token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/RegistrationMailSender.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/RegistrationMailSender.cs index dacd010f..1a8565ad 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/RegistrationMailSender.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/Confirmation/RegistrationMailSender.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Configuration; using DM.Services.Mail.Rendering.Rendering; @@ -26,7 +27,7 @@ public RegistrationMailSender( } /// - public async Task Send(string email, string login, Guid token) + public async Task Send(string email, string login, Guid token, CancellationToken cancellationToken) { var confirmationLinkUri = new Uri(new Uri(integrationSettings.WebUrl), $"activate/{token}"); var emailBody = await renderer.Render("RegistrationLetter", new RegistrationConfirmationViewModel diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs index a7e7bd1e..a25c4542 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs @@ -30,6 +30,7 @@ internal interface IRegistrationRepository /// /// User DAL /// + /// /// - Task AddUser(User user, Token token); + Task AddUser(User user, Token token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationService.cs index e247cc72..3e37e4ff 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Account.Registration; @@ -11,6 +12,7 @@ public interface IRegistrationService /// Register new user /// /// Registration info + /// /// - Task Register(UserRegistration registration); + Task Register(UserRegistration registration, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs index d13acbc4..80205b4d 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs @@ -7,30 +7,22 @@ namespace DM.Services.Community.BusinessProcesses.Account.Registration; /// -internal class RegistrationRepository : IRegistrationRepository +internal class RegistrationRepository( + DmDbContext dbContext) : IRegistrationRepository { - private readonly DmDbContext dbContext; - - /// - public RegistrationRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public Task EmailFree(string email, CancellationToken cancellationToken) => - dbContext.Users.AllAsync(u => u.Email.ToLower() != email.ToLower(), cancellationToken); + public async Task EmailFree(string email, CancellationToken cancellationToken) => + !await dbContext.Users.AnyAsync(u => u.Email.ToLower() == email.ToLower(), cancellationToken); /// - public Task LoginFree(string login, CancellationToken cancellationToken) => - dbContext.Users.AllAsync(u => u.Login.ToLower() != login.ToLower(), cancellationToken); + public async Task LoginFree(string login, CancellationToken cancellationToken) => + !await dbContext.Users.AnyAsync(u => u.Login.ToLower() == login.ToLower(), cancellationToken); /// - public Task AddUser(User user, Token token) + public Task AddUser(User user, Token token, CancellationToken cancellationToken) { dbContext.Users.Add(user); dbContext.Tokens.Add(token); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationService.cs index 84a5992a..64f8e9e8 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.Security; using DM.Services.Community.BusinessProcesses.Account.Activation; @@ -9,46 +10,26 @@ namespace DM.Services.Community.BusinessProcesses.Account.Registration; /// -internal class RegistrationService : IRegistrationService +internal class RegistrationService( + IValidator validator, + ISecurityManager securityManager, + IUserFactory userFactory, + IActivationTokenFactory activationTokenFactory, + IRegistrationRepository repository, + IRegistrationMailSender mailSender, + IInvokedEventProducer producer) : IRegistrationService { - private readonly IValidator validator; - private readonly ISecurityManager securityManager; - private readonly IUserFactory userFactory; - private readonly IActivationTokenFactory activationTokenFactory; - private readonly IRegistrationRepository repository; - private readonly IRegistrationMailSender mailSender; - private readonly IInvokedEventProducer producer; - - /// - public RegistrationService( - IValidator validator, - ISecurityManager securityManager, - IUserFactory userFactory, - IActivationTokenFactory activationTokenFactory, - IRegistrationRepository repository, - IRegistrationMailSender mailSender, - IInvokedEventProducer producer) - { - this.validator = validator; - this.securityManager = securityManager; - this.userFactory = userFactory; - this.activationTokenFactory = activationTokenFactory; - this.repository = repository; - this.mailSender = mailSender; - this.producer = producer; - } - /// - public async Task Register(UserRegistration registration) + public async Task Register(UserRegistration registration, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(registration); + await validator.ValidateAndThrowAsync(registration, cancellationToken); var (hash, salt) = securityManager.GeneratePassword(registration.Password); var user = userFactory.Create(registration, salt, hash); var token = activationTokenFactory.Create(user.UserId); - await repository.AddUser(user, token); - await mailSender.Send(user.Email, user.Login, token.TokenId); + await repository.AddUser(user, token, cancellationToken); + await mailSender.Send(user.Email, user.Login, token.TokenId, cancellationToken); await producer.Send(EventType.NewUser, user.UserId); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs index 0e34f35f..74f91fbb 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,6 +14,7 @@ internal interface ITokenVerificationRepository /// Get user that token was generated for /// /// + /// /// - Task GetTokenOwner(Guid tokenId); + Task GetTokenOwner(Guid tokenId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationService.cs index 9746171a..d9f696ae 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,6 +14,7 @@ public interface ITokenVerificationService /// Verify if the token is available /// /// Token + /// /// - Task Verify(Guid token); + Task Verify(Guid token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs index 5de89cf5..f6e4ba4b 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,24 +11,14 @@ namespace DM.Services.Community.BusinessProcesses.Account.Verification; /// -internal class TokenVerificationRepository : ITokenVerificationRepository +internal class TokenVerificationRepository( + DmDbContext dbContext, + IMapper mapper) : ITokenVerificationRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public TokenVerificationRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task GetTokenOwner(Guid tokenId) => dbContext.Tokens + public Task GetTokenOwner(Guid tokenId, CancellationToken cancellationToken) => dbContext.Tokens .Where(t => t.TokenId == tokenId && !t.IsRemoved) .Select(t => t.User) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationService.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationService.cs index 7571b80e..f94a2751 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationService.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Core.Exceptions; @@ -7,21 +8,13 @@ namespace DM.Services.Community.BusinessProcesses.Account.Verification; /// -internal class TokenVerificationService : ITokenVerificationService +internal class TokenVerificationService( + ITokenVerificationRepository repository) : ITokenVerificationService { - private readonly ITokenVerificationRepository repository; - - /// - public TokenVerificationService( - ITokenVerificationRepository repository) - { - this.repository = repository; - } - /// - public async Task Verify(Guid token) + public async Task Verify(Guid token, CancellationToken cancellationToken) { - var owner = await repository.GetTokenOwner(token); + var owner = await repository.GetTokenOwner(token, cancellationToken); if (owner == null) { throw new HttpException(HttpStatusCode.Gone, "Token is invalid"); diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs index c7ddbc01..19651522 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs @@ -1,37 +1,29 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Community.BusinessProcesses.Chat.Reading; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; +using DbMessage = DM.Services.DataAccess.BusinessObjects.Common.ChatMessage; namespace DM.Services.Community.BusinessProcesses.Chat.Creating; /// -internal class ChatCreatingRepository : IChatCreatingRepository +internal class ChatCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IChatCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ChatCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DataAccess.BusinessObjects.Common.ChatMessage chatMessage) + public async Task Create(DbMessage chatMessage, CancellationToken cancellationToken) { dbContext.ChatMessages.Add(chatMessage); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.ChatMessages .Where(m => m.ChatMessageId == chatMessage.ChatMessageId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingService.cs index fd4b7b73..0cf870e5 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -9,40 +10,22 @@ namespace DM.Services.Community.BusinessProcesses.Chat.Creating; /// -internal class ChatCreatingService : IChatCreatingService +internal class ChatCreatingService( + IValidator validator, + IIntentionManager intentionManager, + IChatMessageFactory factory, + IChatCreatingRepository repository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IChatCreatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IChatMessageFactory factory; - private readonly IChatCreatingRepository repository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public ChatCreatingService( - IValidator validator, - IIntentionManager intentionManager, - IChatMessageFactory factory, - IChatCreatingRepository repository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.factory = factory; - this.repository = repository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateChatMessage createChatMessage) + public async Task Create(CreateChatMessage createChatMessage, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createChatMessage); + await validator.ValidateAndThrowAsync(createChatMessage, cancellationToken); intentionManager.ThrowIfForbidden(ChatIntention.CreateMessage); var chatMessage = factory.Create(createChatMessage, identityProvider.Current.User.UserId); - var result = await repository.Create(chatMessage); + var result = await repository.Create(chatMessage, cancellationToken); await producer.Send(EventType.NewChatMessage, chatMessage.ChatMessageId); return result; diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs index 24dfad48..19f0d330 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Chat.Reading; using DbMessage = DM.Services.DataAccess.BusinessObjects.Common.ChatMessage; @@ -13,6 +14,7 @@ internal interface IChatCreatingRepository /// Create new chat message /// /// DAL model + /// /// - Task Create(DbMessage chatMessage); + Task Create(DbMessage chatMessage, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingService.cs index 61f4163e..b60df89f 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Chat.Reading; @@ -12,6 +13,7 @@ public interface IChatCreatingService /// Create new chat message /// /// Creating DTO + /// /// - Task Create(CreateChatMessage createChatMessage); + Task Create(CreateChatMessage createChatMessage, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs index bac77fbc..f43a39d2 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,43 +13,35 @@ namespace DM.Services.Community.BusinessProcesses.Chat.Reading; /// -internal class ChatReadingRepository : IChatReadingRepository +internal class ChatReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IChatReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ChatReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - + /// /// - public Task Count() => dbContext.ChatMessages.CountAsync(); + public Task Count(CancellationToken cancellationToken) => dbContext.ChatMessages.CountAsync(cancellationToken); /// - public async Task> Get(PagingData pagingData) => await dbContext.ChatMessages - .OrderByDescending(m => m.CreateDate) - .Page(pagingData) - .ProjectTo(mapper.ConfigurationProvider) - .OrderBy(m => m.CreateDate) - .ToArrayAsync(); + public async Task> Get(PagingData pagingData, CancellationToken cancellationToken) => + await dbContext.ChatMessages + .OrderByDescending(m => m.CreateDate) + .Page(pagingData) + .ProjectTo(mapper.ConfigurationProvider) + .OrderBy(m => m.CreateDate) + .ToArrayAsync(cancellationToken); /// - public async Task> Get(DateTimeOffset since) => + public async Task> Get(DateTimeOffset since, CancellationToken cancellationToken) => await dbContext.ChatMessages .OrderByDescending(m => m.CreateDate) .Where(m => m.CreateDate >= since) .ProjectTo(mapper.ConfigurationProvider) .OrderBy(m => m.CreateDate) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); /// - public async Task Get(Guid id) => await dbContext.ChatMessages + public async Task Get(Guid id, CancellationToken cancellationToken) => await dbContext.ChatMessages .Where(m => m.ChatMessageId == id) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingService.cs index 0b010b68..a6b10704 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto; @@ -9,38 +10,30 @@ namespace DM.Services.Community.BusinessProcesses.Chat.Reading; /// -internal class ChatReadingService : IChatReadingService +internal class ChatReadingService( + IChatReadingRepository repository, + IIdentityProvider identityProvider) : IChatReadingService { - private readonly IChatReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public ChatReadingService( - IChatReadingRepository repository, - IIdentityProvider identityProvider) - { - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task<(IEnumerable messages, PagingResult paging)> GetMessages(PagingQuery pagingQuery) + public async Task<(IEnumerable messages, PagingResult paging)> GetMessages( + PagingQuery pagingQuery, CancellationToken cancellationToken) { - var totalCount = await repository.Count(); + var totalCount = await repository.Count(cancellationToken); var pageSize = identityProvider.Current.Settings.Paging.EntitiesPerPage; var pagingData = new PagingData(pagingQuery, pageSize, totalCount); - var chatMessages = await repository.Get(pagingData); + var chatMessages = await repository.Get(pagingData, cancellationToken); return (chatMessages, pagingData.Result); } /// - public Task> GetNewMessages(DateTimeOffset since) => repository.Get(since); + public Task> GetNewMessages(DateTimeOffset since, CancellationToken cancellationToken) => + repository.Get(since, cancellationToken); /// - public async Task GetMessage(Guid id) + public async Task GetMessage(Guid id, CancellationToken cancellationToken) { - var chatMessage = await repository.Get(id); + var chatMessage = await repository.Get(id, cancellationToken); if (chatMessage == null) { throw new HttpException(HttpStatusCode.Gone, "Message not found"); diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs index 4d75a913..e5861caf 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,27 +14,31 @@ internal interface IChatReadingRepository /// /// Count chat messages /// + /// /// - Task Count(); + Task Count(CancellationToken cancellationToken); /// /// Get chat messages /// /// + /// /// - Task> Get(PagingData pagingData); + Task> Get(PagingData pagingData, CancellationToken cancellationToken); /// /// Get new messages since given moment /// /// + /// /// - Task> Get(DateTimeOffset since); + Task> Get(DateTimeOffset since, CancellationToken cancellationToken); /// /// Get single chat message /// /// + /// /// - Task Get(Guid id); + Task Get(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingService.cs index ed14fb67..1818dc07 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,19 +15,22 @@ public interface IChatReadingService /// Get list of chat messages /// /// - Task<(IEnumerable messages, PagingResult paging)> GetMessages(PagingQuery pagingQuery); + Task<(IEnumerable messages, PagingResult paging)> GetMessages(PagingQuery pagingQuery, + CancellationToken cancellationToken); /// /// Get list of new chat messages since given moment /// /// + /// /// - Task> GetNewMessages(DateTimeOffset since); + Task> GetNewMessages(DateTimeOffset since, CancellationToken cancellationToken); /// /// Get single chat message /// /// Message identifier + /// /// - Task GetMessage(Guid id); + Task GetMessage(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs index a9701513..83418d0b 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Messaging.Reading; using DM.Services.DataAccess.RelationalStorage; @@ -16,6 +17,8 @@ internal interface IMessageCreatingRepository /// /// /// + /// /// - Task Create(DbMessage message, IUpdateBuilder updateConversation); + Task Create(DbMessage message, IUpdateBuilder updateConversation, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingService.cs index 61ddf87f..66cb714b 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Messaging.Reading; @@ -12,6 +13,7 @@ public interface IMessageCreatingService /// Create new message /// /// DTO model + /// /// - Task Create(CreateMessage createMessage); + Task Create(CreateMessage createMessage, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs index b2f53550..46b9c084 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,30 +13,21 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Creating; /// -internal class MessageCreatingRepository : IMessageCreatingRepository +internal class MessageCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IMessageCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public MessageCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbMessage message, IUpdateBuilder updateConversation) + public async Task Create( + DbMessage message, IUpdateBuilder updateConversation, CancellationToken cancellationToken) { dbContext.Messages.Add(message); updateConversation.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Messages .Where(m => m.MessageId == message.MessageId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingService.cs index dd44b77d..0e26e287 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -13,54 +14,30 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Creating; /// -internal class MessageCreatingService : IMessageCreatingService +internal class MessageCreatingService( + IConversationReadingService conversationReadingService, + IValidator validator, + IIntentionManager intentionManager, + IMessageFactory factory, + IUpdateBuilderFactory updateBuilderFactory, + IMessageCreatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IMessageCreatingService { - private readonly IConversationReadingService conversationReadingService; - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IMessageFactory factory; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IMessageCreatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public MessageCreatingService( - IConversationReadingService conversationReadingService, - IValidator validator, - IIntentionManager intentionManager, - IMessageFactory factory, - IUpdateBuilderFactory updateBuilderFactory, - IMessageCreatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.conversationReadingService = conversationReadingService; - this.validator = validator; - this.intentionManager = intentionManager; - this.factory = factory; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateMessage createMessage) + public async Task Create(CreateMessage createMessage, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createMessage); - var conversation = await conversationReadingService.Get(createMessage.ConversationId); + await validator.ValidateAndThrowAsync(createMessage, cancellationToken); + var conversation = await conversationReadingService.Get(createMessage.ConversationId, cancellationToken); intentionManager.ThrowIfForbidden(ConversationIntention.CreateMessage, conversation); var message = factory.Create(createMessage, identityProvider.Current.User.UserId); var updateConversation = updateBuilderFactory.Create(conversation.Id) .Field(c => c.LastMessageId, message.MessageId); - var result = await repository.Create(message, updateConversation); - await unreadCountersRepository.Increment(conversation.Id, UnreadEntryType.Message); + var result = await repository.Create(message, updateConversation, cancellationToken); + await unreadCountersRepository.Increment(conversation.Id, UnreadEntryType.Message, cancellationToken); await producer.Send(EventType.NewMessage, message.MessageId); return result; diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/IMessageDeletingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/IMessageDeletingService.cs index 95ee023c..12157ed3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/IMessageDeletingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/IMessageDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Messaging.Deleting; @@ -12,6 +13,7 @@ public interface IMessageDeletingService /// Delete message /// /// Message identifier + /// /// - Task Delete(Guid messageId); + Task Delete(Guid messageId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/MessageDeletingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/MessageDeletingService.cs index 09be9d8b..5212f2fb 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/MessageDeletingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Deleting/MessageDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Messaging.Deleting; @@ -7,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Deleting; internal class MessageDeletingService : IMessageDeletingService { /// - public Task Delete(Guid messageId) + public Task Delete(Guid messageId, CancellationToken cancellationToken) { throw new NotImplementedException("Messages deleting is not available so far"); } diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs index 9d747818..28f7ed85 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -15,20 +16,10 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// -internal class ConversationReadingRepository : IConversationReadingRepository +internal class ConversationReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IConversationReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ConversationReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// /// Participation predicate /// @@ -38,51 +29,52 @@ public static Expression> UserParticipates(Guid userI c => c.UserLinks.Any(l => !l.IsRemoved && l.UserId == userId); /// - public Task Count(Guid userId) => dbContext.Conversations + public Task Count(Guid userId, CancellationToken cancellationToken) => dbContext.Conversations .Where(UserParticipates(userId)) - .CountAsync(); + .CountAsync(cancellationToken); /// - public async Task> Get(Guid userId, PagingData paging) => + public async Task> Get(Guid userId, PagingData paging, + CancellationToken cancellationToken) => await dbContext.Conversations .Where(UserParticipates(userId)) .Where(c => c.LastMessageId.HasValue) .OrderByDescending(c => c.LastMessage.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); /// - public Task Get(Guid conversationId, Guid userId) => dbContext.Conversations + public Task Get(Guid conversationId, Guid userId, CancellationToken cancellationToken) => dbContext.Conversations .Where(UserParticipates(userId)) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// - public async Task FindUser(string login) => (await dbContext.Users + public async Task FindUser(string login, CancellationToken cancellationToken) => (await dbContext.Users .Where(u => u.Login.ToLower() == login.ToLower() && !u.IsRemoved && u.Activated) .Select(u => new {u.UserId}) - .FirstOrDefaultAsync())?.UserId; + .FirstOrDefaultAsync(cancellationToken))?.UserId; /// - public Task FindVisaviConversation(Guid userId, Guid visaviId) => dbContext.Conversations + public Task FindVisaviConversation(Guid userId, Guid visaviId, CancellationToken cancellationToken) => dbContext.Conversations .Where(c => c.Visavi) .Where(UserParticipates(userId)) .Where(UserParticipates(visaviId)) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// public async Task Create(DbConversation conversation, - IEnumerable conversationLinks) + IEnumerable conversationLinks, CancellationToken cancellationToken) { dbContext.Conversations.Add(conversation); dbContext.UserConversationLinks.AddRange(conversationLinks); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Conversations .Where(c => c.ConversationId == conversation.ConversationId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingService.cs index bc313b67..1e7416ff 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -13,92 +14,79 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// -internal class ConversationReadingService : IConversationReadingService +internal class ConversationReadingService( + IConversationFactory factory, + IConversationReadingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IIdentityProvider identityProvider) : IConversationReadingService { - private readonly IConversationFactory factory; - private readonly IConversationReadingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public ConversationReadingService( - IConversationFactory factory, - IConversationReadingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IIdentityProvider identityProvider) - { - this.factory = factory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.identityProvider = identityProvider; - } - /// - public async Task<(IEnumerable conversations, PagingResult paging)> Get(PagingQuery query) + public async Task<(IEnumerable conversations, PagingResult paging)> Get( + PagingQuery query, CancellationToken cancellationToken) { var identity = identityProvider.Current; var currentUserId = identity.User.UserId; - var totalCount = await repository.Count(currentUserId); + var totalCount = await repository.Count(currentUserId, cancellationToken); var pagingData = new PagingData(query, identity.Settings.Paging.MessagesPerPage, totalCount); - var conversations = (await repository.Get(currentUserId, pagingData)).ToArray(); + var conversations = (await repository.Get(currentUserId, pagingData, cancellationToken)).ToArray(); await unreadCountersRepository.FillEntityCounters(conversations, currentUserId, - c => c.Id, c => c.UnreadMessagesCount); + c => c.Id, c => c.UnreadMessagesCount, UnreadEntryType.Message, cancellationToken); return (conversations, pagingData.Result); } /// - public async Task Get(Guid conversationId) + public async Task Get(Guid conversationId, CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var conversation = await repository.Get(conversationId, currentUserId); + var conversation = await repository.Get(conversationId, currentUserId, cancellationToken); if (conversation == null) { throw new HttpException(HttpStatusCode.Gone, "Conversation not found"); } await unreadCountersRepository.FillEntityCounters(new[] {conversation}, currentUserId, - c => c.Id, c => c.UnreadMessagesCount); + c => c.Id, c => c.UnreadMessagesCount, UnreadEntryType.Message, cancellationToken); return conversation; } /// - public async Task GetOrCreate(string login) + public async Task GetOrCreate(string login, CancellationToken cancellationToken) { - var visaviId = await repository.FindUser(login); + var visaviId = await repository.FindUser(login, cancellationToken); if (!visaviId.HasValue) { throw new HttpException(HttpStatusCode.Gone, "User not found"); } var currentUserId = identityProvider.Current.User.UserId; - var existingConversation = await repository.FindVisaviConversation(currentUserId, visaviId.Value); + var existingConversation = await repository.FindVisaviConversation(currentUserId, visaviId.Value, cancellationToken); if (existingConversation != null) { await unreadCountersRepository.FillEntityCounters(new[] {existingConversation}, currentUserId, - c => c.Id, c => c.UnreadMessagesCount); + c => c.Id, c => c.UnreadMessagesCount, UnreadEntryType.Message, cancellationToken); return existingConversation; } var (conversation, conversationLinks) = factory.CreateVisavi(currentUserId, visaviId.Value); - var result = await repository.Create(conversation, conversationLinks); + var result = await repository.Create(conversation, conversationLinks, cancellationToken); await unreadCountersRepository.Create(result.Id, UnreadEntryType.Message, - new[] {currentUserId, visaviId.Value}.Distinct()); + new[] {currentUserId, visaviId.Value}.Distinct().ToArray(), cancellationToken); return result; } /// - public async Task GetTotalUnreadCount() + public async Task GetTotalUnreadCount(CancellationToken cancellationToken) { var userId = identityProvider.Current.User.UserId; - return (await unreadCountersRepository.SelectByParents(userId, UnreadEntryType.Message, userId))[userId]; + return (await unreadCountersRepository.SelectByParents(userId, UnreadEntryType.Message, [userId], cancellationToken))[userId]; } /// - public Task MarkAsRead(Guid conversationId) => + public Task MarkAsRead(Guid conversationId, CancellationToken cancellationToken) => unreadCountersRepository.Flush(identityProvider.Current.User.UserId, - UnreadEntryType.Message, conversationId); + UnreadEntryType.Message, conversationId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs index 5538285b..021a309f 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DbConversation = DM.Services.DataAccess.BusinessObjects.Messaging.Conversation; @@ -16,45 +17,52 @@ internal interface IConversationReadingRepository /// Count user participated conversations /// /// User identifier + /// /// - Task Count(Guid userId); + Task Count(Guid userId, CancellationToken cancellationToken); /// /// Get list of user participated conversations /// /// User identifier /// Paging data + /// /// - Task> Get(Guid userId, PagingData paging); + Task> Get(Guid userId, PagingData paging, CancellationToken cancellationToken); /// /// Get single conversation for user /// /// Conversation identifier /// User identifier + /// /// - Task Get(Guid conversationId, Guid userId); + Task Get(Guid conversationId, Guid userId, CancellationToken cancellationToken); /// /// Find user for conversation /// /// User login + /// /// - Task FindUser(string login); + Task FindUser(string login, CancellationToken cancellationToken); /// /// Find existing visavi conversation /// /// User identifier /// Visavi user identifier + /// /// - Task FindVisaviConversation(Guid userId, Guid visaviId); + Task FindVisaviConversation(Guid userId, Guid visaviId, CancellationToken cancellationToken); /// /// Save conversation /// /// /// + /// /// - Task Create(DbConversation conversation, IEnumerable conversationLinks); + Task Create(DbConversation conversation, IEnumerable conversationLinks, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingService.cs index bca74e40..3b912c18 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,33 +15,38 @@ public interface IConversationReadingService /// Get list of user conversations /// /// Paging query + /// /// - Task<(IEnumerable conversations, PagingResult paging)> Get(PagingQuery query); + Task<(IEnumerable conversations, PagingResult paging)> Get( + PagingQuery query, CancellationToken cancellationToken); /// /// Get single conversation /// /// Conversation identifier + /// /// - Task Get(Guid conversationId); + Task Get(Guid conversationId, CancellationToken cancellationToken); /// /// Find user visavi conversation /// /// User login + /// /// - Task GetOrCreate(string login); + Task GetOrCreate(string login, CancellationToken cancellationToken); /// /// Count all unread conversations /// /// - Task GetTotalUnreadCount(); + Task GetTotalUnreadCount(CancellationToken cancellationToken); /// /// Mark all conversation messages as read /// /// Conversation identifier + /// /// - Task MarkAsRead(Guid conversationId); + Task MarkAsRead(Guid conversationId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs index a0733aa4..02073ed7 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,22 +15,25 @@ internal interface IMessageReadingRepository /// Count messages in conversation /// /// Conversation identifier + /// /// - Task Count(Guid conversationId); + Task Count(Guid conversationId, CancellationToken cancellationToken); /// /// Get messages /// /// Conversation identifier /// Paging data + /// /// - Task> Get(Guid conversationId, PagingData paging); + Task> Get(Guid conversationId, PagingData paging, CancellationToken cancellationToken); /// /// Get single message /// /// Message identifier /// User identifier + /// /// - Task Get(Guid messageId, Guid userId); + Task Get(Guid messageId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingService.cs index 7bb76603..7fc99f42 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -15,13 +16,16 @@ public interface IMessageReadingService /// /// Conversation identifier /// Paging query + /// /// - Task<(IEnumerable messages, PagingResult paging)> Get(Guid conversationId, PagingQuery query); + Task<(IEnumerable messages, PagingResult paging)> Get(Guid conversationId, PagingQuery query, + CancellationToken cancellationToken); /// /// Get single message /// /// Message identifier + /// /// - Task Get(Guid messageId); + Task Get(Guid messageId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs index 6306792a..034de7d2 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,38 +13,29 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// -internal class MessageReadingRepository : IMessageReadingRepository +internal class MessageReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IMessageReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public MessageReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(Guid conversationId) => dbContext.Messages + public Task Count(Guid conversationId, CancellationToken cancellationToken) => dbContext.Messages .Where(m => !m.IsRemoved && m.ConversationId == conversationId) - .CountAsync(); + .CountAsync(cancellationToken); /// - public async Task> Get(Guid conversationId, PagingData paging) => await dbContext.Messages + public async Task> Get(Guid conversationId, PagingData paging, + CancellationToken cancellationToken) => await dbContext.Messages .Where(m => !m.IsRemoved && m.ConversationId == conversationId) .OrderBy(m => m.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); /// - public Task Get(Guid messageId, Guid userId) => dbContext.Conversations + public Task Get(Guid messageId, Guid userId, CancellationToken cancellationToken) => dbContext.Conversations .Where(ConversationReadingRepository.UserParticipates(userId)) .SelectMany(c => c.Messages) .Where(m => !m.IsRemoved && m.MessageId == messageId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingService.cs index dc53397e..3228b4d9 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto; @@ -9,39 +10,27 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// -internal class MessageReadingService : IMessageReadingService +internal class MessageReadingService( + IConversationReadingService conversationReadingService, + IMessageReadingRepository repository, + IIdentityProvider identityProvider) : IMessageReadingService { - private readonly IConversationReadingService conversationReadingService; - private readonly IMessageReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public MessageReadingService( - IConversationReadingService conversationReadingService, - IMessageReadingRepository repository, - IIdentityProvider identityProvider) - { - this.conversationReadingService = conversationReadingService; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// public async Task<(IEnumerable messages, PagingResult paging)> Get( - Guid conversationId, PagingQuery query) + Guid conversationId, PagingQuery query, CancellationToken cancellationToken) { - await conversationReadingService.Get(conversationId); - var totalCount = await repository.Count(conversationId); + await conversationReadingService.Get(conversationId, cancellationToken); + var totalCount = await repository.Count(conversationId, cancellationToken); var pagingData = new PagingData(query, identityProvider.Current.Settings.Paging.MessagesPerPage, totalCount); - var messages = await repository.Get(conversationId, pagingData); + var messages = await repository.Get(conversationId, pagingData, cancellationToken); return (messages, pagingData.Result); } /// - public async Task Get(Guid messageId) + public async Task Get(Guid messageId, CancellationToken cancellationToken) { - var message = await repository.Get(messageId, identityProvider.Current.User.UserId); + var message = await repository.Get(messageId, identityProvider.Current.User.UserId, cancellationToken); if (message == null) { throw new HttpException(HttpStatusCode.Gone, "Message not found"); diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs index 47691e3a..04e8a40a 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; using DbPoll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; @@ -13,6 +14,7 @@ internal interface IPollCreatingRepository /// Create new poll /// /// + /// /// - Task Create(DbPoll poll); + Task Create(DbPoll poll, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingService.cs index aa493817..0aa3b3b6 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; @@ -12,6 +13,7 @@ public interface IPollCreatingService /// Create new poll and start immediately /// /// + /// /// - Task Create(CreatePoll createPoll); + Task Create(CreatePoll createPoll, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs index 3596801e..c52b20d5 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs @@ -1,25 +1,23 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; using DM.Services.DataAccess.MongoIntegration; using MongoDB.Driver; +using DbPoll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; using Poll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; namespace DM.Services.Community.BusinessProcesses.Polls.Creating; /// -internal class PollCreatingRepository : MongoCollectionRepository, IPollCreatingRepository +internal class PollCreatingRepository(DmMongoClient client) + : MongoCollectionRepository(client), IPollCreatingRepository { /// - public PollCreatingRepository(DmMongoClient client) : base(client) + public async Task Create(DbPoll poll, CancellationToken cancellationToken) { - } - - /// - public async Task Create(Poll poll) - { - await Collection.InsertOneAsync(poll); + await Collection.InsertOneAsync(poll, cancellationToken: cancellationToken); return await Collection.Find(Filter.Eq(p => p.Id, poll.Id)) .Project(PollReadingRepository.PollProjection) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingService.cs index 9593908b..7a830b40 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Community.BusinessProcesses.Polls.Reading; @@ -8,37 +9,21 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Creating; /// -internal class PollCreatingService : IPollCreatingService +internal class PollCreatingService( + IValidator validator, + IIntentionManager intentionManager, + IPollFactory factory, + IPollCreatingRepository repository, + IInvokedEventProducer producer) : IPollCreatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IPollFactory factory; - private readonly IPollCreatingRepository repository; - private readonly IInvokedEventProducer producer; - - /// - public PollCreatingService( - IValidator validator, - IIntentionManager intentionManager, - IPollFactory factory, - IPollCreatingRepository repository, - IInvokedEventProducer producer) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.factory = factory; - this.repository = repository; - this.producer = producer; - } - /// - public async Task Create(CreatePoll createPoll) + public async Task Create(CreatePoll createPoll, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createPoll); + await validator.ValidateAndThrowAsync(createPoll, cancellationToken); intentionManager.ThrowIfForbidden(PollIntention.Create); var poll = factory.Create(createPoll); - var result = await repository.Create(poll); + var result = await repository.Create(poll, cancellationToken); await producer.Send(EventType.NewPoll, result.Id); return result; diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs index d2015ecf..192f46a4 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,21 +15,24 @@ internal interface IPollReadingRepository /// Count all /// /// + /// /// - Task Count(DateTimeOffset? activeAt); + Task Count(DateTimeOffset? activeAt, CancellationToken cancellationToken); /// /// Get list of polls /// /// /// + /// /// - Task> Get(DateTimeOffset? activeAt, PagingData pagingData); + Task> Get(DateTimeOffset? activeAt, PagingData pagingData, CancellationToken cancellationToken); /// /// Get single poll by id /// /// + /// /// - Task Get(Guid id); + Task Get(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingService.cs index 91c615bf..b26dd727 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -15,13 +16,16 @@ public interface IPollReadingService /// /// Paging query /// Only get active polls + /// /// - Task<(IEnumerable polls, PagingResult paging)> Get(PagingQuery pagingQuery, bool onlyActive); + Task<(IEnumerable polls, PagingResult paging)> Get( + PagingQuery pagingQuery, bool onlyActive, CancellationToken cancellationToken); /// /// Get single poll /// /// Poll identifier + /// /// - Task Get(Guid pollId); + Task Get(Guid pollId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs index 8d7c49f1..0dea0553 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.DataAccess.MongoIntegration; @@ -10,7 +11,8 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Reading; /// -internal class PollReadingRepository : MongoCollectionRepository, IPollReadingRepository +internal class PollReadingRepository(DmMongoClient client) + : MongoCollectionRepository(client), IPollReadingRepository { /// /// Projection for poll @@ -31,18 +33,15 @@ internal class PollReadingRepository : MongoCollectionRepository, IPollR }); /// - public PollReadingRepository(DmMongoClient client) : base(client) - { - } - - /// - public Task Count(DateTimeOffset? activeUntil) => + public Task Count(DateTimeOffset? activeUntil, CancellationToken cancellationToken) => Collection.CountDocumentsAsync(activeUntil.HasValue ? Filter.Gte(p => p.EndDate, activeUntil.Value.UtcDateTime) - : Filter.Empty); + : Filter.Empty, + cancellationToken: cancellationToken); /// - public async Task> Get(DateTimeOffset? activeUntil, PagingData pagingData) + public async Task> Get(DateTimeOffset? activeUntil, PagingData pagingData, + CancellationToken cancellationToken) { return await Collection .Find(activeUntil.HasValue @@ -52,12 +51,12 @@ public async Task> Get(DateTimeOffset? activeUntil, PagingData .Skip(pagingData.Skip) .Limit(pagingData.Take) .Project(PollProjection) - .ToListAsync(); + .ToListAsync(cancellationToken); } /// - public Task Get(Guid id) => Collection + public Task Get(Guid id, CancellationToken cancellationToken) => Collection .Find(Filter.Eq(p => p.Id, id)) .Project(PollProjection) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingService.cs index 88cc230f..7e8cd1c2 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto; @@ -10,38 +11,27 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Reading; /// -internal class PollReadingService : IPollReadingService +internal class PollReadingService( + IPollReadingRepository repository, + IDateTimeProvider dateTimeProvider, + IIdentityProvider identityProvider) : IPollReadingService { - private readonly IPollReadingRepository repository; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IIdentityProvider identityProvider; - - /// - public PollReadingService( - IPollReadingRepository repository, - IDateTimeProvider dateTimeProvider, - IIdentityProvider identityProvider) - { - this.repository = repository; - this.dateTimeProvider = dateTimeProvider; - this.identityProvider = identityProvider; - } - /// - public async Task<(IEnumerable polls, PagingResult paging)> Get(PagingQuery pagingQuery, bool onlyActive) + public async Task<(IEnumerable polls, PagingResult paging)> Get( + PagingQuery pagingQuery, bool onlyActive, CancellationToken cancellationToken) { var activeAt = onlyActive ? dateTimeProvider.Now : (DateTimeOffset?) null; - var totalCount = await repository.Count(activeAt); + var totalCount = await repository.Count(activeAt, cancellationToken); var pageSize = identityProvider.Current.Settings.Paging.EntitiesPerPage; var pagingData = new PagingData(pagingQuery, pageSize, (int) totalCount); - var polls = await repository.Get(activeAt, pagingData); + var polls = await repository.Get(activeAt, pagingData, cancellationToken); return (polls, pagingData.Result); } /// - public async Task Get(Guid pollId) + public async Task Get(Guid pollId, CancellationToken cancellationToken) { - var poll = await repository.Get(pollId); + var poll = await repository.Get(pollId, cancellationToken); if (poll == null) { throw new HttpException(HttpStatusCode.Gone, "Poll not found"); diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs index f0a45a02..7732f95c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; @@ -15,6 +16,7 @@ internal interface IPollVotingRepository /// Poll identifier /// Option identifier /// User identifier + /// /// - Task Vote(Guid pollId, Guid optionId, Guid userId); + Task Vote(Guid pollId, Guid optionId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingService.cs index f4ea1aeb..b6079edd 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; @@ -14,6 +15,7 @@ public interface IPollVotingService /// /// Poll identifier /// Option identifier + /// /// - Task Vote(Guid pollId, Guid optionId); + Task Vote(Guid pollId, Guid optionId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs index 7ce8f2ba..645a5172 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; using DM.Services.DataAccess.MongoIntegration; @@ -9,15 +10,11 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Voting; /// -internal class PollVotingRepository : MongoCollectionRepository, IPollVotingRepository +internal class PollVotingRepository(DmMongoClient client) + : MongoCollectionRepository(client), IPollVotingRepository { /// - public PollVotingRepository(DmMongoClient client) : base(client) - { - } - - /// - public Task Vote(Guid pollId, Guid optionId, Guid userId) => + public Task Vote(Guid pollId, Guid optionId, Guid userId, CancellationToken cancellationToken) => Collection.FindOneAndUpdateAsync( Filter.Eq(p => p.Id, pollId) & Filter.ElemMatch(p => p.Options, o => o.Id == optionId), @@ -26,5 +23,6 @@ public Task Vote(Guid pollId, Guid optionId, Guid userId) => { Projection = PollReadingRepository.PollProjection, ReturnDocument = ReturnDocument.After - }); + }, + cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingService.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingService.cs index 5c36f875..d8ef5df5 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -7,32 +8,18 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Voting; /// -internal class PollVotingService : IPollVotingService +internal class PollVotingService( + IPollReadingService readingService, + IPollVotingRepository repository, + IIntentionManager intentionManager, + IIdentityProvider identityProvider) : IPollVotingService { - private readonly IPollReadingService readingService; - private readonly IPollVotingRepository repository; - private readonly IIntentionManager intentionManager; - private readonly IIdentityProvider identityProvider; - - /// - public PollVotingService( - IPollReadingService readingService, - IPollVotingRepository repository, - IIntentionManager intentionManager, - IIdentityProvider identityProvider) - { - this.readingService = readingService; - this.repository = repository; - this.intentionManager = intentionManager; - this.identityProvider = identityProvider; - } - /// - public async Task Vote(Guid pollId, Guid optionId) + public async Task Vote(Guid pollId, Guid optionId, CancellationToken cancellationToken) { - var poll = await readingService.Get(pollId); + var poll = await readingService.Get(pollId, cancellationToken); intentionManager.ThrowIfForbidden(PollIntention.Vote, (poll, optionId)); - return await repository.Vote(pollId, optionId, identityProvider.Current.User.UserId); + return await repository.Vote(pollId, optionId, identityProvider.Current.User.UserId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs index 5c73c4c5..40228df8 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DbReview = DM.Services.DataAccess.BusinessObjects.Common.Review; @@ -13,6 +14,7 @@ internal interface IReviewCreatingRepository /// Create new review /// /// + /// /// - Task Create(DbReview review); + Task Create(DbReview review, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingService.cs index 57d96b9a..2082ffe9 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Reviews.Reading; @@ -12,6 +13,7 @@ public interface IReviewCreatingService /// Create new review /// /// + /// /// - Task Create(CreateReview createReview); + Task Create(CreateReview createReview, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs index b21c8d0a..afecd76c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs @@ -1,36 +1,28 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; +using DbReview = DM.Services.DataAccess.BusinessObjects.Common.Review; namespace DM.Services.Community.BusinessProcesses.Reviews.Creating; /// -internal class ReviewCreatingRepository : IReviewCreatingRepository +internal class ReviewCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IReviewCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ReviewCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DataAccess.BusinessObjects.Common.Review review) + public async Task Create(DbReview review, CancellationToken cancellationToken) { dbContext.Reviews.Add(review); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Reviews .Where(r => r.ReviewId == review.ReviewId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingService.cs index 6f9a23d0..9dd579d0 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -7,36 +8,20 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Creating; /// -internal class ReviewCreatingService : IReviewCreatingService +internal class ReviewCreatingService( + IValidator validator, + IIntentionManager intentionManager, + IReviewFactory factory, + IReviewCreatingRepository repository, + IIdentityProvider identityProvider) : IReviewCreatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IReviewFactory factory; - private readonly IReviewCreatingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public ReviewCreatingService( - IValidator validator, - IIntentionManager intentionManager, - IReviewFactory factory, - IReviewCreatingRepository repository, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.factory = factory; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateReview createReview) + public async Task Create(CreateReview createReview, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createReview); + await validator.ValidateAndThrowAsync(createReview, cancellationToken); intentionManager.ThrowIfForbidden(ReviewIntention.Create); var review = factory.Create(createReview, identityProvider.Current.User.UserId); - return await repository.Create(review); + return await repository.Create(review, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/IReviewDeletingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/IReviewDeletingService.cs index f1a33fa4..e04892d1 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/IReviewDeletingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/IReviewDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Community.BusinessProcesses.Reviews.Deleting; @@ -12,6 +13,7 @@ public interface IReviewDeletingService /// Delete existing review /// /// Review identifier + /// /// - Task Delete(Guid id); + Task Delete(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/ReviewDeletingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/ReviewDeletingService.cs index cfc66fbf..b2a0881d 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/ReviewDeletingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Deleting/ReviewDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Community.BusinessProcesses.Reviews.Reading; @@ -9,32 +10,18 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Deleting; /// -internal class ReviewDeletingService : IReviewDeletingService +internal class ReviewDeletingService( + IReviewReadingService reviewReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IReviewUpdatingRepository repository) : IReviewDeletingService { - private readonly IReviewReadingService reviewReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IReviewUpdatingRepository repository; - - /// - public ReviewDeletingService( - IReviewReadingService reviewReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IReviewUpdatingRepository repository) - { - this.reviewReadingService = reviewReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - } - /// - public async Task Delete(Guid id) + public async Task Delete(Guid id, CancellationToken cancellationToken) { - var review = await reviewReadingService.Get(id); + var review = await reviewReadingService.Get(id, cancellationToken); intentionManager.ThrowIfForbidden(ReviewIntention.Delete, review); var deleteReview = updateBuilderFactory.Create(id).Field(r => r.IsRemoved, true); - await repository.Update(deleteReview); + await repository.Update(deleteReview, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs index 88ca5d09..f432c3c3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,21 +15,24 @@ internal interface IReviewReadingRepository /// Get total count of reviews /// /// Only count approved reviews + /// /// - Task Count(bool approvedOnly); + Task Count(bool approvedOnly, CancellationToken cancellationToken); /// /// Get reviews list /// /// Paging data /// Only return approved reviews + /// /// - Task> Get(PagingData paging, bool approvedOnly); + Task> Get(PagingData paging, bool approvedOnly, CancellationToken cancellationToken); /// /// Get single review /// /// Review identifier + /// /// - Task Get(Guid id); + Task Get(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingService.cs index 449bd685..5d84154f 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -15,13 +16,16 @@ public interface IReviewReadingService /// /// /// + /// /// - Task<(IEnumerable reviews, PagingResult paging)> Get(PagingQuery query, bool onlyApproved); + Task<(IEnumerable reviews, PagingResult paging)> Get(PagingQuery query, bool onlyApproved, + CancellationToken cancellationToken); /// /// Get single review /// /// + /// /// - Task Get(Guid id); + Task Get(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs index d2958ced..d8434135 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,36 +13,30 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Reading; /// -internal class ReviewReadingRepository : IReviewReadingRepository +internal class ReviewReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IReviewReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ReviewReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(bool approvedOnly) => dbContext.Reviews - .Where(r => (!approvedOnly || r.IsApproved) && !r.IsRemoved) - .CountAsync(); + public Task Count(bool approvedOnly, CancellationToken cancellationToken) => + dbContext.Reviews + .Where(r => (!approvedOnly || r.IsApproved) && !r.IsRemoved) + .CountAsync(cancellationToken); /// - public async Task> Get(PagingData paging, bool approvedOnly) => await dbContext.Reviews - .Where(r => (!approvedOnly || r.IsApproved) && !r.IsRemoved) - .OrderByDescending(r => r.CreateDate) - .Page(paging) - .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + public async Task> Get(PagingData paging, bool approvedOnly, + CancellationToken cancellationToken) => + await dbContext.Reviews + .Where(r => (!approvedOnly || r.IsApproved) && !r.IsRemoved) + .OrderByDescending(r => r.CreateDate) + .Page(paging) + .ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken); /// - public Task Get(Guid id) => dbContext.Reviews - .Where(r => !r.IsRemoved && r.ReviewId == id) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + public Task Get(Guid id, CancellationToken cancellationToken) => + dbContext.Reviews + .Where(r => !r.IsRemoved && r.ReviewId == id) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingService.cs index 50de2203..ead55059 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -10,39 +11,28 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Reading; /// -internal class ReviewReadingService : IReviewReadingService +internal class ReviewReadingService( + IIntentionManager intentionManager, + IReviewReadingRepository repository, + IIdentityProvider identityProvider) : IReviewReadingService { - private readonly IIntentionManager intentionManager; - private readonly IReviewReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public ReviewReadingService( - IIntentionManager intentionManager, - IReviewReadingRepository repository, - IIdentityProvider identityProvider) - { - this.intentionManager = intentionManager; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task<(IEnumerable reviews, PagingResult paging)> Get(PagingQuery query, bool onlyApproved) + public async Task<(IEnumerable reviews, PagingResult paging)> Get( + PagingQuery query, bool onlyApproved, CancellationToken cancellationToken) { onlyApproved = onlyApproved || !intentionManager.IsAllowed(ReviewIntention.ReadUnapproved); - var totalCount = await repository.Count(onlyApproved); + var totalCount = await repository.Count(onlyApproved, cancellationToken); var pagingData = new PagingData(query, identityProvider.Current.Settings.Paging.EntitiesPerPage, totalCount); - var reviews = await repository.Get(pagingData, onlyApproved); + var reviews = await repository.Get(pagingData, onlyApproved, cancellationToken); return (reviews, pagingData.Result); } /// - public async Task Get(Guid id) + public async Task Get(Guid id, CancellationToken cancellationToken) { - var review = await repository.Get(id); + var review = await repository.Get(id, cancellationToken); if (review == null || !review.Approved && !intentionManager.IsAllowed(ReviewIntention.ReadUnapproved)) { throw new HttpException(HttpStatusCode.Gone, "Review not found"); diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs index 1048b9b2..e1a3a29e 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DM.Services.DataAccess.RelationalStorage; @@ -14,6 +15,7 @@ internal interface IReviewUpdatingRepository /// Update review /// /// + /// /// - Task Update(IUpdateBuilder updateReview); + Task Update(IUpdateBuilder updateReview, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingService.cs index 24b0c02a..a61aca42 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Reviews.Reading; @@ -12,6 +13,7 @@ public interface IReviewUpdatingService /// Update existing review /// /// + /// /// - Task Update(UpdateReview updateReview); + Task Update(UpdateReview updateReview, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs index 728a380c..c9fc61af 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,28 +11,19 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Updating; /// -internal class ReviewUpdatingRepository : IReviewUpdatingRepository +internal class ReviewUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : IReviewUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ReviewUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder updateReview) + public async Task Update(IUpdateBuilder updateReview, + CancellationToken cancellationToken) { var reviewId = updateReview.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Reviews .Where(r => r.ReviewId == reviewId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingService.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingService.cs index 662c3164..f8227395 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Community.BusinessProcesses.Reviews.Reading; @@ -8,34 +9,18 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Updating; /// -internal class ReviewUpdatingService : IReviewUpdatingService +internal class ReviewUpdatingService( + IValidator validator, + IReviewReadingService readingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IReviewUpdatingRepository repository) : IReviewUpdatingService { - private readonly IValidator validator; - private readonly IReviewReadingService readingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IReviewUpdatingRepository repository; - - /// - public ReviewUpdatingService( - IValidator validator, - IReviewReadingService readingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IReviewUpdatingRepository repository) - { - this.validator = validator; - this.readingService = readingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - } - /// - public async Task Update(UpdateReview updateReview) + public async Task Update(UpdateReview updateReview, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateReview); - var review = await readingService.Get(updateReview.ReviewId); + await validator.ValidateAndThrowAsync(updateReview, cancellationToken); + var review = await readingService.Get(updateReview.ReviewId, cancellationToken); var reviewChanges = updateBuilderFactory.Create(review.Id); if (updateReview.Approved.HasValue && updateReview.Approved.Value != review.Approved) @@ -50,7 +35,7 @@ public async Task Update(UpdateReview updateReview) reviewChanges.MaybeField(r => r.Text, updateReview.Text.Trim()); } - var result = await repository.Update(reviewChanges); + var result = await repository.Update(reviewChanges, cancellationToken); return result; } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs index 3348c9ce..59e2b8f6 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,28 +14,32 @@ internal interface IUserReadingRepository /// Count community users by filter /// /// Count inactive users too + /// /// Number of the users - Task CountUsers(bool withInactive); + Task CountUsers(bool withInactive, CancellationToken cancellationToken); /// /// Get users list on paging data /// /// Paging data /// Search among inactive users + /// /// List of users found - Task> GetUsers(PagingData paging, bool withInactive); + Task> GetUsers(PagingData paging, bool withInactive, CancellationToken cancellationToken); /// /// Get user by login /// /// + /// /// - Task GetUser(string login); + Task GetUser(string login, CancellationToken cancellationToken); /// /// Get user details by login /// /// User login + /// /// User found. Null if none found - Task GetUserDetails(string login); + Task GetUserDetails(string login, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingService.cs index 15755553..586447bb 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,20 +15,24 @@ public interface IUserReadingService /// /// Paging query /// Search among inactive users + /// /// Pair of found users and paging data - Task<(IEnumerable users, PagingResult paging)> Get(PagingQuery query, bool withInactive); + Task<(IEnumerable users, PagingResult paging)> Get( + PagingQuery query, bool withInactive, CancellationToken cancellationToken); /// /// Get community user short info by login /// /// User login + /// /// - Task Get(string login); + Task Get(string login, CancellationToken cancellationToken); /// /// Get community user details by login /// /// User login + /// /// Found user - Task GetDetails(string login); + Task GetDetails(string login, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs index d70e9518..5e148193 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -17,38 +18,28 @@ namespace DM.Services.Community.BusinessProcesses.Users.Reading; /// -internal class UserReadingRepository : MongoCollectionRepository, IUserReadingRepository +internal class UserReadingRepository( + DmDbContext dmDbContext, + DmMongoClient mongoClient, + IDateTimeProvider dateTimeProvider, + IMapper mapper) : MongoCollectionRepository(mongoClient), IUserReadingRepository { - private readonly DmDbContext dmDbContext; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IMapper mapper; - - /// - public UserReadingRepository( - DmDbContext dmDbContext, - DmMongoClient mongoClient, - IDateTimeProvider dateTimeProvider, - IMapper mapper) : base(mongoClient) - { - this.dmDbContext = dmDbContext; - this.dateTimeProvider = dateTimeProvider; - this.mapper = mapper; - } - private static readonly TimeSpan ActivityRange = TimeSpan.FromDays(30); /// - public Task CountUsers(bool withInactive) => GetQuery(withInactive).CountAsync(); + public Task CountUsers(bool withInactive, CancellationToken cancellationToken) => + GetQuery(withInactive).CountAsync(cancellationToken); /// - public async Task> GetUsers(PagingData paging, bool withInactive) => + public async Task> GetUsers(PagingData paging, bool withInactive, + CancellationToken cancellationToken) => await GetQuery(withInactive) .OrderBy(u => u.RatingDisabled) .ThenByDescending(u => u.QualityRating) .ThenBy(u => u.QuantityRating) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); private IQueryable GetQuery(bool withInactive) { @@ -65,18 +56,18 @@ private IQueryable GetQuery(bool withInactive) } /// - public Task GetUser(string login) => dmDbContext.Users + public Task GetUser(string login, CancellationToken cancellationToken) => dmDbContext.Users .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); /// - public async Task GetUserDetails(string login) + public async Task GetUserDetails(string login, CancellationToken cancellationToken) { var userDetails = await dmDbContext.Users .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); if (userDetails == null) { @@ -85,7 +76,7 @@ public async Task GetUserDetails(string login) var userSettings = await Collection .Find(Filter.Eq(u => u.UserId, userDetails.UserId)) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); userDetails.Settings = userSettings == null ? Authentication.Dto.UserSettings.Default : mapper.Map(userSettings); diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingService.cs b/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingService.cs index e6d4955c..a0cc3d16 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto; @@ -8,34 +9,24 @@ namespace DM.Services.Community.BusinessProcesses.Users.Reading; /// -internal class UserReadingService : IUserReadingService +internal class UserReadingService( + IIdentityProvider identityProvider, + IUserReadingRepository readingRepository) : IUserReadingService { - private readonly IIdentityProvider identityProvider; - private readonly IUserReadingRepository readingRepository; - - /// - public UserReadingService( - IIdentityProvider identityProvider, - IUserReadingRepository readingRepository) - { - this.identityProvider = identityProvider; - this.readingRepository = readingRepository; - } - /// public async Task<(IEnumerable users, PagingResult paging)> Get( - PagingQuery query, bool withInactive) + PagingQuery query, bool withInactive, CancellationToken cancellationToken) { - var totalCount = await readingRepository.CountUsers(withInactive); + var totalCount = await readingRepository.CountUsers(withInactive, cancellationToken); var paging = new PagingData(query, identityProvider.Current.Settings.Paging.EntitiesPerPage, totalCount); - var users = await readingRepository.GetUsers(paging, withInactive); + var users = await readingRepository.GetUsers(paging, withInactive, cancellationToken); return (users, paging.Result); } /// - public async Task Get(string login) + public async Task Get(string login, CancellationToken cancellationToken) { - var user = await readingRepository.GetUser(login); + var user = await readingRepository.GetUser(login, cancellationToken); if (user == null) { throw new HttpException(HttpStatusCode.Gone, $"User {login} not found"); @@ -45,9 +36,9 @@ public async Task Get(string login) } /// - public async Task GetDetails(string login) + public async Task GetDetails(string login, CancellationToken cancellationToken) { - var user = await readingRepository.GetUserDetails(login); + var user = await readingRepository.GetUserDetails(login, cancellationToken); if (user == null) { throw new HttpException(HttpStatusCode.Gone, $"User {login} not found"); diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs index 481a6ec6..3b48f5cd 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Users; using DM.Services.DataAccess.BusinessObjects.Users.Settings; @@ -15,6 +16,8 @@ internal interface IUserUpdatingRepository /// /// /// + /// /// - Task UpdateUser(IUpdateBuilder updateUser, IUpdateBuilder settingsUpdate); + Task UpdateUser(IUpdateBuilder updateUser, IUpdateBuilder settingsUpdate, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingService.cs b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingService.cs index 5f3f5437..0dd9c094 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingService.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Users.Reading; @@ -13,8 +14,9 @@ public interface IUserUpdatingService /// Update user details /// /// + /// /// - Task Update(UpdateUser updateUser); + Task Update(UpdateUser updateUser, CancellationToken cancellationToken); /// /// Upload user profile picture @@ -23,6 +25,8 @@ public interface IUserUpdatingService /// Uploaded file stream /// File name /// Content type + /// /// - Task UploadPicture(string login, Stream uploadStream, string fileName, string contentType); + Task UploadPicture(string login, Stream uploadStream, string fileName, string contentType, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs index 8b1e6db0..3a58acad 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; @@ -8,25 +9,18 @@ namespace DM.Services.Community.BusinessProcesses.Users.Updating; /// -internal class UserUpdatingRepository : MongoCollectionRepository, IUserUpdatingRepository +internal class UserUpdatingRepository( + DmDbContext dbContext, + DmMongoClient client) : MongoCollectionRepository(client), IUserUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly DmMongoClient mongoClient; + private readonly DmMongoClient mongoClient = client; /// - public UserUpdatingRepository( - DmDbContext dbContext, - DmMongoClient mongoClient) : base(mongoClient) - { - this.dbContext = dbContext; - this.mongoClient = mongoClient; - } - - /// - public async Task UpdateUser(IUpdateBuilder updateUser, IUpdateBuilder settingsUpdate) + public async Task UpdateUser(IUpdateBuilder updateUser, IUpdateBuilder settingsUpdate, + CancellationToken cancellationToken) { updateUser.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); - await settingsUpdate.UpdateFor(mongoClient, true); + await dbContext.SaveChangesAsync(cancellationToken); + await settingsUpdate.UpdateFor(mongoClient, true, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingService.cs b/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingService.cs index c344409a..b721649e 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingService.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingService.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Community.BusinessProcesses.Users.Reading; @@ -12,37 +13,19 @@ namespace DM.Services.Community.BusinessProcesses.Users.Updating; /// -internal class UserUpdatingService : IUserUpdatingService +internal class UserUpdatingService( + IValidator validator, + IUserReadingService userReadingService, + IPublicImageService imageService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IUserUpdatingRepository repository) : IUserUpdatingService { - private readonly IValidator validator; - private readonly IUserReadingService userReadingService; - private readonly IPublicImageService imageService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IUserUpdatingRepository repository; - - /// - public UserUpdatingService( - IValidator validator, - IUserReadingService userReadingService, - IPublicImageService imageService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IUserUpdatingRepository repository) - { - this.validator = validator; - this.userReadingService = userReadingService; - this.imageService = imageService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - } - /// - public async Task Update(UpdateUser updateUser) + public async Task Update(UpdateUser updateUser, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateUser); - var user = await userReadingService.Get(updateUser.Login); + await validator.ValidateAndThrowAsync(updateUser, cancellationToken); + var user = await userReadingService.Get(updateUser.Login, cancellationToken); intentionManager.IsAllowed(UserIntention.Edit, user); var userUpdate = updateBuilderFactory.Create(user.UserId) @@ -62,15 +45,15 @@ public async Task Update(UpdateUser updateUser) .MaybeField(u => u.Paging.PostsPerPage, updateUser.Settings?.Paging?.PostsPerPage) .MaybeField(u => u.Paging.EntitiesPerPage, updateUser.Settings?.Paging?.EntitiesPerPage); - await repository.UpdateUser(userUpdate, settingsUpdate); - return await userReadingService.GetDetails(updateUser.Login); + await repository.UpdateUser(userUpdate, settingsUpdate, cancellationToken); + return await userReadingService.GetDetails(updateUser.Login, cancellationToken); } /// public async Task UploadPicture(string login, Stream uploadStream, string fileName, - string contentType) + string contentType, CancellationToken cancellationToken) { - var user = await userReadingService.Get(login); + var user = await userReadingService.Get(login, cancellationToken); var (original, medium, small) = await imageService.Upload(new CreateUpload { @@ -78,17 +61,17 @@ public async Task UploadPicture(string login, Stream uploadStream, FileName = fileName, ContentType = contentType, StreamAccessor = () => uploadStream - }); + }, cancellationToken); var userUpdate = updateBuilderFactory.Create(user.UserId) .Field(u => u.ProfilePictureUrl, original.FilePath) .Field(u => u.MediumProfilePictureUrl, medium.FilePath) .Field(u => u.SmallProfilePictureUrl, small.FilePath); var settingsUpdate = updateBuilderFactory.Create(user.UserId); - await repository.UpdateUser(userUpdate, settingsUpdate); + await repository.UpdateUser(userUpdate, settingsUpdate, cancellationToken); - await imageService.PrepareObsoleteForDeleting(user.UserId); + await imageService.PrepareObsoleteForDeleting(user.UserId, cancellationToken); - return await userReadingService.GetDetails(login); + return await userReadingService.GetDetails(login, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.DataAccess/RelationalStorage/IUpdateBuilder.cs b/src/DM.Services.DataAccess/RelationalStorage/IUpdateBuilder.cs index 72ce7e44..c18ba656 100644 --- a/src/DM.Services.DataAccess/RelationalStorage/IUpdateBuilder.cs +++ b/src/DM.Services.DataAccess/RelationalStorage/IUpdateBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.MongoIntegration; using Microsoft.EntityFrameworkCore; @@ -44,5 +45,5 @@ public interface IUpdateBuilder /// Save changes in mongodb /// /// - Task UpdateFor(DmMongoClient mongoClient, bool upsert); + Task UpdateFor(DmMongoClient mongoClient, bool upsert, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.DataAccess/RelationalStorage/UpdateBuilder.cs b/src/DM.Services.DataAccess/RelationalStorage/UpdateBuilder.cs index bf94dca7..e9eea5db 100644 --- a/src/DM.Services.DataAccess/RelationalStorage/UpdateBuilder.cs +++ b/src/DM.Services.DataAccess/RelationalStorage/UpdateBuilder.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.MongoIntegration; using Microsoft.EntityFrameworkCore; @@ -98,7 +99,7 @@ public Guid AttachTo(DbContext dbContext) return id; } - public async Task UpdateFor(DmMongoClient mongoClient, bool upsert) + public async Task UpdateFor(DmMongoClient mongoClient, bool upsert, CancellationToken cancellationToken) { var entityType = typeof(TEntity); if (entityType.GetCustomAttribute() == null) diff --git a/src/DM.Services.Forum/Authorization/ForumIntentionResolver.cs b/src/DM.Services.Forum/Authorization/ForumIntentionResolver.cs index e667a44d..157ad250 100644 --- a/src/DM.Services.Forum/Authorization/ForumIntentionResolver.cs +++ b/src/DM.Services.Forum/Authorization/ForumIntentionResolver.cs @@ -7,17 +7,9 @@ namespace DM.Services.Forum.Authorization; /// -internal class ForumIntentionResolver : IIntentionResolver +internal class ForumIntentionResolver( + IAccessPolicyConverter accessPolicyConverter) : IIntentionResolver { - private readonly IAccessPolicyConverter accessPolicyConverter; - - /// - public ForumIntentionResolver( - IAccessPolicyConverter accessPolicyConverter) - { - this.accessPolicyConverter = accessPolicyConverter; - } - /// public bool IsAllowed(AuthenticatedUser user, ForumIntention intention, Dto.Output.Forum target) { diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs index 12d30b41..136b66b4 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,22 +12,13 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Creating; /// -internal class CommentaryCreatingRepository : ICommentaryCreatingRepository +internal class CommentaryCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(Comment comment, IUpdateBuilder topicUpdate) + public async Task Create(Comment comment, IUpdateBuilder topicUpdate, + CancellationToken cancellationToken) { dbContext.Comments.Add(comment); topicUpdate.AttachTo(dbContext); diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs index bbeebfe3..59109ccb 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -17,54 +18,30 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Creating; /// -internal class CommentaryCreatingService : ICommentaryCreatingService +internal class CommentaryCreatingService( + IValidator validator, + ITopicReadingService topicReadingService, + IIntentionManager intentionManager, + IIdentityProvider identityProvider, + ICommentaryFactory commentaryFactory, + IUpdateBuilderFactory updateBuilderFactory, + ICommentaryCreatingRepository repository, + IUnreadCountersRepository countersRepository, + IInvokedEventProducer invokedEventProducer) : ICommentaryCreatingService { - private readonly IValidator validator; - private readonly ITopicReadingService topicReadingService; - private readonly IIntentionManager intentionManager; - private readonly IIdentityProvider identityProvider; - private readonly ICommentaryFactory commentaryFactory; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICommentaryCreatingRepository repository; - private readonly IUnreadCountersRepository countersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryCreatingService( - IValidator validator, - ITopicReadingService topicReadingService, - IIntentionManager intentionManager, - IIdentityProvider identityProvider, - ICommentaryFactory commentaryFactory, - IUpdateBuilderFactory updateBuilderFactory, - ICommentaryCreatingRepository repository, - IUnreadCountersRepository countersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.topicReadingService = topicReadingService; - this.intentionManager = intentionManager; - this.commentaryFactory = commentaryFactory; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.countersRepository = countersRepository; - this.invokedEventProducer = invokedEventProducer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateComment createComment) + public async Task Create(CreateComment createComment, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createComment); + await validator.ValidateAndThrowAsync(createComment, cancellationToken); - var topic = await topicReadingService.GetTopic(createComment.EntityId); + var topic = await topicReadingService.GetTopic(createComment.EntityId, cancellationToken); intentionManager.ThrowIfForbidden(TopicIntention.CreateComment, topic); var comment = commentaryFactory.Create(createComment, identityProvider.Current.User.UserId); var topicUpdate = updateBuilderFactory.Create(topic.Id) .Field(t => t.LastCommentId, comment.CommentId); - var createdComment = await repository.Create(comment, topicUpdate); - await countersRepository.Increment(topic.Id, UnreadEntryType.Message); + var createdComment = await repository.Create(comment, topicUpdate, cancellationToken); + await countersRepository.Increment(topic.Id, UnreadEntryType.Message, cancellationToken); await invokedEventProducer.Send(EventType.NewForumComment, comment.CommentId); return createdComment; diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs index f8cdc9f8..e7fca598 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.DataAccess.RelationalStorage; @@ -15,6 +16,8 @@ public interface ICommentaryCreatingRepository /// /// DAL model for comment /// Updating for parent topic (denormalize) + /// /// - Task Create(Comment comment, IUpdateBuilder topicUpdate); + Task Create( + Comment comment, IUpdateBuilder topicUpdate, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs index 05537a36..a7aaa0f1 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; @@ -12,6 +13,7 @@ public interface ICommentaryCreatingService /// Create new commentary /// /// Create commentary DTO model + /// /// - Task Create(CreateComment createComment); + Task Create(CreateComment createComment, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs index 76b538c0..42b82b0b 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,40 +14,31 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; /// -internal class CommentaryDeletingRepository : ICommentaryDeletingRepository +internal class CommentaryDeletingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryDeletingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryDeletingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task GetForDelete(Guid commentId) + public Task GetForDelete(Guid commentId, CancellationToken cancellationToken) { return dbContext.Comments .TagWith("DM.Forum.CommentToDelete") .Where(c => !c.IsRemoved && c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } /// - public Task Delete(IUpdateBuilder update, IUpdateBuilder topicUpdate) + public Task Delete(IUpdateBuilder update, IUpdateBuilder topicUpdate, + CancellationToken cancellationToken) { update.AttachTo(dbContext); topicUpdate.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } /// - public async Task GetSecondLastCommentId(Guid topicId) + public async Task GetSecondLastCommentId(Guid topicId, CancellationToken cancellationToken) { var result = await dbContext.Comments .TagWith("DM.Forum.SecondLastCommentAfterDelete") @@ -54,7 +46,7 @@ public Task Delete(IUpdateBuilder update, IUpdateBuilder to .OrderByDescending(c => c.CreateDate) .Skip(1) .Select(c => c.CommentId) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return result == default ? null : result; } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs index bebaff98..8efaaee8 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -13,46 +14,31 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; /// -internal class CommentaryDeletingService : ICommentaryDeletingService +internal class CommentaryDeletingService( + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + ICommentaryDeletingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer invokedEventProducer) : ICommentaryDeletingService { - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICommentaryDeletingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryDeletingService( - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - ICommentaryDeletingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task Delete(Guid commentId) + public async Task Delete(Guid commentId, CancellationToken cancellationToken) { - var comment = await repository.GetForDelete(commentId); + var comment = await repository.GetForDelete(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Delete, (Services.Common.Dto.Comment) comment); var updateTopic = updateBuilderFactory.Create(comment.EntityId); if (comment.IsLastCommentOfTopic) { - var previousCommentaryId = await repository.GetSecondLastCommentId(comment.EntityId); + var previousCommentaryId = await repository.GetSecondLastCommentId(comment.EntityId, cancellationToken); updateTopic = updateTopic.Field(t => t.LastCommentId, previousCommentaryId); } var updateComment = updateBuilderFactory.Create(commentId) .Field(c => c.IsRemoved, true); - await repository.Delete(updateComment, updateTopic); - await unreadCountersRepository.Decrement(comment.EntityId, UnreadEntryType.Message, comment.CreateDate); + await repository.Delete(updateComment, updateTopic, cancellationToken); + await unreadCountersRepository.Decrement( + comment.EntityId, UnreadEntryType.Message, comment.CreateDate, cancellationToken); await invokedEventProducer.Send(EventType.DeletedForumComment, commentId); } diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs index b71f731d..36833b9f 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Common; using DM.Services.DataAccess.BusinessObjects.Fora; @@ -16,21 +17,25 @@ internal interface ICommentaryDeletingRepository /// Get single comment to delete by its identifier /// /// + /// /// - Task GetForDelete(Guid commentId); + Task GetForDelete(Guid commentId, CancellationToken cancellationToken); /// /// Gets second last commentary identifier of the topic /// /// Topic identifier + /// /// Null if the only commentary of topic is the last one - Task GetSecondLastCommentId(Guid topicId); + Task GetSecondLastCommentId(Guid topicId, CancellationToken cancellationToken); /// /// Update existing commentary /// /// Updated fields /// Updating for parent topic (denormalize) + /// /// - Task Delete(IUpdateBuilder update, IUpdateBuilder topicUpdate); + Task Delete(IUpdateBuilder update, IUpdateBuilder topicUpdate, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs index 01911b9b..111ca22d 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; @@ -12,6 +13,7 @@ public interface ICommentaryDeletingService /// Delete commentary by identifier /// /// Commentary identifier + /// /// - Task Delete(Guid commentId); + Task Delete(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs index 79a19a0e..97841373 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,27 +14,18 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Reading; /// -internal class CommentaryReadingRepository : ICommentaryReadingRepository +internal class CommentaryReadingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(Guid topicId) => dbContext.Comments + public Task Count(Guid topicId, CancellationToken cancellationToken) => dbContext.Comments .TagWith("DM.Forum.CommentsCount") - .CountAsync(c => !c.IsRemoved && c.EntityId == topicId); + .CountAsync(c => !c.IsRemoved && c.EntityId == topicId, cancellationToken); /// - public async Task> Get(Guid topicId, PagingData paging) + public async Task> Get( + Guid topicId, PagingData paging, CancellationToken cancellationToken) { return await dbContext.Comments .TagWith("DM.Forum.CommentsList") @@ -41,16 +33,16 @@ public async Task> Get(Guid topicId, PagingData paging) .OrderBy(c => c.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); } /// - public Task Get(Guid commentId) + public Task Get(Guid commentId, CancellationToken cancellationToken) { return dbContext.Comments .TagWith("DM.Forum.Comment") .Where(c => !c.IsRemoved && c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs index fc8844d3..9be1c070 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -14,63 +15,47 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Reading; /// -internal class CommentaryReadingService : ICommentaryReadingService +internal class CommentaryReadingService( + ITopicReadingService topicReadingService, + IForumReadingService forumReadingService, + IIdentityProvider identityProvider, + IUnreadCountersRepository unreadCountersRepository, + ICommentaryReadingRepository commentaryRepository) : ICommentaryReadingService { - private readonly ITopicReadingService topicReadingService; - private readonly IForumReadingService forumReadingService; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly ICommentaryReadingRepository commentaryRepository; - private readonly IIdentityProvider identityProvider; - - /// - public CommentaryReadingService( - ITopicReadingService topicReadingService, - IForumReadingService forumReadingService, - IIdentityProvider identityProvider, - IUnreadCountersRepository unreadCountersRepository, - ICommentaryReadingRepository commentaryRepository) - { - this.topicReadingService = topicReadingService; - this.forumReadingService = forumReadingService; - this.unreadCountersRepository = unreadCountersRepository; - this.commentaryRepository = commentaryRepository; - this.identityProvider = identityProvider; - } - /// public async Task<(IEnumerable comments, PagingResult paging)> Get( - Guid topicId, PagingQuery query) + Guid topicId, PagingQuery query, CancellationToken cancellationToken) { - await topicReadingService.GetTopic(topicId); + await topicReadingService.GetTopic(topicId, cancellationToken); - var totalCount = await commentaryRepository.Count(topicId); + var totalCount = await commentaryRepository.Count(topicId, cancellationToken); var paging = new PagingData(query, identityProvider.Current.Settings.Paging.CommentsPerPage, totalCount); - var comments = await commentaryRepository.Get(topicId, paging); + var comments = await commentaryRepository.Get(topicId, paging, cancellationToken); return (comments, paging.Result); } /// - public async Task Get(Guid commentId) + public async Task Get(Guid commentId, CancellationToken cancellationToken) { - return await commentaryRepository.Get(commentId) ?? + return await commentaryRepository.Get(commentId, cancellationToken) ?? throw new HttpException(HttpStatusCode.Gone, $"Comment {commentId} not found"); } /// - public async Task MarkAsRead(Guid topicId) + public async Task MarkAsRead(Guid topicId, CancellationToken cancellationToken) { - await topicReadingService.GetTopic(topicId); + await topicReadingService.GetTopic(topicId, cancellationToken); await unreadCountersRepository.Flush(identityProvider.Current.User.UserId, - UnreadEntryType.Message, topicId); + UnreadEntryType.Message, topicId, cancellationToken); } /// - public async Task MarkAsRead(string forumTitle) + public async Task MarkAsRead(string forumTitle, CancellationToken cancellationToken) { - var forum = await forumReadingService.GetForum(forumTitle); + var forum = await forumReadingService.GetForum(forumTitle, true, cancellationToken); await unreadCountersRepository.FlushAll(identityProvider.Current.User.UserId, - UnreadEntryType.Message, forum.Id); + UnreadEntryType.Message, forum.Id, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs index ac2ca70c..e8c0476a 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; using DM.Services.Core.Dto; @@ -15,21 +16,24 @@ internal interface ICommentaryReadingRepository /// Count comments of the topic /// /// Topic id + /// /// Number of topic comments - Task Count(Guid topicId); + Task Count(Guid topicId, CancellationToken cancellationToken); /// /// Get comments list of the topic /// /// Topic id /// Paging data + /// /// - Task> Get(Guid topicId, PagingData paging); + Task> Get(Guid topicId, PagingData paging, CancellationToken cancellationToken); /// /// Get single comment by its identifier /// /// Commentary identifier + /// /// Found commentary - Task Get(Guid commentId); + Task Get(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs index 13aaa180..7fe43492 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using Comment = DM.Services.Common.Dto.Comment; @@ -16,27 +17,32 @@ public interface ICommentaryReadingService /// /// Topic identifier /// Paging query + /// /// Pair of comments list and paging data - Task<(IEnumerable comments, PagingResult paging)> Get(Guid topicId, PagingQuery query); + Task<(IEnumerable comments, PagingResult paging)> Get(Guid topicId, PagingQuery query, + CancellationToken cancellationToken); /// /// Get topic comment by id /// /// Commentary identifier + /// /// Found comment - Task Get(Guid commentId); + Task Get(Guid commentId, CancellationToken cancellationToken); /// /// Mark all topic comments as read /// /// Topic identifier + /// /// - Task MarkAsRead(Guid topicId); + Task MarkAsRead(Guid topicId, CancellationToken cancellationToken); /// /// Mark all forum comments as read /// /// Forum title + /// /// - Task MarkAsRead(string forumTitle); + Task MarkAsRead(string forumTitle, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs index 86d0a980..57c33eae 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,29 +11,20 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Updating; /// -internal class CommentaryUpdatingRepository : ICommentaryUpdatingRepository +internal class CommentaryUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder update) + public async Task Update( + IUpdateBuilder update, CancellationToken cancellationToken) { var commentId = update.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Comments .TagWith("DM.Forum.UpdatedComment") .Where(c => c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs index 5bbab660..21d2d7bc 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.Dto; @@ -13,40 +14,21 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Updating; /// -internal class CommentaryUpdatingService : ICommentaryUpdatingService +internal class CommentaryUpdatingService( + IValidator validator, + ICommentaryReadingService commentaryReadingService, + IIntentionManager intentionManager, + IDateTimeProvider dateTimeProvider, + IUpdateBuilderFactory updateBuilderFactory, + ICommentaryUpdatingRepository repository, + IInvokedEventProducer invokedEventProducer) : ICommentaryUpdatingService { - private readonly IValidator validator; - private readonly ICommentaryReadingService commentaryReadingService; - private readonly IIntentionManager intentionManager; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICommentaryUpdatingRepository repository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryUpdatingService( - IValidator validator, - ICommentaryReadingService commentaryReadingService, - IIntentionManager intentionManager, - IDateTimeProvider dateTimeProvider, - IUpdateBuilderFactory updateBuilderFactory, - ICommentaryUpdatingRepository repository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.commentaryReadingService = commentaryReadingService; - this.intentionManager = intentionManager; - this.dateTimeProvider = dateTimeProvider; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task Update(UpdateComment updateComment) + public async Task Update( + UpdateComment updateComment, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateComment); - var comment = await commentaryReadingService.Get(updateComment.CommentId); + await validator.ValidateAndThrowAsync(updateComment, cancellationToken); + var comment = await commentaryReadingService.Get(updateComment.CommentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Edit, comment); var updateBuilder = updateBuilderFactory.Create(updateComment.CommentId) @@ -57,7 +39,7 @@ public CommentaryUpdatingService( updateBuilder.Field(f => f.LastUpdateDate, dateTimeProvider.Now); } - var updatedComment = await repository.Update(updateBuilder); + var updatedComment = await repository.Update(updateBuilder, cancellationToken); await invokedEventProducer.Send(EventType.ChangedForumComment, updateComment.CommentId); return updatedComment; } diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs index 80714e80..fad161d3 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using Comment = DM.Services.DataAccess.BusinessObjects.Common.Comment; @@ -13,6 +14,7 @@ public interface ICommentaryUpdatingRepository /// Update single commentary /// /// Update commentary + /// /// - Task Update(IUpdateBuilder update); + Task Update(IUpdateBuilder update, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs index 32736f48..d77094ac 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; @@ -12,6 +13,7 @@ public interface ICommentaryUpdatingService /// Update existing comment /// /// Update comment model + /// /// - Task Update(UpdateComment updateComment); + Task Update(UpdateComment updateComment, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Common/AccessPolicyConverter.cs b/src/DM.Services.Forum/BusinessProcesses/Common/AccessPolicyConverter.cs index e1aa561d..067943eb 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Common/AccessPolicyConverter.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Common/AccessPolicyConverter.cs @@ -16,22 +16,22 @@ public ForumAccessPolicy Convert(UserRole role) var result = ForumAccessPolicy.Guest | ForumAccessPolicy.Player; if (role.HasFlag(UserRole.Administrator)) { - result = result | ForumAccessPolicy.Administrator; + result |= ForumAccessPolicy.Administrator; } if (role.HasFlag(UserRole.SeniorModerator)) { - result = result | ForumAccessPolicy.SeniorModerator; + result |= ForumAccessPolicy.SeniorModerator; } if (role.HasFlag(UserRole.RegularModerator)) { - result = result | ForumAccessPolicy.RegularModerator; + result |= ForumAccessPolicy.RegularModerator; } if (role.HasFlag(UserRole.NannyModerator)) { - result = result | ForumAccessPolicy.NannyModerator; + result |= ForumAccessPolicy.NannyModerator; } return result; diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Fora/ForumReadingService.cs index ab2c95e6..ed6edd41 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Fora/ForumReadingService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -13,58 +14,46 @@ namespace DM.Services.Forum.BusinessProcesses.Fora; /// -internal class ForumReadingService : IForumReadingService +internal class ForumReadingService( + IIdentityProvider identityProvider, + IAccessPolicyConverter accessPolicyConverter, + IForumRepository forumRepository, + IUnreadCountersRepository unreadCountersRepository) : IForumReadingService { - private readonly IIdentityProvider identityProvider; - private readonly IAccessPolicyConverter accessPolicyConverter; - private readonly IForumRepository forumRepository; - private readonly IUnreadCountersRepository unreadCountersRepository; - - /// - public ForumReadingService( - IIdentityProvider identityProvider, - IAccessPolicyConverter accessPolicyConverter, - IForumRepository forumRepository, - IUnreadCountersRepository unreadCountersRepository) - { - this.identityProvider = identityProvider; - this.accessPolicyConverter = accessPolicyConverter; - this.forumRepository = forumRepository; - this.unreadCountersRepository = unreadCountersRepository; - } - + /// /// - public async Task> GetForaList() + public async Task> GetForaList(CancellationToken cancellationToken) { - var fora = await GetFora(); + var fora = await GetFora(true, cancellationToken); var identity = identityProvider.Current; if (identity.User.IsAuthenticated) { await unreadCountersRepository.FillParentCounters(fora, identity.User.UserId, - f => f.Id, f => f.UnreadTopicsCount); + f => f.Id, f => f.UnreadTopicsCount, cancellationToken); } return fora; } /// - public async Task GetSingleForum(string forumTitle) + public async Task GetSingleForum(string forumTitle, CancellationToken cancellationToken) { - var forum = await GetForum(forumTitle); + var forum = await GetForum(forumTitle, true, cancellationToken); var identity = identityProvider.Current; if (identity.User.IsAuthenticated) { forum.UnreadTopicsCount = (await unreadCountersRepository.SelectByParents( - identity.User.UserId, UnreadEntryType.Message, forum.Id))[forum.Id]; + identity.User.UserId, UnreadEntryType.Message, [forum.Id], cancellationToken))[forum.Id]; } return forum; } /// - public async Task GetForum(string forumTitle, bool onlyAvailable = true) + public async Task GetForum( + string forumTitle, bool onlyAvailable, CancellationToken cancellationToken) { - var forum = (await GetFora(onlyAvailable)).FirstOrDefault(f => f.Title == forumTitle); + var forum = (await GetFora(onlyAvailable, cancellationToken)).FirstOrDefault(f => f.Title == forumTitle); if (forum == null) { throw new HttpException(HttpStatusCode.Gone, $"Forum {forumTitle} not found"); @@ -73,11 +62,11 @@ await unreadCountersRepository.FillParentCounters(fora, identity.User.UserId, return forum; } - private async Task GetFora(bool onlyAvailable = true) + private async Task GetFora(bool onlyAvailable, CancellationToken cancellationToken) { var accessPolicy = onlyAvailable ? accessPolicyConverter.Convert(identityProvider.Current.User.Role) : (ForumAccessPolicy?) null; - return (await forumRepository.SelectFora(accessPolicy)).ToArray(); + return (await forumRepository.SelectFora(accessPolicy, cancellationToken)).ToArray(); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs index 9444cfc0..c05cf084 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -18,13 +19,14 @@ internal class ForumRepository( : IForumRepository { /// - public async Task> SelectFora(ForumAccessPolicy? accessPolicy) + public async Task> SelectFora(ForumAccessPolicy? accessPolicy, + CancellationToken cancellationToken) { var forums = await cache.GetOrCreate>("Fora", async () => await dmDbContext.Fora .TagWith("DM.Forum.ForaList") .OrderBy(f => f.Order) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync()); + .ToArrayAsync(cancellationToken)); if (accessPolicy.HasValue) { diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumReadingService.cs index aa2b69ac..c9afc2cd 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumReadingService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Forum.BusinessProcesses.Fora; @@ -11,21 +12,24 @@ public interface IForumReadingService /// /// Get list of available fora /// + /// /// - Task> GetForaList(); + Task> GetForaList(CancellationToken cancellationToken); /// /// Get available forum by title with counters /// /// Forum title + /// /// - Task GetSingleForum(string forumTitle); + Task GetSingleForum(string forumTitle, CancellationToken cancellationToken); /// /// Get available forum by title with no counters /// /// Forum title + /// /// Only search in forums that are available for display for current user /// - Task GetForum(string forumTitle, bool onlyAvailable = true); + Task GetForum(string forumTitle, bool onlyAvailable, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs index 265ae6c2..714181ef 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto.Enums; @@ -13,6 +14,7 @@ internal interface IForumRepository /// Get list of available fora by access policy /// /// Forum access policy + /// /// - Task> SelectFora(ForumAccessPolicy? accessPolicy); + Task> SelectFora(ForumAccessPolicy? accessPolicy, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Likes/ILikeService.cs b/src/DM.Services.Forum/BusinessProcesses/Likes/ILikeService.cs index 0ab9dfd9..9a151866 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Likes/ILikeService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Likes/ILikeService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,27 +14,31 @@ public interface ILikeService /// Create new like from current user to selected topic /// /// Topic identifier + /// /// User who liked the topic - Task LikeTopic(Guid topicId); + Task LikeTopic(Guid topicId, CancellationToken cancellationToken); /// /// Remove existing like from current user to selected topic /// /// Topic identifier + /// /// - Task DislikeTopic(Guid topicId); + Task DislikeTopic(Guid topicId, CancellationToken cancellationToken); /// /// Create new like from current user to selected comment /// /// Comment identifier + /// /// User who liked the comment - Task LikeComment(Guid commentId); + Task LikeComment(Guid commentId, CancellationToken cancellationToken); /// /// Remove existing like from current user to selected comment /// /// Comment identifier + /// /// - Task DislikeComment(Guid commentId); + Task DislikeComment(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Likes/LikeService.cs b/src/DM.Services.Forum/BusinessProcesses/Likes/LikeService.cs index 2fcb60aa..d22aa058 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Likes/LikeService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Likes/LikeService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -15,57 +16,45 @@ namespace DM.Services.Forum.BusinessProcesses.Likes; /// /// Forum like service /// -internal class LikeService : LikeServiceBase, ILikeService +internal class LikeService( + ITopicReadingService topicReadingService, + ICommentaryReadingService commentaryReadingService, + IIntentionManager intentionManager, + IIdentityProvider identityProvider, + ILikeFactory likeFactory, + ILikeRepository likeRepository, + IInvokedEventProducer invokedEventProducer) + : LikeServiceBase(identityProvider, likeFactory, likeRepository, invokedEventProducer), ILikeService { - private readonly ITopicReadingService topicReadingService; - private readonly ICommentaryReadingService commentaryReadingService; - private readonly IIntentionManager intentionManager; - - /// - public LikeService( - ITopicReadingService topicReadingService, - ICommentaryReadingService commentaryReadingService, - IIntentionManager intentionManager, - IIdentityProvider identityProvider, - ILikeFactory likeFactory, - ILikeRepository likeRepository, - IInvokedEventProducer invokedEventProducer) - : base(identityProvider, likeFactory, likeRepository, invokedEventProducer) - { - this.topicReadingService = topicReadingService; - this.commentaryReadingService = commentaryReadingService; - this.intentionManager = intentionManager; - } - /// - public async Task LikeTopic(Guid topicId) + public async Task LikeTopic(Guid topicId, CancellationToken cancellationToken) { - var topic = await topicReadingService.GetTopic(topicId); + var topic = await topicReadingService.GetTopic(topicId, cancellationToken); intentionManager.ThrowIfForbidden(TopicIntention.Like, topic); - return await Like(topic, EventType.LikedTopic); + return await Like(topic, EventType.LikedTopic, cancellationToken); } /// - public async Task LikeComment(Guid commentId) + public async Task LikeComment(Guid commentId, CancellationToken cancellationToken) { - var comment = await commentaryReadingService.Get(commentId); + var comment = await commentaryReadingService.Get(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Like, comment); - return await Like(comment, EventType.LikedForumComment); + return await Like(comment, EventType.LikedForumComment, cancellationToken); } /// - public async Task DislikeTopic(Guid topicId) + public async Task DislikeTopic(Guid topicId, CancellationToken cancellationToken) { - var topic = await topicReadingService.GetTopic(topicId); + var topic = await topicReadingService.GetTopic(topicId, cancellationToken); intentionManager.ThrowIfForbidden(TopicIntention.Like, topic); - await Dislike(topic); + await Dislike(topic, cancellationToken); } /// - public async Task DislikeComment(Guid commentId) + public async Task DislikeComment(Guid commentId, CancellationToken cancellationToken) { - var comment = await commentaryReadingService.Get(commentId); + var comment = await commentaryReadingService.Get(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Like, comment); - await Dislike(comment); + await Dislike(comment, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs index ebceb817..9ddbe0ca 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,6 +15,7 @@ internal interface IModeratorRepository /// Get list of forum moderators /// /// Forum id + /// /// - Task> Get(Guid forumId); + Task> Get(Guid forumId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorsReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorsReadingService.cs index de3a2a9e..ea1b8527 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorsReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorsReadingService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,6 +14,7 @@ public interface IModeratorsReadingService /// Get list of forum moderators by forum title /// /// Forum title + /// /// - Task> GetModerators(string forumTitle); + Task> GetModerators(string forumTitle, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs index 0958d83d..f80e5e11 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,28 +12,18 @@ namespace DM.Services.Forum.BusinessProcesses.Moderation; /// -internal class ModeratorRepository : IModeratorRepository +internal class ModeratorRepository( + DmDbContext dmDbContext, + IMapper mapper) : IModeratorRepository { - private readonly DmDbContext dmDbContext; - private readonly IMapper mapper; - - /// - public ModeratorRepository( - DmDbContext dmDbContext, - IMapper mapper) - { - this.dmDbContext = dmDbContext; - this.mapper = mapper; - } - /// - public async Task> Get(Guid forumId) + public async Task> Get(Guid forumId, CancellationToken cancellationToken) { return await dmDbContext.ForumModerators .TagWith("DM.Forum.ModeratorsList") .Where(m => m.ForumId == forumId) .Select(m => m.User) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorsReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorsReadingService.cs index 3500d3d8..e72ca374 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorsReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorsReadingService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Forum.BusinessProcesses.Fora; @@ -6,24 +7,14 @@ namespace DM.Services.Forum.BusinessProcesses.Moderation; /// -internal class ModeratorsReadingService : IModeratorsReadingService +internal class ModeratorsReadingService( + IForumReadingService forumReadingService, + IModeratorRepository moderatorRepository) : IModeratorsReadingService { - private readonly IForumReadingService forumReadingService; - private readonly IModeratorRepository moderatorRepository; - - /// - public ModeratorsReadingService( - IForumReadingService forumReadingService, - IModeratorRepository moderatorRepository) - { - this.forumReadingService = forumReadingService; - this.moderatorRepository = moderatorRepository; - } - /// - public async Task> GetModerators(string forumTitle) + public async Task> GetModerators(string forumTitle, CancellationToken cancellationToken) { - var forum = await forumReadingService.GetForum(forumTitle); - return await moderatorRepository.Get(forum.Id); + var forum = await forumReadingService.GetForum(forumTitle, true, cancellationToken); + return await moderatorRepository.Get(forum.Id, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs index ebfdc46b..4d603a55 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.Forum.Dto.Output; @@ -13,6 +14,7 @@ internal interface ITopicCreatingRepository /// Create new topic /// /// DAL model + /// /// DTO model of created topic - Task Create(ForumTopic forumTopic); + Task Create(ForumTopic forumTopic, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingService.cs index da269b76..79901335 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Forum.Dto.Input; using DM.Services.Forum.Dto.Output; @@ -13,6 +14,7 @@ public interface ITopicCreatingService /// Create new topic /// /// Create topic model + /// /// - Task CreateTopic(CreateTopic createTopic); + Task CreateTopic(CreateTopic createTopic, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs index 54578f7e..259b73c4 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,29 +11,19 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Creating; /// -internal class TopicCreatingRepository : ITopicCreatingRepository +internal class TopicCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : ITopicCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public TopicCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(ForumTopic forumTopic) + public async Task Create(ForumTopic forumTopic, CancellationToken cancellationToken) { dbContext.ForumTopics.Add(forumTopic); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.ForumTopics .TagWith("DM.Forum.CreatedTopic") .Where(t => t.ForumTopicId == forumTopic.ForumTopicId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingService.cs index 1bdc04d7..8812eedf 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -14,52 +15,30 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Creating; /// -internal class TopicCreatingService : ITopicCreatingService +internal class TopicCreatingService( + IValidator validator, + IForumReadingService forumReadingService, + IIntentionManager intentionManager, + IIdentityProvider identityProvider, + ITopicFactory topicFactory, + ITopicCreatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer invokedEventProducer) : ITopicCreatingService { - private readonly IValidator validator; - private readonly IForumReadingService forumReadingService; - private readonly IIntentionManager intentionManager; - private readonly ITopicFactory topicFactory; - private readonly ITopicCreatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - private readonly IIdentityProvider identityProvider; - - /// - public TopicCreatingService( - IValidator validator, - IForumReadingService forumReadingService, - IIntentionManager intentionManager, - IIdentityProvider identityProvider, - ITopicFactory topicFactory, - ITopicCreatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.forumReadingService = forumReadingService; - this.intentionManager = intentionManager; - this.topicFactory = topicFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.invokedEventProducer = invokedEventProducer; - this.identityProvider = identityProvider; - } - /// - public async Task CreateTopic(CreateTopic createTopic) + public async Task CreateTopic(CreateTopic createTopic, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createTopic); + await validator.ValidateAndThrowAsync(createTopic, cancellationToken); - var forum = await forumReadingService.GetForum(createTopic.ForumTitle); + var forum = await forumReadingService.GetForum(createTopic.ForumTitle, true, cancellationToken); intentionManager.ThrowIfForbidden(ForumIntention.CreateTopic, forum); var topicToCreate = topicFactory.Create(forum.Id, identityProvider.Current.User.UserId, createTopic); - var topic = await repository.Create(topicToCreate); + var topic = await repository.Create(topicToCreate, cancellationToken); await Task.WhenAll( invokedEventProducer.Send(EventType.NewForumTopic, topic.Id), - unreadCountersRepository.Create(topic.Id, forum.Id, UnreadEntryType.Message)); + unreadCountersRepository.Create(topic.Id, forum.Id, UnreadEntryType.Message, cancellationToken)); return topic; } diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/ITopicDeletingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/ITopicDeletingService.cs index aea89864..e41dae2e 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/ITopicDeletingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/ITopicDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Forum.BusinessProcesses.Topics.Deleting; @@ -12,6 +13,7 @@ public interface ITopicDeletingService /// Remove existing topic /// /// Topic identifier + /// /// - Task DeleteTopic(Guid topicId); + Task DeleteTopic(Guid topicId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/TopicDeletingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/TopicDeletingService.cs index 4a41efa5..3035a83e 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/TopicDeletingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Deleting/TopicDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -14,40 +15,23 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Deleting; /// -internal class TopicDeletingService : ITopicDeletingService +internal class TopicDeletingService( + ITopicReadingService topicReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + ITopicUpdatingRepository repository, + IInvokedEventProducer invokedEventProducer, + IUnreadCountersRepository unreadCountersRepository) : ITopicDeletingService { - private readonly ITopicReadingService topicReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ITopicUpdatingRepository repository; - private readonly IInvokedEventProducer invokedEventProducer; - private readonly IUnreadCountersRepository unreadCountersRepository; - - /// - public TopicDeletingService( - ITopicReadingService topicReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - ITopicUpdatingRepository repository, - IInvokedEventProducer invokedEventProducer, - IUnreadCountersRepository unreadCountersRepository) - { - this.topicReadingService = topicReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.invokedEventProducer = invokedEventProducer; - this.unreadCountersRepository = unreadCountersRepository; - } - /// - public async Task DeleteTopic(Guid topicId) + public async Task DeleteTopic(Guid topicId, CancellationToken cancellationToken) { - var topic = await topicReadingService.GetTopic(topicId); + var topic = await topicReadingService.GetTopic(topicId, cancellationToken); intentionManager.ThrowIfForbidden(ForumIntention.AdministrateTopics, topic.Forum); - await repository.Update(updateBuilderFactory.Create(topicId).Field(t => t.IsRemoved, true)); - await unreadCountersRepository.Delete(topicId, UnreadEntryType.Message); + var updateBuilder = updateBuilderFactory.Create(topicId).Field(t => t.IsRemoved, true); + await repository.Update(updateBuilder, cancellationToken); + await unreadCountersRepository.Delete(topicId, UnreadEntryType.Message, cancellationToken); await invokedEventProducer.Send(EventType.DeletedForumTopic, topicId); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs index 173ab7ab..7bead0be 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Core.Dto.Enums; @@ -16,8 +17,9 @@ internal interface ITopicReadingRepository /// Get number of forum topics /// /// Forum identifier + /// /// - Task Count(Guid forumId); + Task Count(Guid forumId, CancellationToken cancellationToken); /// /// Get list of forum topics @@ -25,8 +27,10 @@ internal interface ITopicReadingRepository /// Forum identifier /// Paging data /// Select attached/not attached topics exclusively + /// /// - Task> Get(Guid forumId, PagingData pagingData, bool attached); + Task> Get(Guid forumId, PagingData pagingData, bool attached, + CancellationToken cancellationToken); /// /// Get topic diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingService.cs index 2171460c..654355b0 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Forum.Dto.Output; @@ -16,20 +17,24 @@ public interface ITopicReadingService /// /// Forum title /// Paging query + /// /// Pair of topics list and paging data - Task<(IEnumerable topics, PagingResult paging)> GetTopicsList(string forumTitle, PagingQuery query); + Task<(IEnumerable topics, PagingResult paging)> GetTopicsList(string forumTitle, PagingQuery query, + CancellationToken cancellationToken); /// /// Get attached topics of certain forum by its title /// /// Forum title + /// /// - Task> GetAttachedTopics(string forumTitle); + Task> GetAttachedTopics(string forumTitle, CancellationToken cancellationToken); /// /// Get topic by id /// /// Topic identifier + /// /// - Task GetTopic(Guid topicId); + Task GetTopic(Guid topicId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs index 3cfb7c02..4deceacc 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -22,12 +23,13 @@ internal class TopicReadingRepository( private static readonly Guid ErrorsForumId = Guid.Parse("00000000-0000-0000-0000-000000000006"); /// - public Task Count(Guid forumId) => dbContext.ForumTopics + public Task Count(Guid forumId, CancellationToken cancellationToken) => dbContext.ForumTopics .TagWith("DM.Forum.TopicsCount") .CountAsync(t => !t.IsRemoved && t.ForumId == forumId && !t.Attached); /// - public async Task> Get(Guid forumId, PagingData pagingData, bool attached) + public async Task> Get(Guid forumId, PagingData pagingData, bool attached, + CancellationToken cancellationToken) { var query = dbContext.ForumTopics .TagWith("DM.Forum.TopicsList") diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs index 509a6a47..d379fcae 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -16,66 +17,50 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Reading; /// -internal class TopicReadingService : ITopicReadingService +internal class TopicReadingService( + IIdentityProvider identityProvider, + IForumReadingService forumReadingService, + IAccessPolicyConverter accessPolicyConverter, + ITopicReadingRepository repository, + IUnreadCountersRepository unreadCountersRepository) : ITopicReadingService { - private readonly IForumReadingService forumReadingService; - private readonly IAccessPolicyConverter accessPolicyConverter; - private readonly ITopicReadingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public TopicReadingService( - IIdentityProvider identityProvider, - IForumReadingService forumReadingService, - IAccessPolicyConverter accessPolicyConverter, - ITopicReadingRepository repository, - IUnreadCountersRepository unreadCountersRepository) - { - this.identityProvider = identityProvider; - this.forumReadingService = forumReadingService; - this.accessPolicyConverter = accessPolicyConverter; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - } - /// public async Task<(IEnumerable topics, PagingResult paging)> GetTopicsList( - string forumTitle, PagingQuery query) + string forumTitle, PagingQuery query, CancellationToken cancellationToken) { - var forum = await forumReadingService.GetForum(forumTitle); + var forum = await forumReadingService.GetForum(forumTitle, true, cancellationToken); - var totalCount = await repository.Count(forum.Id); + var totalCount = await repository.Count(forum.Id, cancellationToken); var identity = identityProvider.Current; var pagingData = new PagingData(query, identity.Settings.Paging.TopicsPerPage, totalCount); - var topics = (await repository.Get(forum.Id, pagingData, false)).ToArray(); + var topics = (await repository.Get(forum.Id, pagingData, false, cancellationToken)).ToArray(); if (identity.User.IsAuthenticated) { await unreadCountersRepository.FillEntityCounters(topics, identity.User.UserId, - t => t.Id, t => t.UnreadCommentsCount); + t => t.Id, t => t.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); } return (topics, pagingData.Result); } /// - public async Task> GetAttachedTopics(string forumTitle) + public async Task> GetAttachedTopics(string forumTitle, CancellationToken cancellationToken) { - var forum = await forumReadingService.GetForum(forumTitle); - var topics = (await repository.Get(forum.Id, null, true)).ToArray(); + var forum = await forumReadingService.GetForum(forumTitle, true, cancellationToken); + var topics = (await repository.Get(forum.Id, null, true, cancellationToken)).ToArray(); var identity = identityProvider.Current; if (identity.User.IsAuthenticated) { await unreadCountersRepository.FillEntityCounters(topics, identity.User.UserId, - t => t.Id, t => t.UnreadCommentsCount); + t => t.Id, t => t.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); } return topics; } /// - public async Task GetTopic(Guid topicId) + public async Task GetTopic(Guid topicId, CancellationToken cancellationToken) { var identity = identityProvider.Current; var accessPolicy = accessPolicyConverter.Convert(identity.User.Role); @@ -87,8 +72,9 @@ public async Task GetTopic(Guid topicId) if (identity.User.IsAuthenticated) { - topic.UnreadCommentsCount = (await unreadCountersRepository.SelectByEntities( - identity.User.UserId, UnreadEntryType.Message, topicId))[topicId]; + var selectByEntities = await unreadCountersRepository.SelectByEntities( + identity.User.UserId, UnreadEntryType.Message, [topicId], cancellationToken); + topic.UnreadCommentsCount = selectByEntities[topicId]; } return topic; diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs index 6e7b057e..8d9b2099 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.DataAccess.RelationalStorage; @@ -14,6 +15,7 @@ internal interface ITopicUpdatingRepository /// Update existing topic /// /// + /// /// DTO model of updated topic - Task Update(IUpdateBuilder updateBuilder); + Task Update(IUpdateBuilder updateBuilder, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingService.cs index cbdbdad1..4d952107 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Forum.Dto.Input; using DM.Services.Forum.Dto.Output; @@ -13,6 +14,7 @@ public interface ITopicUpdatingService /// Update existing topic /// /// Update topic model + /// /// - Task UpdateTopic(UpdateTopic updateTopic); + Task UpdateTopic(UpdateTopic updateTopic, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs index e89bc2ab..685d4f67 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,29 +12,19 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Updating; /// -internal class TopicUpdatingRepository : ITopicUpdatingRepository +internal class TopicUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : ITopicUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public TopicUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder updateBuilder) + public async Task Update(IUpdateBuilder updateBuilder, CancellationToken cancellationToken) { var topicId = updateBuilder.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.ForumTopics .TagWith("DM.Forum.UpdatedTopic") .Where(t => t.ForumTopicId == topicId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingService.cs index c7493620..24754d43 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -16,43 +17,21 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Updating; /// -internal class TopicUpdatingService : ITopicUpdatingService +internal class TopicUpdatingService( + IValidator validator, + ITopicReadingService topicReadingService, + IForumReadingService forumReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + ITopicUpdatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer invokedEventProducer) : ITopicUpdatingService { - private readonly IValidator validator; - private readonly ITopicReadingService topicReadingService; - private readonly IForumReadingService forumReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ITopicUpdatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public TopicUpdatingService( - IValidator validator, - ITopicReadingService topicReadingService, - IForumReadingService forumReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - ITopicUpdatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.topicReadingService = topicReadingService; - this.forumReadingService = forumReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task UpdateTopic(UpdateTopic updateTopic) + public async Task UpdateTopic(UpdateTopic updateTopic, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateTopic); - var oldTopic = await topicReadingService.GetTopic(updateTopic.TopicId); + await validator.ValidateAndThrowAsync(updateTopic, cancellationToken); + var oldTopic = await topicReadingService.GetTopic(updateTopic.TopicId, cancellationToken); intentionManager.ThrowIfForbidden(TopicIntention.Edit, oldTopic); @@ -69,14 +48,15 @@ public async Task UpdateTopic(UpdateTopic updateTopic) if (updateTopic.ForumTitle != default && oldTopic.Forum.Title != updateTopic.ForumTitle) { - var forum = await forumReadingService.GetForum(updateTopic.ForumTitle, false); + var forum = await forumReadingService.GetForum(updateTopic.ForumTitle, false, cancellationToken); intentionManager.ThrowIfForbidden(ForumIntention.CreateTopic, forum); changes.Field(t => t.ForumId, forum.Id); - await unreadCountersRepository.ChangeParent(oldTopic.Forum.Id, UnreadEntryType.Message, forum.Id); + await unreadCountersRepository.ChangeParent( + oldTopic.Forum.Id, UnreadEntryType.Message, forum.Id, cancellationToken); } } - var topic = await repository.Update(changes); + var topic = await repository.Update(changes, cancellationToken); await invokedEventProducer.Send(EventType.ChangedForumTopic, topic.Id); return topic; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingRepository.cs index ea189c33..7216fc81 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,29 +11,19 @@ namespace DM.Services.Gaming.BusinessProcesses.Blacklist.Creating; /// -internal class BlacklistCreatingRepository : IBlacklistCreatingRepository +internal class BlacklistCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IBlacklistCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public BlacklistCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(BlackListLink link) + public async Task Create(BlackListLink link, CancellationToken cancellationToken) { dbContext.BlackListLinks.Add(link); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.BlackListLinks .Where(l => l.BlackListLinkId == link.BlackListLinkId) .Select(l => l.User) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingService.cs index d0c53278..c3c2b9af 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/BlacklistCreatingService.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Dto; @@ -15,43 +16,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Blacklist.Creating; /// -internal class BlacklistCreatingService : IBlacklistCreatingService +internal class BlacklistCreatingService( + IValidator validator, + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + IBlacklistLinkFactory factory, + IUserRepository userRepository, + IBlacklistCreatingRepository repository, + IInvokedEventProducer producer) : IBlacklistCreatingService { - private readonly IValidator validator; - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly IBlacklistLinkFactory factory; - private readonly IUserRepository userRepository; - private readonly IBlacklistCreatingRepository repository; - private readonly IInvokedEventProducer producer; - - /// - public BlacklistCreatingService( - IValidator validator, - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - IBlacklistLinkFactory factory, - IUserRepository userRepository, - IBlacklistCreatingRepository repository, - IInvokedEventProducer producer) - { - this.validator = validator; - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.factory = factory; - this.userRepository = userRepository; - this.repository = repository; - this.producer = producer; - } - /// - public async Task Create(OperateBlacklistLink operateBlacklistLink) + public async Task Create( + OperateBlacklistLink operateBlacklistLink, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(operateBlacklistLink); - var game = await gameReadingService.GetGame(operateBlacklistLink.GameId); + await validator.ValidateAndThrowAsync(operateBlacklistLink, cancellationToken); + var game = await gameReadingService.GetGame(operateBlacklistLink.GameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, game); - var (_, userId) = await userRepository.FindUserId(operateBlacklistLink.Login); + var (_, userId) = await userRepository.FindUserId(operateBlacklistLink.Login, cancellationToken); if (game.BlacklistedUsers.Any(l => l.UserId == userId)) { throw new HttpException(HttpStatusCode.Conflict, "User already blacklisted"); @@ -64,7 +46,7 @@ public async Task Create(OperateBlacklistLink operateBlacklistLink) } var blackListLink = factory.Create(game.Id, userId); - var blacklistedUser = await repository.Create(blackListLink); + var blacklistedUser = await repository.Create(blackListLink, cancellationToken); await producer.Send(EventType.ChangedGame, game.Id); return blacklistedUser; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingRepository.cs index fe8696a4..d9d1cbc9 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.DataAccess.BusinessObjects.Games.Links; @@ -13,6 +14,7 @@ internal interface IBlacklistCreatingRepository /// Save new link /// /// DAL model + /// /// - Task Create(BlackListLink link); + Task Create(BlackListLink link, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingService.cs index 62f51102..a33c5492 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Creating/IBlacklistCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Gaming.Dto.Input; @@ -13,6 +14,7 @@ public interface IBlacklistCreatingService /// Create new blacklist link /// /// DTO for creating + /// /// - Task Create(OperateBlacklistLink operateBlacklistLink); + Task Create(OperateBlacklistLink operateBlacklistLink, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingRepository.cs index d2e529b3..566c909c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Games.Links; @@ -18,7 +19,7 @@ public BlacklistDeletingRepository( } /// - public Task Delete(IUpdateBuilder updateBuilder) + public Task Delete(IUpdateBuilder updateBuilder, CancellationToken cancellationToken) { updateBuilder.AttachTo(dbContext); return dbContext.SaveChangesAsync(); diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingService.cs index ceaa43d8..68be6657 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/BlacklistDeletingService.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Dto.Enums; @@ -16,43 +17,23 @@ namespace DM.Services.Gaming.BusinessProcesses.Blacklist.Deleting; /// -internal class BlacklistDeletingService : IBlacklistDeletingService +internal class BlacklistDeletingService( + IValidator validator, + IUserRepository userRepository, + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IBlacklistDeletingRepository repository, + IInvokedEventProducer invokedEventProducer) : IBlacklistDeletingService { - private readonly IValidator validator; - private readonly IUserRepository userRepository; - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IBlacklistDeletingRepository repository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public BlacklistDeletingService( - IValidator validator, - IUserRepository userRepository, - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IBlacklistDeletingRepository repository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.userRepository = userRepository; - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task Delete(OperateBlacklistLink operateBlacklistLink) + public async Task Delete(OperateBlacklistLink operateBlacklistLink, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(operateBlacklistLink); - var game = await gameReadingService.GetGame(operateBlacklistLink.GameId); + await validator.ValidateAndThrowAsync(operateBlacklistLink, cancellationToken); + var game = await gameReadingService.GetGame(operateBlacklistLink.GameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, game); - var (_, userId) = await userRepository.FindUserId(operateBlacklistLink.Login); + var (_, userId) = await userRepository.FindUserId(operateBlacklistLink.Login, cancellationToken); var blacklistedLink = game.BlacklistedUsers.FirstOrDefault(u => u.UserId == userId); if (blacklistedLink == default) { @@ -60,7 +41,7 @@ public async Task Delete(OperateBlacklistLink operateBlacklistLink) } var updateBuilder = updateBuilderFactory.Create(blacklistedLink.LinkId).Delete(); - await repository.Delete(updateBuilder); + await repository.Delete(updateBuilder, cancellationToken); await invokedEventProducer.Send(EventType.ChangedGame, game.Id); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingRepository.cs index 55ac4985..36297434 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Games.Links; using DM.Services.DataAccess.RelationalStorage; @@ -13,6 +14,7 @@ internal interface IBlacklistDeletingRepository /// Delete existing blacklist link /// /// + /// /// - Task Delete(IUpdateBuilder updateBuilder); + Task Delete(IUpdateBuilder updateBuilder, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingService.cs index ef28f279..5cbc2316 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Deleting/IBlacklistDeletingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; @@ -12,6 +13,7 @@ public interface IBlacklistDeletingService /// Delete existing blacklist link /// /// DTO model + /// /// - Task Delete(OperateBlacklistLink operateBlacklistLink); + Task Delete(OperateBlacklistLink operateBlacklistLink, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingRepository.cs index b289661e..2201b8b9 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -16,9 +17,10 @@ internal class BlacklistReadingRepository( IMapper mapper) : IBlacklistReadingRepository { /// - public async Task> Get(Guid gameId) => await dbContext.BlackListLinks - .Where(l => l.GameId == gameId) - .Select(l => l.User) - .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); + public async Task> Get(Guid gameId, CancellationToken cancellationToken) => + await dbContext.BlackListLinks + .Where(l => l.GameId == gameId) + .Select(l => l.User) + .ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingService.cs index 3c17a41a..ae7514de 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/BlacklistReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Dto; @@ -9,30 +10,16 @@ namespace DM.Services.Gaming.BusinessProcesses.Blacklist.Reading; /// -internal class BlacklistReadingService : IBlacklistReadingService +internal class BlacklistReadingService( + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + IBlacklistReadingRepository repository) : IBlacklistReadingService { - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly IBlacklistReadingRepository repository; - - /// - /// - /// - public BlacklistReadingService( - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - IBlacklistReadingRepository repository) - { - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.repository = repository; - } - /// - public async Task> Get(Guid gameId) + public async Task> Get(Guid gameId, CancellationToken cancellationToken) { - var game = await gameReadingService.GetGame(gameId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, game); - return await repository.Get(gameId); + return await repository.Get(gameId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingRepository.cs index 5e4f4bb3..5c5fa0b3 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,6 +15,7 @@ internal interface IBlacklistReadingRepository /// Get blacklisted users /// /// Game identifier + /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingService.cs index 2c43cae4..00c418d0 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Blacklist/Reading/IBlacklistReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,6 +15,7 @@ public interface IBlacklistReadingService /// Get list of undesired users /// /// Game identifier + /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingRepository.cs index 30833570..83c44fac 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,29 +13,20 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Creating; /// -internal class CharacterCreatingRepository : ICharacterCreatingRepository +internal class CharacterCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICharacterCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CharacterCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbCharacter character, IEnumerable attributes) + public async Task Create(DbCharacter character, IEnumerable attributes, + CancellationToken cancellationToken) { dbContext.Characters.Add(character); dbContext.CharacterAttributes.AddRange(attributes); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Characters .Where(c => c.CharacterId == character.CharacterId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingService.cs index 30c70d6c..a8ed5fe5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/CharacterCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -15,43 +16,21 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Creating; /// -internal class CharacterCreatingService : ICharacterCreatingService +internal class CharacterCreatingService( + IValidator validator, + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + ICharacterFactory factory, + ICharacterCreatingRepository creatingRepository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : ICharacterCreatingService { - private readonly IValidator validator; - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly ICharacterFactory factory; - private readonly ICharacterCreatingRepository creatingRepository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public CharacterCreatingService( - IValidator validator, - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - ICharacterFactory factory, - ICharacterCreatingRepository creatingRepository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.factory = factory; - this.creatingRepository = creatingRepository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateCharacter createCharacter) + public async Task Create(CreateCharacter createCharacter, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createCharacter); - var game = await gameReadingService.GetGame(createCharacter.GameId); + await validator.ValidateAndThrowAsync(createCharacter, cancellationToken); + var game = await gameReadingService.GetGame(createCharacter.GameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.CreateCharacter, game); var currentUserId = identityProvider.Current.User.UserId; @@ -66,9 +45,9 @@ public async Task Create(CreateCharacter createCharacter) createCharacter.IsNpc = createCharacter.IsNpc && gameParticipation.HasFlag(GameParticipation.Authority); var (character, attributes) = factory.Create(createCharacter, currentUserId, initialStatus); - var createdCharacter = await creatingRepository.Create(character, attributes); + var createdCharacter = await creatingRepository.Create(character, attributes, cancellationToken); - await unreadCountersRepository.Increment(createCharacter.GameId, UnreadEntryType.Character); + await unreadCountersRepository.Increment(createCharacter.GameId, UnreadEntryType.Character, cancellationToken); await producer.Send(EventType.NewCharacter, createdCharacter.Id); return createdCharacter; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingRepository.cs index 9ea6a503..7a4b2dcc 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; using CharacterAttribute = DM.Services.DataAccess.BusinessObjects.Games.Characters.Attributes.CharacterAttribute; @@ -16,6 +17,8 @@ internal interface ICharacterCreatingRepository /// /// Character DAL /// + /// /// - Task Create(DbCharacter character, IEnumerable attributes); + Task Create(DbCharacter character, IEnumerable attributes, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingService.cs index 590dbab8..b7e8d71e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Creating/ICharacterCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface ICharacterCreatingService /// Create new character /// /// Create character DTO model + /// /// - Task Create(CreateCharacter createCharacter); + Task Create(CreateCharacter createCharacter, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/CharacterDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/CharacterDeletingService.cs index 4d9e479f..51ca99a1 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/CharacterDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/CharacterDeletingService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -15,42 +16,27 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Deleting; /// -internal class CharacterDeletingService : ICharacterDeletingService +internal class CharacterDeletingService( + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + ICharacterUpdatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer) : ICharacterDeletingService { - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICharacterUpdatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - - /// - public CharacterDeletingService( - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - ICharacterUpdatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer) - { - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - } - /// - public async Task Delete(Guid characterId) + public async Task Delete(Guid characterId, CancellationToken cancellationToken) { - var character = await repository.Get(characterId); + var character = await repository.Get(characterId, cancellationToken); intentionManager.ThrowIfForbidden(CharacterIntention.Delete, character); var updateCharacter = updateBuilderFactory.Create(characterId); updateCharacter.Field(c => c.IsRemoved, true); - var updateAttributes = (await repository.GetAttributeIds(characterId)).Keys + var updateAttributes = (await repository.GetAttributeIds(characterId, cancellationToken)).Keys .Select(id => updateBuilderFactory.Create(id).Delete()); - await repository.Update(updateCharacter, updateAttributes); - await unreadCountersRepository.Decrement(character.GameId, UnreadEntryType.Character, character.CreateDate); + await repository.Update(updateCharacter, updateAttributes, cancellationToken); + await unreadCountersRepository.Decrement( + character.GameId, UnreadEntryType.Character, character.CreateDate, cancellationToken); await producer.Send(EventType.DeletedCharacter, characterId); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/ICharacterDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/ICharacterDeletingService.cs index 7674c287..437035c6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/ICharacterDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Deleting/ICharacterDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Characters.Deleting; @@ -12,6 +13,7 @@ public interface ICharacterDeletingService /// Delete existing character /// /// Character identifier + /// /// - Task Delete(Guid characterId); + Task Delete(Guid characterId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingRepository.cs index f22b7eef..669f76b6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,36 +12,22 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Reading; /// -internal class CharacterReadingRepository : ICharacterReadingRepository +internal class CharacterReadingRepository( + DmDbContext dbContext, + IMapper mapper) : ICharacterReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CharacterReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task> GetCharacters(Guid gameId) - { - return await dbContext.Characters + public async Task> GetCharacters(Guid gameId, CancellationToken cancellationToken) => + await dbContext.Characters .Where(c => !c.IsRemoved && c.GameId == gameId) .OrderByDescending(c => c.CreateDate) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public async Task FindCharacter(Guid characterId) - { - return await dbContext.Characters + public async Task FindCharacter(Guid characterId, CancellationToken cancellationToken) => + await dbContext.Characters .Where(c => !c.IsRemoved && c.CharacterId == characterId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingService.cs index 08f09e9d..573ac5cd 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/CharacterReadingService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -14,57 +15,41 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Reading; /// -internal class CharacterReadingService : ICharacterReadingService +internal class CharacterReadingService( + IGameReadingService gameReadingService, + ICharacterReadingRepository readingRepository, + ICharacterAttributeValueFiller attributeValueFiller, + IUnreadCountersRepository unreadCountersRepository, + IIdentityProvider identityProvider) : ICharacterReadingService { - private readonly IGameReadingService gameReadingService; - private readonly ICharacterReadingRepository readingRepository; - private readonly ICharacterAttributeValueFiller attributeValueFiller; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public CharacterReadingService( - IGameReadingService gameReadingService, - ICharacterReadingRepository readingRepository, - ICharacterAttributeValueFiller attributeValueFiller, - IUnreadCountersRepository unreadCountersRepository, - IIdentityProvider identityProvider) - { - this.gameReadingService = gameReadingService; - this.readingRepository = readingRepository; - this.attributeValueFiller = attributeValueFiller; - this.unreadCountersRepository = unreadCountersRepository; - this.identityProvider = identityProvider; - } - /// - public async Task> GetCharacters(Guid gameId) + public async Task> GetCharacters(Guid gameId, CancellationToken cancellationToken) { - var game = await gameReadingService.GetGame(gameId); - var characters = (await readingRepository.GetCharacters(gameId)).ToArray(); - await attributeValueFiller.Fill(characters, game.AttributeSchemaId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); + var characters = (await readingRepository.GetCharacters(gameId, cancellationToken)).ToArray(); + await attributeValueFiller.Fill(characters, game.AttributeSchemaId, cancellationToken); return characters; } /// - public async Task GetCharacter(Guid characterId) + public async Task GetCharacter(Guid characterId, CancellationToken cancellationToken) { - var character = await readingRepository.FindCharacter(characterId); + var character = await readingRepository.FindCharacter(characterId, cancellationToken); if (character == null) { throw new HttpException(HttpStatusCode.Gone, "Character not found"); } - var game = await gameReadingService.GetGame(character.GameId); - await attributeValueFiller.Fill(new[] {character}, game.AttributeSchemaId); + var game = await gameReadingService.GetGame(character.GameId, cancellationToken); + await attributeValueFiller.Fill(new[] {character}, game.AttributeSchemaId, cancellationToken); return character; } /// - public async Task MarkAsRead(Guid gameId) + public async Task MarkAsRead(Guid gameId, CancellationToken cancellationToken) { - await gameReadingService.GetGame(gameId); + await gameReadingService.GetGame(gameId, cancellationToken); await unreadCountersRepository.Flush(identityProvider.Current.User.UserId, - UnreadEntryType.Character, gameId); + UnreadEntryType.Character, gameId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingRepository.cs index 55a8ae3b..3a4b5945 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -14,13 +15,15 @@ internal interface ICharacterReadingRepository /// Get all game characters /// /// Game identifier + /// /// - Task> GetCharacters(Guid gameId); + Task> GetCharacters(Guid gameId, CancellationToken cancellationToken); /// /// Get single character /// /// Character identifier + /// /// - Task FindCharacter(Guid characterId); + Task FindCharacter(Guid characterId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingService.cs index 0b647843..5595d772 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Reading/ICharacterReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -14,20 +15,23 @@ public interface ICharacterReadingService /// Get all game characters /// /// Game identifier + /// /// - Task> GetCharacters(Guid gameId); + Task> GetCharacters(Guid gameId, CancellationToken cancellationToken); /// /// Get single character /// /// Character identifier + /// /// - Task GetCharacter(Guid characterId); + Task GetCharacter(Guid characterId, CancellationToken cancellationToken); /// /// Mark all characters in game as read /// /// Game identifier + /// /// - Task MarkAsRead(Guid gameId); + Task MarkAsRead(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterAttributeValueFiller.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterAttributeValueFiller.cs index d51209d1..5883076e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterAttributeValueFiller.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterAttributeValueFiller.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.BusinessProcesses.Schemas.Reading; using DM.Services.Gaming.Dto.Output; @@ -9,22 +10,12 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Shared; /// -internal class CharacterAttributeValueFiller : ICharacterAttributeValueFiller +internal class CharacterAttributeValueFiller( + ISchemaReadingService schemaReadingService, + IAttributeValueValidator attributeValueValidator) : ICharacterAttributeValueFiller { - private readonly ISchemaReadingService schemaReadingService; - private readonly IAttributeValueValidator attributeValueValidator; - - /// - public CharacterAttributeValueFiller( - ISchemaReadingService schemaReadingService, - IAttributeValueValidator attributeValueValidator) - { - this.schemaReadingService = schemaReadingService; - this.attributeValueValidator = attributeValueValidator; - } - /// - public async Task Fill(IEnumerable characters, Guid? schemaId) + public async Task Fill(IEnumerable characters, Guid? schemaId, CancellationToken cancellationToken) { if (!schemaId.HasValue) { @@ -36,7 +27,7 @@ public async Task Fill(IEnumerable characters, Guid? schemaId) return; } - var schema = await schemaReadingService.Get(schemaId.Value); + var schema = await schemaReadingService.Get(schemaId.Value, cancellationToken); foreach (var character in characters) { var attributeIndex = character.Attributes.ToDictionary(a => a.Id); diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterValidationRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterValidationRepository.cs index ad784b7e..a799426d 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterValidationRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/CharacterValidationRepository.cs @@ -14,21 +14,11 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Shared; /// -internal class CharacterValidationRepository : MongoCollectionRepository, ICharacterValidationRepository +internal class CharacterValidationRepository( + IMapper mapper, + DmDbContext dbContext, + DmMongoClient client) : MongoCollectionRepository(client), ICharacterValidationRepository { - private readonly IMapper mapper; - private readonly DmDbContext dbContext; - - /// - public CharacterValidationRepository( - IMapper mapper, - DmDbContext dbContext, - DmMongoClient client) : base(client) - { - this.mapper = mapper; - this.dbContext = dbContext; - } - /// public Task GameRequiresAttributes(CreateCharacter createCharacter, CancellationToken cancellationToken) => dbContext.Games @@ -37,25 +27,25 @@ public Task GameRequiresAttributes(CreateCharacter createCharacter, Cancel .FirstAsync(cancellationToken); /// - public async Task GetGameSchema(Guid gameId) + public async Task GetGameSchema(Guid gameId, CancellationToken cancellationToken) { var schemaId = await dbContext.Games .Where(g => g.GameId == gameId) .Select(g => g.AttributeSchemaId) - .FirstAsync(); + .FirstAsync(cancellationToken); var schema = await Collection .Find(Filter.Eq(s => s.Id, schemaId.Value)) - .FirstAsync(); + .FirstAsync(cancellationToken); return mapper.Map(schema); } /// - public async Task GetCharacterSchema(Guid characterId) + public async Task GetCharacterSchema(Guid characterId, CancellationToken cancellationToken) { var gameId = await dbContext.Characters .Where(c => c.CharacterId == characterId) .Select(c => c.GameId) - .FirstAsync(); - return await GetGameSchema(gameId); + .FirstAsync(cancellationToken); + return await GetGameSchema(gameId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterAttributeValueFiller.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterAttributeValueFiller.cs index 1551fec7..2385444b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterAttributeValueFiller.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterAttributeValueFiller.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -15,6 +16,7 @@ internal interface ICharacterAttributeValueFiller /// /// /// + /// /// - Task Fill(IEnumerable characters, Guid? schemaId); + Task Fill(IEnumerable characters, Guid? schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterValidationRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterValidationRepository.cs index 24762408..5be780aa 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterValidationRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Shared/ICharacterValidationRepository.cs @@ -23,13 +23,15 @@ internal interface ICharacterValidationRepository /// Get schema for game /// /// + /// /// - Task GetGameSchema(Guid gameId); + Task GetGameSchema(Guid gameId, CancellationToken cancellationToken); /// /// Get game schema for character /// /// + /// /// - Task GetCharacterSchema(Guid characterId); + Task GetCharacterSchema(Guid characterId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingRepository.cs index ab504484..e68ffd76 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -14,33 +15,21 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Updating; /// -internal class CharacterUpdatingRepository : ICharacterUpdatingRepository +internal class CharacterUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICharacterUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CharacterUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Get(Guid characterId) - { - return dbContext.Characters + public Task Get(Guid characterId, CancellationToken cancellationToken) => + dbContext.Characters .Where(c => c.CharacterId == characterId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); - } + .FirstAsync(cancellationToken); /// public async Task Update( IUpdateBuilder updateCharacter, - IEnumerable> attributeChanges) + IEnumerable> attributeChanges, CancellationToken cancellationToken) { var characterId = updateCharacter.AttachTo(dbContext); foreach (var attributeChange in attributeChanges) @@ -48,18 +37,19 @@ public async Task Update( attributeChange.AttachTo(dbContext); } - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Characters .Where(c => c.CharacterId == characterId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } /// - public async Task> GetAttributeIds(Guid characterId) - { - return await dbContext.CharacterAttributes + public async Task> GetAttributeIds(Guid characterId, CancellationToken cancellationToken) => + await dbContext.CharacterAttributes .Where(c => c.CharacterId == characterId) - .ToDictionaryAsync(a => a.AttributeId, a => a.CharacterAttributeId); - } + .ToDictionaryAsync( + a => a.AttributeId, + a => a.CharacterAttributeId, + cancellationToken: cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingService.cs index 0311194b..f44e938c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/CharacterUpdatingService.cs @@ -1,5 +1,7 @@ +using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Dto.Enums; @@ -16,40 +18,20 @@ namespace DM.Services.Gaming.BusinessProcesses.Characters.Updating; /// -internal class CharacterUpdatingService : ICharacterUpdatingService +internal class CharacterUpdatingService( + IValidator validator, + IIntentionManager intentionManager, + IDateTimeProvider dateTimeProvider, + IUpdateBuilderFactory updateBuilderFactory, + ICharacterUpdatingRepository repository, + ICharacterIntentionConverter intentionConverter, + IInvokedEventProducer producer) : ICharacterUpdatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICharacterUpdatingRepository repository; - private readonly ICharacterIntentionConverter intentionConverter; - private readonly IInvokedEventProducer producer; - - /// - public CharacterUpdatingService( - IValidator validator, - IIntentionManager intentionManager, - IDateTimeProvider dateTimeProvider, - IUpdateBuilderFactory updateBuilderFactory, - ICharacterUpdatingRepository repository, - ICharacterIntentionConverter intentionConverter, - IInvokedEventProducer producer) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.dateTimeProvider = dateTimeProvider; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.intentionConverter = intentionConverter; - this.producer = producer; - } - /// - public async Task Update(UpdateCharacter updateCharacter) + public async Task Update(UpdateCharacter updateCharacter, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateCharacter); - var characterToUpdate = await repository.Get(updateCharacter.CharacterId); + await validator.ValidateAndThrowAsync(updateCharacter, cancellationToken); + var characterToUpdate = await repository.Get(updateCharacter.CharacterId, cancellationToken); intentionManager.ThrowIfForbidden(CharacterIntention.Edit, characterToUpdate); @@ -63,10 +45,11 @@ public async Task Update(UpdateCharacter updateCharacter) .MaybeField(c => c.Skills, updateCharacter.Skills) .MaybeField(c => c.Inventory, updateCharacter.Inventory); - var attributeChanges = new IUpdateBuilder[0]; + var attributeChanges = Array.Empty>(); if (updateCharacter.Attributes != null && updateCharacter.Attributes.Any()) { - var attributeIdsIndex = await repository.GetAttributeIds(updateCharacter.CharacterId); + var attributeIdsIndex = await repository.GetAttributeIds( + updateCharacter.CharacterId, cancellationToken); attributeChanges = updateCharacter.Attributes .Where(a => attributeIdsIndex.ContainsKey(a.Id)) .Select(a => updateBuilderFactory.Create(attributeIdsIndex[a.Id]) @@ -101,7 +84,7 @@ public async Task Update(UpdateCharacter updateCharacter) changes.Field(c => c.LastUpdateDate, dateTimeProvider.Now); } - var character = await repository.Update(changes, attributeChanges); + var character = await repository.Update(changes, attributeChanges, cancellationToken); await producer.Send(invokedEvents, updateCharacter.CharacterId); return character; } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingRepository.cs index a0615ba4..6de87b18 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Internal; @@ -18,22 +19,25 @@ internal interface ICharacterUpdatingRepository /// Get character for updating /// /// Character identifier + /// /// - Task Get(Guid characterId); + Task Get(Guid characterId, CancellationToken cancellationToken); /// /// Update character /// /// Update builder /// + /// /// Task Update(IUpdateBuilder updateCharacter, - IEnumerable> attributeChanges); + IEnumerable> attributeChanges, CancellationToken cancellationToken); /// /// Get list of character attribute value ids /// /// Character identifier + /// /// - Task> GetAttributeIds(Guid characterId); + Task> GetAttributeIds(Guid characterId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingService.cs index d6b1e296..c2fad3df 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Characters/Updating/ICharacterUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface ICharacterUpdatingService /// Update existing character /// /// Update character model + /// /// - Task Update(UpdateCharacter updateCharacter); + Task Update(UpdateCharacter updateCharacter, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/CharacterClaimApprove.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/CharacterClaimApprove.cs index 531058d7..dc8613ec 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/CharacterClaimApprove.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/CharacterClaimApprove.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Exceptions; using DM.Services.Gaming.Dto.Internal; @@ -8,21 +9,13 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Creating; /// -internal class CharacterClaimApprove : ICharacterClaimApprove +internal class CharacterClaimApprove( + IRoomClaimsCreatingRepository repository) : ICharacterClaimApprove { - private readonly IRoomClaimsCreatingRepository repository; - - /// - public CharacterClaimApprove( - IRoomClaimsCreatingRepository repository) - { - this.repository = repository; - } - /// - public async Task GetParticipantId(Guid characterId, RoomToUpdate room) + public async Task GetParticipantId(Guid characterId, RoomToUpdate room, CancellationToken cancellationToken) { - var gameId = await repository.FindCharacterGameId(characterId); + var gameId = await repository.FindCharacterGameId(characterId, cancellationToken); if (!gameId.HasValue || room.Game.Id != gameId) { throw new HttpBadRequestException(new Dictionary diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ICharacterClaimApprove.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ICharacterClaimApprove.cs index fafcab2d..6789ab8f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ICharacterClaimApprove.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ICharacterClaimApprove.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Internal; @@ -14,6 +15,7 @@ internal interface ICharacterClaimApprove /// /// Character identifier /// Room to update + /// /// - Task GetParticipantId(Guid characterId, RoomToUpdate room); + Task GetParticipantId(Guid characterId, RoomToUpdate room, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IReaderClaimApprove.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IReaderClaimApprove.cs index 4648ddb0..0410e889 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IReaderClaimApprove.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IReaderClaimApprove.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Internal; @@ -14,6 +15,7 @@ internal interface IReaderClaimApprove /// /// Reader login /// Room to update + /// /// - Task GetParticipantId(string readerLogin, RoomToUpdate room); + Task GetParticipantId(string readerLogin, RoomToUpdate room, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingRepository.cs index 4833bf0c..a3a5f1d5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using RoomClaim = DM.Services.DataAccess.BusinessObjects.Games.Links.RoomClaim; @@ -13,21 +14,24 @@ internal interface IRoomClaimsCreatingRepository /// Save room claim /// /// DAL model + /// /// - Task Create(RoomClaim claim); + Task Create(RoomClaim claim, CancellationToken cancellationToken); /// /// Find reader in game /// /// Game identifier /// Reader login + /// /// - Task FindReaderId(Guid gameId, string readerLogin); + Task FindReaderId(Guid gameId, string readerLogin, CancellationToken cancellationToken); /// /// Get game identifier for character /// /// Character identifier + /// /// - Task FindCharacterGameId(Guid characterId); + Task FindCharacterGameId(Guid characterId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingService.cs index 8c9f9f28..cd570f64 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/IRoomClaimsCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IRoomClaimsCreatingService /// Create new room claims /// /// DTO model + /// /// - Task Create(CreateRoomClaim createRoomClaim); + Task Create(CreateRoomClaim createRoomClaim, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ReaderClaimApprove.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ReaderClaimApprove.cs index 19896018..cfb626ea 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ReaderClaimApprove.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/ReaderClaimApprove.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Exceptions; using DM.Services.Gaming.Dto.Internal; @@ -8,21 +9,13 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Creating; /// -internal class ReaderClaimApprove : IReaderClaimApprove +internal class ReaderClaimApprove( + IRoomClaimsCreatingRepository creatingRepository) : IReaderClaimApprove { - private readonly IRoomClaimsCreatingRepository creatingRepository; - - /// - public ReaderClaimApprove( - IRoomClaimsCreatingRepository creatingRepository) - { - this.creatingRepository = creatingRepository; - } - /// - public async Task GetParticipantId(string readerLogin, RoomToUpdate room) + public async Task GetParticipantId(string readerLogin, RoomToUpdate room, CancellationToken cancellationToken) { - var readerId = await creatingRepository.FindReaderId(room.Game.Id, readerLogin); + var readerId = await creatingRepository.FindReaderId(room.Game.Id, readerLogin, cancellationToken); if (!readerId.HasValue) { throw new HttpBadRequestException(new Dictionary diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingRepository.cs index 35ce74cc..c463243f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,48 +11,38 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Creating; /// -internal class RoomClaimsCreatingRepository : IRoomClaimsCreatingRepository +internal class RoomClaimsCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomClaimsCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomClaimsCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(RoomClaim claim) + public async Task Create(RoomClaim claim, CancellationToken cancellationToken) { dbContext.RoomClaims.Add(claim); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.RoomClaims .Where(l => l.RoomClaimId == claim.RoomClaimId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } /// - public async Task FindReaderId(Guid gameId, string readerLogin) + public async Task FindReaderId(Guid gameId, string readerLogin, CancellationToken cancellationToken) { var readerWrapper = await dbContext.Readers .Where(r => r.User.Login == readerLogin && r.GameId == gameId) .Select(r => new {r.ReaderId}) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return readerWrapper?.ReaderId; } /// - public async Task FindCharacterGameId(Guid characterId) + public async Task FindCharacterGameId(Guid characterId, CancellationToken cancellationToken) { var gameWrapper = await dbContext.Characters .Where(c => c.CharacterId == characterId && !c.IsRemoved) .Select(c => new {c.GameId}) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return gameWrapper?.GameId; } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingService.cs index 280bfaa6..8d3ec4b3 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Creating/RoomClaimsCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -12,54 +13,31 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Creating; /// -internal class RoomClaimsCreatingService : IRoomClaimsCreatingService +internal class RoomClaimsCreatingService( + IValidator validator, + IRoomUpdatingRepository updatingRepository, + IIntentionManager intentionManager, + IRoomClaimFactory factory, + ICharacterClaimApprove characterClaimApprove, + IReaderClaimApprove readerClaimApprove, + IRoomClaimsCreatingRepository repository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IRoomClaimsCreatingService { - private readonly IValidator validator; - private readonly IRoomUpdatingRepository updatingRepository; - private readonly IIntentionManager intentionManager; - private readonly IRoomClaimFactory factory; - private readonly ICharacterClaimApprove characterClaimApprove; - private readonly IReaderClaimApprove readerClaimApprove; - private readonly IRoomClaimsCreatingRepository repository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public RoomClaimsCreatingService( - IValidator validator, - IRoomUpdatingRepository updatingRepository, - IIntentionManager intentionManager, - IRoomClaimFactory factory, - ICharacterClaimApprove characterClaimApprove, - IReaderClaimApprove readerClaimApprove, - IRoomClaimsCreatingRepository repository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.updatingRepository = updatingRepository; - this.intentionManager = intentionManager; - this.factory = factory; - this.characterClaimApprove = characterClaimApprove; - this.readerClaimApprove = readerClaimApprove; - this.repository = repository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateRoomClaim createRoomClaim) + public async Task Create(CreateRoomClaim createRoomClaim, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createRoomClaim); - var room = await updatingRepository.GetRoom(createRoomClaim.RoomId, identityProvider.Current.User.UserId); + await validator.ValidateAndThrowAsync(createRoomClaim, cancellationToken); + var room = await updatingRepository.GetRoom( + createRoomClaim.RoomId, identityProvider.Current.User.UserId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, room.Game); var participantId = createRoomClaim.CharacterId.HasValue - ? await characterClaimApprove.GetParticipantId(createRoomClaim.CharacterId.Value, room) - : await readerClaimApprove.GetParticipantId(createRoomClaim.ReaderLogin.Trim(), room); - ; + ? await characterClaimApprove.GetParticipantId(createRoomClaim.CharacterId.Value, room, cancellationToken) + : await readerClaimApprove.GetParticipantId(createRoomClaim.ReaderLogin.Trim(), room, cancellationToken); + var link = factory.Create(createRoomClaim, participantId); - var result = await repository.Create(link); + var result = await repository.Create(link, cancellationToken); await producer.Send(EventType.ChangedRoom, link.RoomId); return result; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingRepository.cs index c1413450..d9690b39 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Games.Links; using DM.Services.DataAccess.RelationalStorage; @@ -13,6 +14,7 @@ internal interface IRoomClaimsDeletingRepository /// Delete existing link /// /// + /// /// - Task Delete(IUpdateBuilder deleteLink); + Task Delete(IUpdateBuilder deleteLink, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingService.cs index 91e3533f..2ca2e48a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/IRoomClaimsDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Claims.Deleting; @@ -12,6 +13,7 @@ public interface IRoomClaimsDeletingService /// Delete existing claim /// /// Claim identifier + /// /// - Task Delete(Guid claimId); + Task Delete(Guid claimId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingRepository.cs index b8b25edc..3f4ab2a1 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Games.Links; @@ -6,21 +7,13 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Deleting; /// -internal class RoomClaimsDeletingRepository : IRoomClaimsDeletingRepository +internal class RoomClaimsDeletingRepository( + DmDbContext dbContext) : IRoomClaimsDeletingRepository { - private readonly DmDbContext dbContext; - - /// - public RoomClaimsDeletingRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public Task Delete(IUpdateBuilder deleteLink) + public Task Delete(IUpdateBuilder deleteLink, CancellationToken cancellationToken) { deleteLink.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingService.cs index 4e72dd09..2f7ea16d 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Deleting/RoomClaimsDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -13,45 +14,25 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Deleting; /// -internal class RoomClaimsDeletingService : IRoomClaimsDeletingService +internal class RoomClaimsDeletingService( + IRoomClaimsDeletingRepository repository, + IRoomClaimsReadingRepository readingRepository, + IRoomUpdatingRepository roomUpdatingRepository, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IRoomClaimsDeletingService { - private readonly IRoomClaimsDeletingRepository repository; - private readonly IRoomClaimsReadingRepository readingRepository; - private readonly IRoomUpdatingRepository roomUpdatingRepository; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public RoomClaimsDeletingService( - IRoomClaimsDeletingRepository repository, - IRoomClaimsReadingRepository readingRepository, - IRoomUpdatingRepository roomUpdatingRepository, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.repository = repository; - this.readingRepository = readingRepository; - this.roomUpdatingRepository = roomUpdatingRepository; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Delete(Guid claimId) + public async Task Delete(Guid claimId, CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var oldClaim = await readingRepository.GetClaim(claimId, currentUserId); - var room = await roomUpdatingRepository.GetRoom(oldClaim.RoomId, currentUserId); + var oldClaim = await readingRepository.GetClaim(claimId, currentUserId, cancellationToken); + var room = await roomUpdatingRepository.GetRoom(oldClaim.RoomId, currentUserId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, room.Game); var updateBuilder = updateBuilderFactory.Create(claimId).Delete(); - await repository.Delete(updateBuilder); + await repository.Delete(updateBuilder, cancellationToken); await producer.Send(EventType.ChangedRoom, room.Id); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingRepository.cs index 3c71736d..52147f31 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -15,22 +16,25 @@ internal interface IRoomClaimsReadingRepository /// /// Game identifier /// User identifier + /// /// - Task> GetGameClaims(Guid gameId, Guid userId); + Task> GetGameClaims(Guid gameId, Guid userId, CancellationToken cancellationToken); /// /// Get all room claims /// /// Room identifier /// User identifier + /// /// - Task> GetRoomClaims(Guid roomId, Guid userId); + Task> GetRoomClaims(Guid roomId, Guid userId, CancellationToken cancellationToken); /// /// Get existing room claim /// /// Claim identifier /// User identifier + /// /// - Task GetClaim(Guid claimId, Guid userId); + Task GetClaim(Guid claimId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingService.cs index 06b39e9d..aee65dfd 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/IRoomClaimsReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -14,20 +15,23 @@ public interface IRoomClaimsReadingService /// Get all game claims /// /// Game identifier + /// /// - Task> GetGameClaims(Guid gameId); - + Task> GetGameClaims(Guid gameId, CancellationToken cancellationToken); + /// /// Get all room claims /// /// Room identifier + /// /// - Task> GetRoomClaims(Guid roomId); + Task> GetRoomClaims(Guid roomId, CancellationToken cancellationToken); /// /// Get existing claim /// /// Claim identifier + /// /// - Task GetClaim(Guid claimId); + Task GetClaim(Guid claimId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingRepository.cs index 0d4cc65c..222e2196 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,50 +13,34 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Reading; /// -internal class RoomClaimsReadingRepository : IRoomClaimsReadingRepository +internal class RoomClaimsReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomClaimsReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomClaimsReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task> GetGameClaims(Guid gameId, Guid userId) - { - return await dbContext.Rooms - .Where(AccessibilityFilters.RoomAvailable(userId)) - .Where(r => r.GameId == gameId) - .SelectMany(r => r.RoomClaims) - .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + public async Task> GetGameClaims( + Guid gameId, Guid userId, CancellationToken cancellationToken) => await dbContext.Rooms + .Where(AccessibilityFilters.RoomAvailable(userId)) + .Where(r => r.GameId == gameId) + .SelectMany(r => r.RoomClaims) + .ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken); /// - public async Task> GetRoomClaims(Guid roomId, Guid userId) - { - return await dbContext.Rooms - .Where(r => r.RoomId == roomId) - .Where(AccessibilityFilters.RoomAvailable(userId)) - .Select(r => r.RoomClaims) - .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + public async Task> GetRoomClaims( + Guid roomId, Guid userId, CancellationToken cancellationToken) => await dbContext.Rooms + .Where(r => r.RoomId == roomId) + .Where(AccessibilityFilters.RoomAvailable(userId)) + .Select(r => r.RoomClaims) + .ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken); /// - public async Task GetClaim(Guid claimId, Guid userId) - { - return await dbContext.Rooms + public async Task GetClaim(Guid claimId, Guid userId, CancellationToken cancellationToken) => + await dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .SelectMany(r => r.RoomClaims) .Where(l => l.RoomClaimId == claimId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingService.cs index 94a9c3ff..1acb89a8 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Reading/RoomClaimsReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Exceptions; @@ -9,32 +10,22 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Reading; /// -internal class RoomClaimsReadingService : IRoomClaimsReadingService +internal class RoomClaimsReadingService( + IRoomClaimsReadingRepository repository, + IIdentityProvider identityProvider) : IRoomClaimsReadingService { - private readonly IRoomClaimsReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public RoomClaimsReadingService( - IRoomClaimsReadingRepository repository, - IIdentityProvider identityProvider) - { - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public Task> GetGameClaims(Guid gameId) => - repository.GetGameClaims(gameId, identityProvider.Current.User.UserId); + public Task> GetGameClaims(Guid gameId, CancellationToken cancellationToken) => + repository.GetGameClaims(gameId, identityProvider.Current.User.UserId, cancellationToken); /// - public Task> GetRoomClaims(Guid roomId) => - repository.GetRoomClaims(roomId, identityProvider.Current.User.UserId); + public Task> GetRoomClaims(Guid roomId, CancellationToken cancellationToken) => + repository.GetRoomClaims(roomId, identityProvider.Current.User.UserId, cancellationToken); /// - public async Task GetClaim(Guid claimId) + public async Task GetClaim(Guid claimId, CancellationToken cancellationToken) { - var claim = await repository.GetClaim(claimId, identityProvider.Current.User.UserId); + var claim = await repository.GetClaim(claimId, identityProvider.Current.User.UserId, cancellationToken); if (claim == null) { throw new HttpException(HttpStatusCode.Gone, "Claim not found"); diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingRepository.cs index 12481818..eed80a7d 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using RoomClaim = DM.Services.DataAccess.BusinessObjects.Games.Links.RoomClaim; @@ -13,6 +14,7 @@ internal interface IRoomClaimsUpdatingRepository /// Update room claim /// /// Update rules + /// /// - Task Update(IUpdateBuilder updateClaim); + Task Update(IUpdateBuilder updateClaim, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingService.cs index 501653a1..17f9773f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/IRoomClaimsUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IRoomClaimsUpdatingService /// Update existing room claim /// /// DTO for update + /// /// - Task Update(UpdateRoomClaim updateRoomClaim); + Task Update(UpdateRoomClaim updateRoomClaim, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingRepository.cs index 63c1e49b..4f22aa7e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,28 +12,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Updating; /// -internal class RoomClaimsUpdatingRepository : IRoomClaimsUpdatingRepository +internal class RoomClaimsUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomClaimsUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomClaimsUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder updateClaim) + public async Task Update(IUpdateBuilder updateClaim, CancellationToken cancellationToken) { var linkId = updateClaim.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.RoomClaims .Where(l => l.RoomClaimId == linkId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingService.cs index aa38d88d..699821ef 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Claims/Updating/RoomClaimsUpdatingService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -16,42 +17,22 @@ namespace DM.Services.Gaming.BusinessProcesses.Claims.Updating; /// -internal class RoomClaimsUpdatingService : IRoomClaimsUpdatingService +internal class RoomClaimsUpdatingService( + IValidator validator, + IRoomClaimsUpdatingRepository repository, + IRoomClaimsReadingRepository readingRepository, + IRoomUpdatingRepository roomUpdatingRepository, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IIdentityProvider identityProvider) : IRoomClaimsUpdatingService { - private readonly IValidator validator; - private readonly IRoomClaimsUpdatingRepository repository; - private readonly IRoomClaimsReadingRepository readingRepository; - private readonly IRoomUpdatingRepository roomUpdatingRepository; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IIdentityProvider identityProvider; - - /// - public RoomClaimsUpdatingService( - IValidator validator, - IRoomClaimsUpdatingRepository repository, - IRoomClaimsReadingRepository readingRepository, - IRoomUpdatingRepository roomUpdatingRepository, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.repository = repository; - this.readingRepository = readingRepository; - this.roomUpdatingRepository = roomUpdatingRepository; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.identityProvider = identityProvider; - } - /// - public async Task Update(UpdateRoomClaim updateRoomClaim) + public async Task Update(UpdateRoomClaim updateRoomClaim, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateRoomClaim); + await validator.ValidateAndThrowAsync(updateRoomClaim, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; - var oldClaim = await readingRepository.GetClaim(updateRoomClaim.ClaimId, currentUserId); - var room = await roomUpdatingRepository.GetRoom(oldClaim.RoomId, currentUserId); + var oldClaim = await readingRepository.GetClaim(updateRoomClaim.ClaimId, currentUserId, cancellationToken); + var room = await roomUpdatingRepository.GetRoom(oldClaim.RoomId, currentUserId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, room.Game); if (oldClaim.User != null && updateRoomClaim.Policy == RoomAccessPolicy.Full) @@ -64,6 +45,6 @@ public async Task Update(UpdateRoomClaim updateRoomClaim) var updateBuilder = updateBuilderFactory.Create(updateRoomClaim.ClaimId) .Field(c => c.Policy, updateRoomClaim.Policy); - return await repository.Update(updateBuilder); + return await repository.Update(updateBuilder, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs index a72a292a..cf050043 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,28 +11,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Creating; /// -internal class CommentaryCreatingRepository : ICommentaryCreatingRepository +internal class CommentaryCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbComment comment) + public async Task Create(DbComment comment, CancellationToken cancellationToken) { dbContext.Comments.Add(comment); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Comments .Where(c => c.CommentId == comment.CommentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs index e1b1659e..2d5c24f5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/CommentaryCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -15,49 +16,27 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Creating; /// -internal class CommentaryCreatingService : ICommentaryCreatingService +internal class CommentaryCreatingService( + IValidator validator, + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + IIdentityProvider identityProvider, + ICommentaryFactory commentaryFactory, + ICommentaryCreatingRepository repository, + IUnreadCountersRepository countersRepository, + IInvokedEventProducer invokedEventProducer) : ICommentaryCreatingService { - private readonly IValidator validator; - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly IIdentityProvider identityProvider; - private readonly ICommentaryFactory commentaryFactory; - private readonly ICommentaryCreatingRepository repository; - private readonly IUnreadCountersRepository countersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryCreatingService( - IValidator validator, - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - IIdentityProvider identityProvider, - ICommentaryFactory commentaryFactory, - ICommentaryCreatingRepository repository, - IUnreadCountersRepository countersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.commentaryFactory = commentaryFactory; - this.repository = repository; - this.countersRepository = countersRepository; - this.invokedEventProducer = invokedEventProducer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreateComment createComment) + public async Task Create(CreateComment createComment, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createComment); + await validator.ValidateAndThrowAsync(createComment, cancellationToken); - var game = await gameReadingService.GetGame(createComment.EntityId); + var game = await gameReadingService.GetGame(createComment.EntityId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.CreateComment, game); var comment = commentaryFactory.Create(createComment, identityProvider.Current.User.UserId); - var createdComment = await repository.Create(comment); - await countersRepository.Increment(game.Id, UnreadEntryType.Message); + var createdComment = await repository.Create(comment, cancellationToken); + await countersRepository.Increment(game.Id, UnreadEntryType.Message, cancellationToken); await invokedEventProducer.Send(EventType.NewGameComment, comment.CommentId); return createdComment; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs index 5e1404fc..c20b4b60 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; using DbComment = DM.Services.DataAccess.BusinessObjects.Common.Comment; @@ -13,6 +14,7 @@ internal interface ICommentaryCreatingRepository /// Create comment from DAL /// /// DAL model for comment + /// /// - Task Create(DbComment comment); + Task Create(DbComment comment, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs index ae1e8546..7b1ccfd1 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Creating/ICommentaryCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; @@ -12,6 +13,7 @@ public interface ICommentaryCreatingService /// Create new commentary /// /// Create commentary DTO model + /// /// - Task Create(CreateComment createComment); + Task Create(CreateComment createComment, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs index 9f3953a3..e57a3e14 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -14,42 +15,25 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Deleting; /// -internal class CommentaryDeletingService : ICommentaryDeletingService +internal class CommentaryDeletingService( + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + ICommentaryReadingService readingService, + ICommentaryUpdatingRepository updatingRepository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer invokedEventProducer) : ICommentaryDeletingService { - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICommentaryReadingService readingService; - private readonly ICommentaryUpdatingRepository updatingRepository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryDeletingService( - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - ICommentaryReadingService readingService, - ICommentaryUpdatingRepository updatingRepository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer invokedEventProducer) - { - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.readingService = readingService; - this.updatingRepository = updatingRepository; - this.unreadCountersRepository = unreadCountersRepository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task Delete(Guid commentId) + public async Task Delete(Guid commentId, CancellationToken cancellationToken) { - var comment = await readingService.Get(commentId); + var comment = await readingService.Get(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Delete, comment); var updateComment = updateBuilderFactory.Create(commentId) .Field(c => c.IsRemoved, true); - await updatingRepository.Update(updateComment); - await unreadCountersRepository.Decrement(comment.EntityId, UnreadEntryType.Message, comment.CreateDate); + await updatingRepository.Update(updateComment, cancellationToken); + await unreadCountersRepository.Decrement( + comment.EntityId, UnreadEntryType.Message, comment.CreateDate, cancellationToken); await invokedEventProducer.Send(EventType.DeletedGameComment, commentId); } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs index 5adaa4cf..81f21d17 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Deleting; @@ -12,6 +13,7 @@ public interface ICommentaryDeletingService /// Delete commentary by identifier /// /// Commentary identifier + /// /// - Task Delete(Guid commentId); + Task Delete(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs index f9c4a82e..2b5b665d 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,41 +14,27 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Reading; /// -internal class CommentaryReadingRepository : ICommentaryReadingRepository +internal class CommentaryReadingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(Guid gameId) => dbContext.Comments - .CountAsync(c => !c.IsRemoved && c.EntityId == gameId); + public Task Count(Guid gameId, CancellationToken cancellationToken) => dbContext.Comments + .CountAsync(c => !c.IsRemoved && c.EntityId == gameId, cancellationToken); /// - public async Task> Get(Guid gameId, PagingData paging) - { - return await dbContext.Comments + public async Task> Get(Guid gameId, PagingData paging, CancellationToken cancellationToken) => + await dbContext.Comments .Where(c => !c.IsRemoved && c.EntityId == gameId) .OrderBy(c => c.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public Task Get(Guid commentId) - { - return dbContext.Comments + public Task Get(Guid commentId, CancellationToken cancellationToken) => + dbContext.Comments .Where(c => !c.IsRemoved && c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs index 0057a168..b10dde5a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/CommentaryReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -16,57 +17,41 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Reading; /// -internal class CommentaryReadingService : ICommentaryReadingService +internal class CommentaryReadingService( + IIntentionManager intentionManager, + IGameReadingService gameReadingService, + ICommentaryReadingRepository commentaryRepository, + IUnreadCountersRepository unreadCountersRepository, + IIdentityProvider identityProvider) : ICommentaryReadingService { - private readonly IIntentionManager intentionManager; - private readonly IGameReadingService gameReadingService; - private readonly ICommentaryReadingRepository commentaryRepository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public CommentaryReadingService( - IIntentionManager intentionManager, - IGameReadingService gameReadingService, - ICommentaryReadingRepository commentaryRepository, - IUnreadCountersRepository unreadCountersRepository, - IIdentityProvider identityProvider) - { - this.intentionManager = intentionManager; - this.gameReadingService = gameReadingService; - this.commentaryRepository = commentaryRepository; - this.unreadCountersRepository = unreadCountersRepository; - this.identityProvider = identityProvider; - } - /// public async Task<(IEnumerable comments, PagingResult paging, Game game)> Get( - Guid gameId, PagingQuery query) + Guid gameId, PagingQuery query, CancellationToken cancellationToken) { - var game = await gameReadingService.GetGame(gameId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.ReadComments, game); - var totalCount = await commentaryRepository.Count(gameId); + var totalCount = await commentaryRepository.Count(gameId, cancellationToken); var paging = new PagingData(query, identityProvider.Current.Settings.Paging.CommentsPerPage, totalCount); - var comments = await commentaryRepository.Get(gameId, paging); + var comments = await commentaryRepository.Get(gameId, paging, cancellationToken); return (comments, paging.Result, game); } /// - public async Task Get(Guid commentId) + public async Task Get(Guid commentId, CancellationToken cancellationToken) { - return await commentaryRepository.Get(commentId) ?? + return await commentaryRepository.Get(commentId, cancellationToken) ?? throw new HttpException(HttpStatusCode.Gone, $"Comment {commentId} not found"); } /// - public async Task MarkAsRead(Guid gameId) + public async Task MarkAsRead(Guid gameId, CancellationToken cancellationToken) { - var game = await gameReadingService.GetGame(gameId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.ReadComments, game); await unreadCountersRepository.Flush(identityProvider.Current.User.UserId, - UnreadEntryType.Message, gameId); + UnreadEntryType.Message, gameId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs index 92f01428..b4183da2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; using DM.Services.Core.Dto; @@ -15,21 +16,24 @@ internal interface ICommentaryReadingRepository /// Count comments of the game /// /// Game identifier + /// /// Number of game comments - Task Count(Guid gameId); + Task Count(Guid gameId, CancellationToken cancellationToken); /// /// Get comments list of the game /// /// Game identifier /// Paging data + /// /// - Task> Get(Guid gameId, PagingData paging); + Task> Get(Guid gameId, PagingData paging, CancellationToken cancellationToken); /// /// Get single comment by its identifier /// /// Commentary identifier + /// /// Found commentary - Task Get(Guid commentId); + Task Get(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs index 512f77f5..e369c825 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Reading/ICommentaryReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; using DM.Services.Core.Dto; @@ -17,20 +18,24 @@ public interface ICommentaryReadingService /// /// Game identifier /// Paging query + /// /// Pair of comments list and paging data - Task<(IEnumerable comments, PagingResult paging, Game game)> Get(Guid gameId, PagingQuery query); + Task<(IEnumerable comments, PagingResult paging, Game game)> Get(Guid gameId, PagingQuery query, + CancellationToken cancellationToken); /// /// Get game comment by id /// /// Commentary identifier + /// /// Found comment - Task Get(Guid commentId); + Task Get(Guid commentId, CancellationToken cancellationToken); /// /// Mark game comments as read /// /// Game identifier + /// /// - Task MarkAsRead(Guid gameId); + Task MarkAsRead(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs index 4c095e98..824c1efc 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -10,28 +11,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Updating; /// -internal class CommentaryUpdatingRepository : ICommentaryUpdatingRepository +internal class CommentaryUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : ICommentaryUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public CommentaryUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder update) + public async Task Update(IUpdateBuilder update, CancellationToken cancellationToken) { var commentId = update.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Comments .Where(c => c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs index 6bd371ac..f90f5808 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.Dto; @@ -13,40 +14,20 @@ namespace DM.Services.Gaming.BusinessProcesses.Commentaries.Updating; /// -internal class CommentaryUpdatingService : ICommentaryUpdatingService +internal class CommentaryUpdatingService( + IValidator validator, + ICommentaryReadingService commentaryReadingService, + IIntentionManager intentionManager, + IDateTimeProvider dateTimeProvider, + IUpdateBuilderFactory updateBuilderFactory, + ICommentaryUpdatingRepository repository, + IInvokedEventProducer invokedEventProducer) : ICommentaryUpdatingService { - private readonly IValidator validator; - private readonly ICommentaryReadingService commentaryReadingService; - private readonly IIntentionManager intentionManager; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly ICommentaryUpdatingRepository repository; - private readonly IInvokedEventProducer invokedEventProducer; - - /// - public CommentaryUpdatingService( - IValidator validator, - ICommentaryReadingService commentaryReadingService, - IIntentionManager intentionManager, - IDateTimeProvider dateTimeProvider, - IUpdateBuilderFactory updateBuilderFactory, - ICommentaryUpdatingRepository repository, - IInvokedEventProducer invokedEventProducer) - { - this.validator = validator; - this.commentaryReadingService = commentaryReadingService; - this.intentionManager = intentionManager; - this.dateTimeProvider = dateTimeProvider; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.invokedEventProducer = invokedEventProducer; - } - /// - public async Task Update(UpdateComment updateComment) + public async Task Update(UpdateComment updateComment, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateComment); - var comment = await commentaryReadingService.Get(updateComment.CommentId); + await validator.ValidateAndThrowAsync(updateComment, cancellationToken); + var comment = await commentaryReadingService.Get(updateComment.CommentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Edit, comment); var updateBuilder = updateBuilderFactory.Create(updateComment.CommentId) @@ -57,7 +38,7 @@ public CommentaryUpdatingService( updateBuilder.Field(f => f.LastUpdateDate, dateTimeProvider.Now); } - var updatedComment = await repository.Update(updateBuilder); + var updatedComment = await repository.Update(updateBuilder, cancellationToken); await invokedEventProducer.Send(EventType.ChangedGameComment, updateComment.CommentId); return updatedComment; } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs index f4833de1..a3a5bc42 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using Comment = DM.Services.DataAccess.BusinessObjects.Common.Comment; @@ -13,6 +14,7 @@ public interface ICommentaryUpdatingRepository /// Update single commentary /// /// Update commentary + /// /// - Task Update(IUpdateBuilder update); + Task Update(IUpdateBuilder update, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs index aa22eff8..4778f49a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Commentaries/Updating/ICommentaryUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Dto; @@ -12,6 +13,7 @@ public interface ICommentaryUpdatingService /// Update existing comment /// /// Update comment model + /// /// - Task Update(UpdateComment updateComment); + Task Update(UpdateComment updateComment, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/AssignmentService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/AssignmentService.cs index a13573c8..cf116a78 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/AssignmentService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/AssignmentService.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto.Enums; @@ -37,7 +38,7 @@ public AssignmentService( } /// - public async Task CreateAssignment(Guid gameId, Guid userId) + public async Task CreateAssignment(Guid gameId, Guid userId, CancellationToken cancellationToken) { var updates = (await repository.FindAssignments(gameId)) .Select(id => updateBuilderFactory.Create(id).Field(t => t.IsRemoved, true)); diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/IAssignmentService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/IAssignmentService.cs index b3b3ad80..2c16f54c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/IAssignmentService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/AssistantAssignment/IAssignmentService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Games.AssistantAssignment; @@ -13,8 +14,9 @@ public interface IAssignmentService /// /// Game identifier /// User identifier + /// /// - Task CreateAssignment(Guid gameId, Guid userId); + Task CreateAssignment(Guid gameId, Guid userId, CancellationToken cancellationToken); /// /// User accepts the request and becomes the game assistant diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingRepository.cs index 0b1823f5..fe7cfaeb 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,31 +14,21 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Creating; /// -internal class GameCreatingRepository : IGameCreatingRepository +internal class GameCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IGameCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public GameCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// public async Task Create(DbGame game, DbRoom room, - IEnumerable tags) + IEnumerable tags, CancellationToken cancellationToken) { - await dbContext.Games.AddAsync(game); - await dbContext.Rooms.AddAsync(room); - await dbContext.GameTags.AddRangeAsync(tags); - await dbContext.SaveChangesAsync(); + await dbContext.Games.AddAsync(game, cancellationToken); + await dbContext.Rooms.AddAsync(room, cancellationToken); + await dbContext.GameTags.AddRangeAsync(tags, cancellationToken); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Games .Where(g => g.GameId == game.GameId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingService.cs index cb9e8d0b..37133ca5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/GameCreatingService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -20,57 +21,25 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Creating; /// -internal class GameCreatingService : IGameCreatingService +internal class GameCreatingService( + IValidator validator, + IIntentionManager intentionManager, + IGameReadingService readingService, + IAssignmentService assignmentService, + IIdentityProvider identityProvider, + IGameFactory gameFactory, + IRoomFactory roomFactory, + IGameTagFactory gameTagFactory, + IGameCreatingRepository repository, + IUserRepository userRepository, + ISchemaReadingRepository schemaRepository, + IUnreadCountersRepository countersRepository, + IInvokedEventProducer producer) : IGameCreatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IGameReadingService readingService; - private readonly IAssignmentService assignmentService; - private readonly IIdentityProvider identityProvider; - private readonly IGameFactory gameFactory; - private readonly IRoomFactory roomFactory; - private readonly IGameTagFactory gameTagFactory; - private readonly IGameCreatingRepository repository; - private readonly IUserRepository userRepository; - private readonly ISchemaReadingRepository schemaRepository; - private readonly IUnreadCountersRepository countersRepository; - private readonly IInvokedEventProducer producer; - - /// - public GameCreatingService( - IValidator validator, - IIntentionManager intentionManager, - IGameReadingService readingService, - IAssignmentService assignmentService, - IIdentityProvider identityProvider, - IGameFactory gameFactory, - IRoomFactory roomFactory, - IGameTagFactory gameTagFactory, - IGameCreatingRepository repository, - IUserRepository userRepository, - ISchemaReadingRepository schemaRepository, - IUnreadCountersRepository countersRepository, - IInvokedEventProducer producer) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.readingService = readingService; - this.assignmentService = assignmentService; - this.identityProvider = identityProvider; - this.gameFactory = gameFactory; - this.roomFactory = roomFactory; - this.gameTagFactory = gameTagFactory; - this.repository = repository; - this.userRepository = userRepository; - this.schemaRepository = schemaRepository; - this.countersRepository = countersRepository; - this.producer = producer; - } - /// - public async Task Create(CreateGame createGame) + public async Task Create(CreateGame createGame, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createGame); + await validator.ValidateAndThrowAsync(createGame, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Create); // resolve game initial status @@ -88,7 +57,7 @@ public async Task Create(CreateGame createGame) IEnumerable tags; if (createGame.Tags != null && createGame.Tags.Any()) { - var availableTags = (await readingService.GetTags()).Select(t => t.Id).ToHashSet(); + var availableTags = (await readingService.GetTags(cancellationToken)).Select(t => t.Id).ToHashSet(); tags = createGame.Tags .Where(availableTags.Contains) .Select(tagId => gameTagFactory.Create(game.GameId, tagId)); @@ -101,27 +70,28 @@ public async Task Create(CreateGame createGame) // initiate assistant assignment if (!string.IsNullOrEmpty(createGame.AssistantLogin)) { - var (assistantExists, foundAssistantId) = await userRepository.FindUserId(createGame.AssistantLogin); + var (assistantExists, foundAssistantId) = await userRepository.FindUserId( + createGame.AssistantLogin, cancellationToken); if (assistantExists) { - await assignmentService.CreateAssignment(game.GameId, foundAssistantId); + await assignmentService.CreateAssignment(game.GameId, foundAssistantId, cancellationToken); } } if (createGame.AttributeSchemaId.HasValue) { - var schema = await schemaRepository.GetSchema(createGame.AttributeSchemaId.Value); + var schema = await schemaRepository.GetSchema(createGame.AttributeSchemaId.Value, cancellationToken); if (intentionManager.IsAllowed(AttributeSchemaIntention.Use, schema)) { game.AttributeSchemaId = createGame.AttributeSchemaId.Value; } } - var createdGame = await repository.Create(game, room, tags); + var createdGame = await repository.Create(game, room, tags, cancellationToken); - await countersRepository.Create(room.RoomId, UnreadEntryType.Message); - await countersRepository.Create(game.GameId, UnreadEntryType.Message); - await countersRepository.Create(game.GameId, UnreadEntryType.Character); + await countersRepository.Create(room.RoomId, UnreadEntryType.Message, cancellationToken); + await countersRepository.Create(game.GameId, UnreadEntryType.Message, cancellationToken); + await countersRepository.Create(game.GameId, UnreadEntryType.Character, cancellationToken); await producer.Send(EventType.NewGame, game.GameId); return createdGame; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingRepository.cs index d6ef0bf9..d8dba44f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; using DbGame = DM.Services.DataAccess.BusinessObjects.Games.Game; @@ -18,7 +19,8 @@ internal interface IGameCreatingRepository /// Game DAL /// Room DAL /// Game tag DALs + /// /// - Task Create(DbGame game, DbRoom room, IEnumerable tags); + Task Create(DbGame game, DbRoom room, IEnumerable tags, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingService.cs index 50f56972..2fbf6c67 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Creating/IGameCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,5 +14,5 @@ public interface IGameCreatingService /// Create new game /// /// - Task Create(CreateGame createGame); + Task Create(CreateGame createGame, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/GameDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/GameDeletingService.cs index dbecaa40..7e3f7c2b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/GameDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/GameDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Dto.Enums; @@ -12,38 +13,22 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Deleting; /// -internal class GameDeletingService : IGameDeletingService +internal class GameDeletingService( + IGameReadingService gameReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IGameUpdatingRepository repository, + IInvokedEventProducer producer) : IGameDeletingService { - private readonly IGameReadingService gameReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IGameUpdatingRepository repository; - private readonly IInvokedEventProducer producer; - - /// - public GameDeletingService( - IGameReadingService gameReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IGameUpdatingRepository repository, - IInvokedEventProducer producer) - { - this.gameReadingService = gameReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.producer = producer; - } - /// - public async Task DeleteGame(Guid gameId) + public async Task DeleteGame(Guid gameId, CancellationToken cancellationToken) { - var gameToRemove = await gameReadingService.GetGame(gameId); + var gameToRemove = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Delete, gameToRemove); var updateBuilder = updateBuilderFactory.Create(gameId) .Field(g => g.IsRemoved, true); - await repository.Update(updateBuilder); + await repository.Update(updateBuilder, cancellationToken); await producer.Send(EventType.DeletedGame, gameId); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/IGameDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/IGameDeletingService.cs index 28e66601..b47545dc 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/IGameDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Deleting/IGameDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Games.Deleting; @@ -12,6 +13,7 @@ public interface IGameDeletingService /// Remove existing game /// /// Game identifier + /// /// - Task DeleteGame(Guid gameId); + Task DeleteGame(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingRepository.cs index 1bd3f2f0..ad83edd2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -15,34 +16,22 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Reading; /// -internal class GameReadingRepository : IGameReadingRepository +internal class GameReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IGameReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public GameReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(GamesQuery query, Guid userId) - { - return dbContext.Games + public Task Count(GamesQuery query, Guid userId, CancellationToken cancellationToken) => + dbContext.Games .Where(AccessibilityFilters.GameAvailable(userId)) .Where(g => query.Statuses.Contains(g.Status)) .Where(g => !query.TagId.HasValue || g.GameTags.Any(t => t.TagId == query.TagId.Value)) - .CountAsync(); - } + .CountAsync(cancellationToken); /// - public async Task> GetGames(PagingData pagingData, GamesQuery query, Guid userId) - { - return await dbContext.Games + public async Task> GetGames( + PagingData pagingData, GamesQuery query, Guid userId, CancellationToken cancellationToken) => + await dbContext.Games .Where(AccessibilityFilters.GameAvailable(userId)) .Where(g => query.Statuses.Contains(g.Status)) .Where(g => !query.TagId.HasValue || g.GameTags.Any(t => t.TagId == query.TagId.Value)) @@ -50,83 +39,73 @@ public async Task> GetGames(PagingData pagingData, GamesQuery .Skip(pagingData.Skip) .Take(pagingData.Take) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public async Task> GetOwn(Guid userId) - { - return await dbContext.Games + public async Task> GetOwn(Guid userId, CancellationToken cancellationToken) => + await dbContext.Games .Where(AccessibilityFilters.GameAvailable(userId)) .Where(g => g.Characters.Any(c => !c.IsRemoved && c.Status == CharacterStatus.Active && c.UserId == userId) || g.Readers.Any(r => r.UserId == userId) || g.MasterId == userId || g.AssistantId == userId || g.NannyId == userId) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public async Task>> GetAvailableRoomIds(IEnumerable gameIds, Guid userId) + public async Task>> GetAvailableRoomIds( + IEnumerable gameIds, Guid userId, CancellationToken cancellationToken) { var roomsInGames = await dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .Where(r => gameIds.Contains(r.GameId)) .Select(r => new {r.RoomId, r.GameId}) - .ToArrayAsync(); + .ToArrayAsync(cancellationToken); return roomsInGames .GroupBy(g => g.GameId) .ToDictionary(g => g.Key, g => g.Select(r => r.RoomId)); } /// - public async Task> GetPendingPosts(IEnumerable gameIds, Guid userId) - { - return await dbContext.Rooms + public async Task> GetPendingPosts( + IEnumerable gameIds, Guid userId, CancellationToken cancellationToken) => + await dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .Where(r => gameIds.Contains(r.GameId)) .SelectMany(r => r.PendingPosts) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public Task GetGameDetails(Guid gameId, Guid userId) - { - return dbContext.Games + public Task GetGameDetails(Guid gameId, Guid userId, CancellationToken cancellationToken) => + dbContext.Games .Where(AccessibilityFilters.GameAvailable(userId)) .Where(g => g.GameId == gameId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); /// - public Task GetGame(Guid gameId, Guid userId) - { - return dbContext.Games + public Task GetGame(Guid gameId, Guid userId, CancellationToken cancellationToken) => + dbContext.Games .Where(AccessibilityFilters.GameAvailable(userId)) .Where(g => g.GameId == gameId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); + /// /// - public async Task> GetTags() - { - return await dbContext.Tags + public async Task> GetTags(CancellationToken cancellationToken) => + await dbContext.Tags .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public async Task> GetPopularGames(int gamesCount) - { - return await dbContext.Games + public async Task> GetPopularGames(int gamesCount, CancellationToken cancellationToken) => + await dbContext.Games .Where(g => !g.IsRemoved) .Where(g => g.Status == GameStatus.Active || g.Status == GameStatus.Requirement) .OrderByDescending(g => g.Readers.Count) .Take(gamesCount) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingService.cs index 28e9dc60..bb8c6903 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/GameReadingService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -20,67 +21,47 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Reading; /// -internal class GameReadingService : IGameReadingService +internal class GameReadingService( + IValidator validator, + IIntentionManager intentionManager, + ISchemaReadingService schemaReadingService, + IGameReadingRepository repository, + IIdentityProvider identityProvider, + IUnreadCountersRepository unreadCountersRepository, + IMemoryCache cache) : IGameReadingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly ISchemaReadingService schemaReadingService; - private readonly IGameReadingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IMemoryCache cache; - private readonly IIdentityProvider identityProvider; - private const string TagListCacheKey = nameof(TagListCacheKey); private const string PopularGamesCacheKey = nameof(PopularGamesCacheKey); private const int PopularGamesLimit = 10; /// - public GameReadingService( - IValidator validator, - IIntentionManager intentionManager, - ISchemaReadingService schemaReadingService, - IGameReadingRepository repository, - IIdentityProvider identityProvider, - IUnreadCountersRepository unreadCountersRepository, - IMemoryCache cache) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.schemaReadingService = schemaReadingService; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.cache = cache; - this.identityProvider = identityProvider; - } - - /// - public Task> GetTags() + public Task> GetTags(CancellationToken cancellationToken) { return cache.GetOrCreateAsync(TagListCacheKey, async e => { e.SlidingExpiration = TimeSpan.FromDays(1); - return await repository.GetTags(); + return await repository.GetTags(cancellationToken); }); } /// - public async Task> GetOwnGames() + public async Task> GetOwnGames(CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var games = (await repository.GetOwn(currentUserId)).ToArray(); + var games = (await repository.GetOwn(currentUserId, cancellationToken)).ToArray(); - await unreadCountersRepository.FillEntityCounters( - games, currentUserId, g => g.Id, g => g.UnreadCommentsCount); - await unreadCountersRepository.FillEntityCounters( - games, currentUserId, g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character); + await unreadCountersRepository.FillEntityCounters(games, currentUserId, + g => g.Id, g => g.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); + await unreadCountersRepository.FillEntityCounters(games, currentUserId, + g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character, cancellationToken); var gameIds = games.Select(g => g.Id).ToArray(); - var gameRooms = await repository.GetAvailableRoomIds(gameIds, currentUserId); + var gameRooms = await repository.GetAvailableRoomIds(gameIds, currentUserId, cancellationToken); var allRoomIds = gameRooms.SelectMany(r => r.Value).ToArray(); var unreadPostCounters = await unreadCountersRepository.SelectByEntities( - currentUserId, UnreadEntryType.Message, allRoomIds); + currentUserId, UnreadEntryType.Message, allRoomIds, cancellationToken); - var pendingPosts = (await repository.GetPendingPosts(gameIds, currentUserId)).ToArray(); + var pendingPosts = (await repository.GetPendingPosts(gameIds, currentUserId, cancellationToken)).ToArray(); foreach (var game in games) { @@ -95,51 +76,52 @@ await unreadCountersRepository.FillEntityCounters( } /// - public async Task<(IEnumerable games, PagingResult paging)> GetGames(GamesQuery query) + public async Task<(IEnumerable games, PagingResult paging)> GetGames( + GamesQuery query, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(query); + await validator.ValidateAndThrowAsync(query, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; - var totalCount = await repository.Count(query, currentUserId); + var totalCount = await repository.Count(query, currentUserId, cancellationToken); var pagingData = new PagingData(query, identityProvider.Current.Settings.Paging.EntitiesPerPage, totalCount); - var games = (await repository.GetGames(pagingData, query, currentUserId)).ToArray(); + var games = (await repository.GetGames(pagingData, query, currentUserId, cancellationToken)).ToArray(); await unreadCountersRepository.FillEntityCounters(games, currentUserId, - g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character); + g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character, cancellationToken); var gamesWithAvailableComments = games .Where(g => intentionManager.IsAllowed(GameIntention.ReadComments, g)) .ToArray(); await unreadCountersRepository.FillEntityCounters(gamesWithAvailableComments, currentUserId, - g => g.Id, g => g.UnreadCommentsCount); + g => g.Id, g => g.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); return (games, pagingData.Result); } /// - public async Task GetGame(Guid gameId) + public async Task GetGame(Guid gameId, CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var game = await repository.GetGame(gameId, currentUserId); + var game = await repository.GetGame(gameId, currentUserId, cancellationToken); if (game == null) { throw new HttpException(HttpStatusCode.Gone, "Game not found"); } await unreadCountersRepository.FillEntityCounters(new[] {game}, currentUserId, - g => g.Id, g => g.UnreadCommentsCount); + g => g.Id, g => g.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); await unreadCountersRepository.FillEntityCounters(new[] {game}, currentUserId, - g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character); + g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character, cancellationToken); return game; } /// - public async Task GetGameDetails(Guid gameId) + public async Task GetGameDetails(Guid gameId, CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var game = await repository.GetGameDetails(gameId, currentUserId); + var game = await repository.GetGameDetails(gameId, currentUserId, cancellationToken); if (game == null) { throw new HttpException(HttpStatusCode.Gone, "Game not found"); @@ -147,24 +129,25 @@ public async Task GetGameDetails(Guid gameId) if (game.AttributeSchemaId.HasValue) { - game.AttributeSchema = await schemaReadingService.Get(game.AttributeSchemaId.Value); + game.AttributeSchema = await schemaReadingService.Get(game.AttributeSchemaId.Value, cancellationToken); } await unreadCountersRepository.FillEntityCounters(new[] {game}, currentUserId, - g => g.Id, g => g.UnreadCommentsCount); + g => g.Id, g => g.UnreadCommentsCount, UnreadEntryType.Message, cancellationToken); await unreadCountersRepository.FillEntityCounters(new[] {game}, currentUserId, - g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character); + g => g.Id, g => g.UnreadCharactersCount, UnreadEntryType.Character, cancellationToken); return game; } + /// /// - public Task> GetPopularGames() + public Task> GetPopularGames(CancellationToken cancellationToken) { return cache.GetOrCreateAsync(PopularGamesCacheKey, async e => { e.SlidingExpiration = TimeSpan.FromDays(1); - return await repository.GetPopularGames(PopularGamesLimit); + return await repository.GetPopularGames(PopularGamesLimit, cancellationToken); }); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingRepository.cs index bfb2e02e..1e7bd84d 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Gaming.Dto.Input; @@ -17,8 +18,9 @@ internal interface IGameReadingRepository /// /// Status filter /// User identifier + /// /// - Task Count(GamesQuery status, Guid userId); + Task Count(GamesQuery status, Guid userId, CancellationToken cancellationToken); /// /// Get list of matching games on certain page @@ -26,55 +28,64 @@ internal interface IGameReadingRepository /// Paging data /// Filter query /// User identifier + /// /// - Task> GetGames(PagingData pagingData, GamesQuery query, Guid userId); + Task> GetGames(PagingData pagingData, GamesQuery query, Guid userId, + CancellationToken cancellationToken); /// /// Get list of user owned active games /// /// User identifier + /// /// - Task> GetOwn(Guid userId); + Task> GetOwn(Guid userId, CancellationToken cancellationToken); /// /// Get available room identifiers grouped by game ids /// /// - Task>> GetAvailableRoomIds(IEnumerable gameIds, Guid userId); + Task>> GetAvailableRoomIds(IEnumerable gameIds, Guid userId, + CancellationToken cancellationToken); /// /// Get game pending posts /// /// Game identifiers /// User identifier + /// /// - Task> GetPendingPosts(IEnumerable gameIds, Guid userId); + Task> GetPendingPosts(IEnumerable gameIds, Guid userId, + CancellationToken cancellationToken); /// /// Get single game model /// /// Game identifier /// User identifier + /// /// - Task GetGame(Guid gameId, Guid userId); + Task GetGame(Guid gameId, Guid userId, CancellationToken cancellationToken); /// /// Get single game full info /// /// Game identifier /// User identifier + /// /// - Task GetGameDetails(Guid gameId, Guid userId); + Task GetGameDetails(Guid gameId, Guid userId, CancellationToken cancellationToken); /// /// Get list of available tags /// + /// /// - Task> GetTags(); + Task> GetTags(CancellationToken cancellationToken); /// /// Get list of popular active games /// /// - Task> GetPopularGames(int gamesCount); + Task> GetPopularGames(int gamesCount, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingService.cs index 0803626c..5e1870f1 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Reading/IGameReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Gaming.Dto.Input; @@ -15,39 +16,45 @@ public interface IGameReadingService /// /// Get available game tags /// + /// /// - Task> GetTags(); + Task> GetTags(CancellationToken cancellationToken); /// /// Get user games /// + /// /// - Task> GetOwnGames(); + Task> GetOwnGames(CancellationToken cancellationToken); /// /// Get games page /// /// Search query + /// /// List of fetched games and paging data - Task<(IEnumerable games, PagingResult paging)> GetGames(GamesQuery query); + Task<(IEnumerable games, PagingResult paging)> GetGames(GamesQuery query, CancellationToken cancellationToken); /// /// Get game by identifier /// /// Game identifier + /// /// - Task GetGame(Guid gameId); + Task GetGame(Guid gameId, CancellationToken cancellationToken); /// /// Get game details by identifier /// /// Game identifier + /// /// - Task GetGameDetails(Guid gameId); + Task GetGameDetails(Guid gameId, CancellationToken cancellationToken); /// /// Get user games /// + /// /// - Task> GetPopularGames(); + Task> GetPopularGames(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/IUserRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/IUserRepository.cs index b3a9e7df..9c6fa5e6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/IUserRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/IUserRepository.cs @@ -13,8 +13,9 @@ internal interface IUserRepository /// Try find user by login /// /// User login + /// /// Pair of existence flag and user identifier - Task<(bool exists, Guid userId)> FindUserId(string login); + Task<(bool exists, Guid userId)> FindUserId(string login, CancellationToken cancellationToken); /// /// User with login exists diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/UserRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/UserRepository.cs index 01a8e4eb..9e8cdee9 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/UserRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Shared/UserRepository.cs @@ -8,24 +8,16 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Shared; /// -internal class UserRepository : IUserRepository +internal class UserRepository( + DmDbContext dbContext) : IUserRepository { - private readonly DmDbContext dbContext; - - /// - public UserRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public async Task<(bool exists, Guid userId)> FindUserId(string login) + public async Task<(bool exists, Guid userId)> FindUserId(string login, CancellationToken cancellationToken) { var foundUserId = await dbContext.Users .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) .Select(u => u.UserId) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); return (foundUserId != default, foundUserId); } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingRepository.cs index 51fa6d2b..75fd80c2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingRepository.cs @@ -1,38 +1,30 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Output; +using Microsoft.EntityFrameworkCore; using Game = DM.Services.DataAccess.BusinessObjects.Games.Game; namespace DM.Services.Gaming.BusinessProcesses.Games.Updating; /// -internal class GameUpdatingRepository : IGameUpdatingRepository +internal class GameUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : IGameUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public GameUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder updateGame) + public async Task Update(IUpdateBuilder updateGame, CancellationToken cancellationToken) { var gameId = updateGame.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); - return dbContext.Games + return await dbContext.Games .Where(g => g.GameId == gameId) .ProjectTo(mapper.ConfigurationProvider) - .First(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingService.cs index e9367a4e..23c7a726 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/GameUpdatingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -19,52 +20,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Games.Updating; /// -internal class GameUpdatingService : IGameUpdatingService +internal class GameUpdatingService( + IValidator validator, + IIntentionManager intentionManager, + IGameReadingService gameReadingService, + IAssignmentService assignmentService, + IUpdateBuilderFactory updateBuilderFactory, + IUserRepository userRepository, + IDateTimeProvider dateTimeProvider, + IGameUpdatingRepository updatingRepository, + IGameIntentionConverter intentionConverter, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IGameUpdatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IGameReadingService gameReadingService; - private readonly IAssignmentService assignmentService; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IUserRepository userRepository; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IGameUpdatingRepository updatingRepository; - private readonly IGameIntentionConverter intentionConverter; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public GameUpdatingService( - IValidator validator, - IIntentionManager intentionManager, - IGameReadingService gameReadingService, - IAssignmentService assignmentService, - IUpdateBuilderFactory updateBuilderFactory, - IUserRepository userRepository, - IDateTimeProvider dateTimeProvider, - IGameUpdatingRepository updatingRepository, - IGameIntentionConverter intentionConverter, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.gameReadingService = gameReadingService; - this.assignmentService = assignmentService; - this.updateBuilderFactory = updateBuilderFactory; - this.userRepository = userRepository; - this.dateTimeProvider = dateTimeProvider; - this.updatingRepository = updatingRepository; - this.intentionConverter = intentionConverter; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Update(UpdateGame updateGame) + public async Task Update(UpdateGame updateGame, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateGame); - var game = await gameReadingService.GetGameDetails(updateGame.GameId); + await validator.ValidateAndThrowAsync(updateGame, cancellationToken); + var game = await gameReadingService.GetGameDetails(updateGame.GameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, game); var changes = updateBuilderFactory.Create(game.Id) @@ -86,11 +59,12 @@ public async Task Update(UpdateGame updateGame) if (updateGame.AssistantLogin != default && !updateGame.AssistantLogin.Equals(oldAssistant?.Login, StringComparison.InvariantCultureIgnoreCase)) { - var (assistantExists, foundAssistantId) = await userRepository.FindUserId(updateGame.AssistantLogin); + var (assistantExists, foundAssistantId) = await userRepository.FindUserId( + updateGame.AssistantLogin, cancellationToken); if (assistantExists) { changes.Field(g => g.AssistantId, null); - await assignmentService.CreateAssignment(game.Id, foundAssistantId); + await assignmentService.CreateAssignment(game.Id, foundAssistantId, cancellationToken); } } @@ -119,7 +93,7 @@ public async Task Update(UpdateGame updateGame) } } - var result = await updatingRepository.Update(changes); + var result = await updatingRepository.Update(changes, cancellationToken); await producer.Send(invokedEvents, game.Id); return result; } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingRepository.cs index 06311a32..7fe72715 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Output; @@ -14,6 +15,7 @@ internal interface IGameUpdatingRepository /// Save game changes /// /// Game changes + /// /// - Task Update(IUpdateBuilder updateGame); + Task Update(IUpdateBuilder updateGame, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingService.cs index d2852591..4b4a807e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Games/Updating/IGameUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IGameUpdatingService /// Update existing game /// /// Update game model + /// /// - Task Update(UpdateGame updateGame); + Task Update(UpdateGame updateGame, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Likes/ILikeService.cs b/src/DM.Services.Gaming/BusinessProcesses/Likes/ILikeService.cs index a81c60e7..5553e54a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Likes/ILikeService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Likes/ILikeService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,13 +14,15 @@ public interface ILikeService /// Create new like from current user to selected comment /// /// Comment identifier + /// /// User who liked the comment - Task LikeComment(Guid commentId); + Task LikeComment(Guid commentId, CancellationToken cancellationToken); /// /// Remove existing like from current user to selected comment /// /// Comment identifier + /// /// - Task DislikeComment(Guid commentId); + Task DislikeComment(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Likes/LikeService.cs b/src/DM.Services.Gaming/BusinessProcesses/Likes/LikeService.cs index 21a56683..013a8c4e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Likes/LikeService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Likes/LikeService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -14,38 +15,28 @@ namespace DM.Services.Gaming.BusinessProcesses.Likes; /// /// Forum like service /// -internal class LikeService : LikeServiceBase, ILikeService +internal class LikeService( + ICommentaryReadingService commentaryReadingService, + IIntentionManager intentionManager, + IIdentityProvider identityProvider, + ILikeFactory likeFactory, + ILikeRepository likeRepository, + IInvokedEventProducer invokedEventProducer) + : LikeServiceBase(identityProvider, likeFactory, likeRepository, invokedEventProducer), ILikeService { - private readonly ICommentaryReadingService commentaryReadingService; - private readonly IIntentionManager intentionManager; - - /// - public LikeService( - ICommentaryReadingService commentaryReadingService, - IIntentionManager intentionManager, - IIdentityProvider identityProvider, - ILikeFactory likeFactory, - ILikeRepository likeRepository, - IInvokedEventProducer invokedEventProducer) - : base(identityProvider, likeFactory, likeRepository, invokedEventProducer) - { - this.commentaryReadingService = commentaryReadingService; - this.intentionManager = intentionManager; - } - /// - public async Task LikeComment(Guid commentId) + public async Task LikeComment(Guid commentId, CancellationToken cancellationToken) { - var comment = await commentaryReadingService.Get(commentId); + var comment = await commentaryReadingService.Get(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Like, comment); - return await Like(comment, EventType.LikedGameComment); + return await Like(comment, EventType.LikedGameComment, cancellationToken); } /// - public async Task DislikeComment(Guid commentId) + public async Task DislikeComment(Guid commentId, CancellationToken cancellationToken) { - var comment = await commentaryReadingService.Get(commentId); + var comment = await commentaryReadingService.Get(commentId, cancellationToken); intentionManager.ThrowIfForbidden(CommentIntention.Like, comment); - await Dislike(comment); + await Dislike(comment, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingRepository.cs index 9e08fade..026451c6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; using DbPendingPost = DM.Services.DataAccess.BusinessObjects.Games.Links.PendingPost; @@ -13,6 +14,7 @@ internal interface IPendingPostCreatingRepository /// Save new pending post /// /// DAL model + /// /// - Task Create(DbPendingPost pendingPost); + Task Create(DbPendingPost pendingPost, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingService.cs index 06e41d75..914e6164 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/IPendingPostCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IPendingPostCreatingService /// Create new pending /// /// DTO model + /// /// - Task Create(CreatePendingPost createPendingPost); + Task Create(CreatePendingPost createPendingPost, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingRepository.cs index eef6745c..febb1b65 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingRepository.cs @@ -1,36 +1,28 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.Gaming.Dto.Output; using Microsoft.EntityFrameworkCore; +using DbPendingPost = DM.Services.DataAccess.BusinessObjects.Games.Links.PendingPost; namespace DM.Services.Gaming.BusinessProcesses.Pending.Creating; /// -internal class PendingPostCreatingRepository : IPendingPostCreatingRepository +internal class PendingPostCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IPendingPostCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PendingPostCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DataAccess.BusinessObjects.Games.Links.PendingPost pendingPost) + public async Task Create(DbPendingPost pendingPost, CancellationToken cancellationToken) { dbContext.PendingPosts.Add(pendingPost); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.PendingPosts .Where(p => p.PendingPostId == pendingPost.PendingPostId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingService.cs index 629f7f8f..d2d12e6f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Creating/PendingPostCreatingService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -17,46 +18,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Pending.Creating; /// -internal class PendingPostCreatingService : IPendingPostCreatingService +internal class PendingPostCreatingService( + IValidator validator, + IRoomReadingService roomReadingService, + IIntentionManager intentionManager, + IPendingPostFactory factory, + IUserRepository userRepository, + IPendingPostCreatingRepository repository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IPendingPostCreatingService { - private readonly IValidator validator; - private readonly IRoomReadingService roomReadingService; - private readonly IIntentionManager intentionManager; - private readonly IPendingPostFactory factory; - private readonly IUserRepository userRepository; - private readonly IPendingPostCreatingRepository repository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public PendingPostCreatingService( - IValidator validator, - IRoomReadingService roomReadingService, - IIntentionManager intentionManager, - IPendingPostFactory factory, - IUserRepository userRepository, - IPendingPostCreatingRepository repository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.roomReadingService = roomReadingService; - this.intentionManager = intentionManager; - this.factory = factory; - this.userRepository = userRepository; - this.repository = repository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreatePendingPost createPendingPost) + public async Task Create(CreatePendingPost createPendingPost, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createPendingPost); - var room = await roomReadingService.Get(createPendingPost.RoomId); + await validator.ValidateAndThrowAsync(createPendingPost, cancellationToken); + var room = await roomReadingService.Get(createPendingPost.RoomId, cancellationToken); intentionManager.ThrowIfForbidden(RoomIntention.CreatePendingPost, room); - var (_, pendingUserId) = await userRepository.FindUserId(createPendingPost.PendingUserLogin); + var (_, pendingUserId) = await userRepository.FindUserId(createPendingPost.PendingUserLogin, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; if (room.Pendings.Any(p => p.AwaitingUser.UserId == currentUserId && @@ -76,7 +55,7 @@ public async Task Create(CreatePendingPost createPendingPost) var pendingPostToCreate = factory.Create(createPendingPost, currentUserId, pendingUserId); - var pendingPost = await repository.Create(pendingPostToCreate); + var pendingPost = await repository.Create(pendingPostToCreate, cancellationToken); await producer.Send(EventType.RoomPendingCreated, pendingPost.Id); return pendingPost; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingRepository.cs index c81d308b..dee541ac 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Output; @@ -15,13 +16,15 @@ internal interface IPendingPostDeletingRepository /// Get pending post /// /// Identifier + /// /// - Task Get(Guid pendingPostId); + Task Get(Guid pendingPostId, CancellationToken cancellationToken); /// /// Delete pending post /// /// + /// /// - Task Delete(IUpdateBuilder updateBuilder); + Task Delete(IUpdateBuilder updateBuilder, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingService.cs index d8b5a820..ff46c01b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/IPendingPostDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Pending.Deleting; @@ -12,6 +13,7 @@ public interface IPendingPostDeletingService /// Delete existing pending /// /// Pending post identifier + /// /// - Task Delete(Guid pendingPostId); + Task Delete(Guid pendingPostId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingRepository.cs index 6aab89c2..b922d4ed 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,33 +13,21 @@ namespace DM.Services.Gaming.BusinessProcesses.Pending.Deleting; /// -internal class PendingPostDeletingRepository : IPendingPostDeletingRepository +internal class PendingPostDeletingRepository( + DmDbContext dbContext, + IMapper mapper) : IPendingPostDeletingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PendingPostDeletingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Get(Guid pendingPostId) - { - return dbContext.PendingPosts + public Task Get(Guid pendingPostId, CancellationToken cancellationToken) => + dbContext.PendingPosts .Where(p => p.PendingPostId == pendingPostId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); /// - public Task Delete(IUpdateBuilder updateBuilder) + public Task Delete(IUpdateBuilder updateBuilder, CancellationToken cancellationToken) { updateBuilder.AttachTo(dbContext); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingService.cs index fdf7bdf7..77115584 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Pending/Deleting/PendingPostDeletingService.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Core.Exceptions; @@ -10,33 +11,21 @@ namespace DM.Services.Gaming.BusinessProcesses.Pending.Deleting; /// -internal class PendingPostDeletingService : IPendingPostDeletingService +internal class PendingPostDeletingService( + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IPendingPostDeletingRepository repository) : IPendingPostDeletingService { - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IPendingPostDeletingRepository repository; - - /// - public PendingPostDeletingService( - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IPendingPostDeletingRepository repository) - { - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - } - /// - public async Task Delete(Guid pendingPostId) + public async Task Delete(Guid pendingPostId, CancellationToken cancellationToken) { - var pendingPost = await repository.Get(pendingPostId); + var pendingPost = await repository.Get(pendingPostId, cancellationToken); if (pendingPost == null) { throw new HttpException(HttpStatusCode.Gone, "Pending post not found"); } intentionManager.ThrowIfForbidden(RoomIntention.DeletePending, pendingPost); - await repository.Delete(updateBuilderFactory.Create(pendingPostId).Delete()); + await repository.Delete(updateBuilderFactory.Create(pendingPostId).Delete(), cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingRepository.cs index e36351e5..ef55164f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Output; @@ -17,6 +18,8 @@ internal interface IPostCreatingRepository /// /// Post DAL model /// Pending post changes + /// /// - Task Create(DbPost post, IEnumerable> pendingPostUpdates); + Task Create(DbPost post, IEnumerable> pendingPostUpdates, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingService.cs index 4878b2f4..ba8d39f5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/IPostCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IPostCreatingService /// Create new post /// /// DTO model + /// /// - Task Create(CreatePost createPost); + Task Create(CreatePost createPost, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingRepository.cs index ba56e434..16f4ecd7 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,22 +14,13 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Creating; /// -internal class PostCreatingRepository : IPostCreatingRepository +internal class PostCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IPostCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PostCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbPost post, IEnumerable> pendingPostUpdates) + public async Task Create( + DbPost post, IEnumerable> pendingPostUpdates, CancellationToken cancellationToken) { dbContext.Posts.Add(post); foreach (var pendingPostUpdate in pendingPostUpdates) @@ -36,10 +28,10 @@ public async Task Create(DbPost post, IEnumerable p.PostId == post.PostId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingService.cs index 03cee4a3..a11102db 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Creating/PostCreatingService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -20,47 +21,23 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Creating; /// -internal class PostCreatingService : IPostCreatingService +internal class PostCreatingService( + IValidator validator, + IRoomUpdatingRepository roomUpdatingRepository, + IIntentionManager intentionManager, + IPostFactory postFactory, + IUpdateBuilderFactory updateBuilderFactory, + IPostCreatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IPostCreatingService { - private readonly IValidator validator; - private readonly IRoomUpdatingRepository roomUpdatingRepository; - private readonly IIntentionManager intentionManager; - private readonly IPostFactory postFactory; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IPostCreatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public PostCreatingService( - IValidator validator, - IRoomUpdatingRepository roomUpdatingRepository, - IIntentionManager intentionManager, - IPostFactory postFactory, - IUpdateBuilderFactory updateBuilderFactory, - IPostCreatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.roomUpdatingRepository = roomUpdatingRepository; - this.intentionManager = intentionManager; - this.postFactory = postFactory; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Create(CreatePost createPost) + public async Task Create(CreatePost createPost, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createPost); + await validator.ValidateAndThrowAsync(createPost, cancellationToken); var identity = identityProvider.Current; - var room = await roomUpdatingRepository.GetRoom(createPost.RoomId, identity.User.UserId); + var room = await roomUpdatingRepository.GetRoom(createPost.RoomId, identity.User.UserId, cancellationToken); if (room == null) { throw new HttpException(HttpStatusCode.Gone, "Room not found"); @@ -81,8 +58,8 @@ public async Task Create(CreatePost createPost) var post = postFactory.Create(createPost, identity.User.UserId); - var createdPost = await repository.Create(post, pendingPostUpdates); - await unreadCountersRepository.Increment(createdPost.RoomId, UnreadEntryType.Message); + var createdPost = await repository.Create(post, pendingPostUpdates, cancellationToken); + await unreadCountersRepository.Increment(createdPost.RoomId, UnreadEntryType.Message, cancellationToken); await producer.Send(events, createdPost.Id); return createdPost; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/IPostDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/IPostDeletingService.cs index 1e1d32d4..244aada6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/IPostDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/IPostDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Posts.Deleting; @@ -12,6 +13,7 @@ public interface IPostDeletingService /// Delete existing post /// /// Post identifier + /// /// - Task Delete(Guid postId); + Task Delete(Guid postId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/PostDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/PostDeletingService.cs index d8fc3652..3c6e0cb5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/PostDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Deleting/PostDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -14,42 +15,25 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Deleting; /// -internal class PostDeletingService : IPostDeletingService +internal class PostDeletingService( + IPostReadingService postReadingService, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IPostUpdatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer) : IPostDeletingService { - private readonly IPostReadingService postReadingService; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IPostUpdatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - - /// - public PostDeletingService( - IPostReadingService postReadingService, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IPostUpdatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer) - { - this.postReadingService = postReadingService; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - } - /// - public async Task Delete(Guid postId) + public async Task Delete(Guid postId, CancellationToken cancellationToken) { - var post = await postReadingService.Get(postId); + var post = await postReadingService.Get(postId, cancellationToken); intentionManager.ThrowIfForbidden(PostIntention.Delete, post); var updateBuilder = updateBuilderFactory.Create(postId) .Field(p => p.IsRemoved, true); - await repository.Update(updateBuilder); - await unreadCountersRepository.Decrement(post.RoomId, UnreadEntryType.Message, post.CreateDate); + await repository.Update(updateBuilder,cancellationToken); + await unreadCountersRepository.Decrement( + post.RoomId, UnreadEntryType.Message, post.CreateDate, cancellationToken); await producer.Send(EventType.DeletedPost, postId); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingRepository.cs index 8f03fd43..e57da9ce 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Gaming.Dto.Output; @@ -16,8 +17,9 @@ internal interface IPostReadingRepository /// /// Room identifier /// User identifier + /// /// - Task Count(Guid roomId, Guid userId); + Task Count(Guid roomId, Guid userId, CancellationToken cancellationToken); /// /// Get room posts @@ -25,14 +27,16 @@ internal interface IPostReadingRepository /// Room identifier /// Paging data /// User identifier + /// /// - Task> Get(Guid roomId, PagingData paging, Guid userId); + Task> Get(Guid roomId, PagingData paging, Guid userId, CancellationToken cancellationToken); /// /// Get single room post /// /// Post identifier /// User identifier + /// /// - Task Get(Guid postId, Guid userId); + Task Get(Guid postId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingService.cs index e2c54945..528c28f2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/IPostReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Services.Gaming.Dto.Output; @@ -16,20 +17,24 @@ public interface IPostReadingService /// /// Room identifier /// Paging query + /// /// - Task<(IEnumerable posts, PagingResult paging)> Get(Guid roomId, PagingQuery query); + Task<(IEnumerable posts, PagingResult paging)> Get(Guid roomId, PagingQuery query, + CancellationToken cancellationToken); /// /// Get single existing post /// /// Post identifier + /// /// - Task Get(Guid postId); + Task Get(Guid postId, CancellationToken cancellationToken); /// /// Mark all posts in a room as read /// /// Room identifier + /// /// - Task MarkAsRead(Guid roomId); + Task MarkAsRead(Guid roomId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingRepository.cs index 57586c46..73737aae 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -14,35 +15,23 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Reading; /// -internal class PostReadingRepository : IPostReadingRepository +internal class PostReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IPostReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PostReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task Count(Guid roomId, Guid userId) - { - return dbContext.Rooms + public Task Count(Guid roomId, Guid userId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .Where(r => r.RoomId == roomId) .SelectMany(r => r.Posts) .Where(p => !p.IsRemoved) - .CountAsync(); - } + .CountAsync(cancellationToken); /// - public async Task> Get(Guid roomId, PagingData paging, Guid userId) - { - return await dbContext.Rooms + public async Task> Get(Guid roomId, PagingData paging, Guid userId, + CancellationToken cancellationToken) => + await dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .Where(r => r.RoomId == roomId) .SelectMany(r => r.Posts) @@ -50,17 +39,14 @@ public async Task> Get(Guid roomId, PagingData paging, Guid us .OrderBy(p => p.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public Task Get(Guid postId, Guid userId) - { - return dbContext.Rooms + public Task Get(Guid postId, Guid userId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(AccessibilityFilters.RoomAvailable(userId)) .SelectMany(r => r.Posts) .Where(p => !p.IsRemoved && p.PostId == postId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingService.cs index 5c3f96a9..d323a571 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Reading/PostReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -15,48 +16,33 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Reading; /// -internal class PostReadingService : IPostReadingService +internal class PostReadingService( + IRoomReadingService roomReadingService, + IIntentionManager intentionManager, + IPostReadingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IIdentityProvider identityProvider) : IPostReadingService { - private readonly IRoomReadingService roomReadingService; - private readonly IIntentionManager intentionManager; - private readonly IPostReadingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public PostReadingService( - IRoomReadingService roomReadingService, - IIntentionManager intentionManager, - IPostReadingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IIdentityProvider identityProvider) - { - this.roomReadingService = roomReadingService; - this.intentionManager = intentionManager; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.identityProvider = identityProvider; - } - /// - public async Task<(IEnumerable posts, PagingResult paging)> Get(Guid roomId, PagingQuery query) + public async Task<(IEnumerable posts, PagingResult paging)> Get( + Guid roomId, PagingQuery query, CancellationToken cancellationToken) { - var room = await roomReadingService.Get(roomId); + var room = await roomReadingService.Get(roomId, cancellationToken); intentionManager.ThrowIfForbidden(RoomIntention.CreatePost, room); var identity = identityProvider.Current; - var totalCount = await repository.Count(roomId, identity.User.UserId); + var totalCount = await repository.Count(roomId, identity.User.UserId, cancellationToken); var paging = new PagingData(query, identity.Settings.Paging.PostsPerPage, totalCount); - var posts = await repository.Get(roomId, paging, identity.User.UserId); + var posts = await repository.Get(roomId, paging, identity.User.UserId, cancellationToken); return (posts, paging.Result); } /// - public async Task Get(Guid postId) + public async Task Get(Guid postId, CancellationToken cancellationToken) { - var post = await repository.Get(postId, identityProvider.Current.User.UserId); + var post = await repository.Get(postId, identityProvider.Current.User.UserId, cancellationToken); if (post == null) { throw new HttpException(HttpStatusCode.Gone, "Post not found"); @@ -66,10 +52,10 @@ public async Task Get(Guid postId) } /// - public async Task MarkAsRead(Guid roomId) + public async Task MarkAsRead(Guid roomId, CancellationToken cancellationToken) { - await roomReadingService.Get(roomId); + await roomReadingService.Get(roomId, cancellationToken); await unreadCountersRepository.Flush(identityProvider.Current.User.UserId, - UnreadEntryType.Message, roomId); + UnreadEntryType.Message, roomId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingRepository.cs index 8ed35a91..d3e046b2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Output; @@ -14,6 +15,7 @@ internal interface IPostUpdatingRepository /// Update post /// /// Update post + /// /// - Task Update(IUpdateBuilder updatePost); + Task Update(IUpdateBuilder updatePost, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingService.cs index 0dfd1b7f..626a6016 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/IPostUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IPostUpdatingService /// Update existing post /// /// DTO for post updating + /// /// - Task Update(UpdatePost updatePost); + Task Update(UpdatePost updatePost, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingRepository.cs index fe8d3f1c..d12aab7b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,28 +12,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Updating; /// -internal class PostUpdatingRepository : IPostUpdatingRepository +internal class PostUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : IPostUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PostUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Update(IUpdateBuilder updatePost) + public async Task Update(IUpdateBuilder updatePost, CancellationToken cancellationToken) { var postId = updatePost.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Posts .Where(p => p.PostId == postId) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingService.cs index a09f58c3..7c20dce6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Posts/Updating/PostUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -17,48 +18,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Posts.Updating; /// -internal class PostUpdatingService : IPostUpdatingService +internal class PostUpdatingService( + IValidator validator, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IDateTimeProvider dateTimeProvider, + IPostReadingService postReadingService, + IRoomUpdatingRepository roomUpdatingRepository, + IPostUpdatingRepository repository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IPostUpdatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IDateTimeProvider dateTimeProvider; - private readonly IPostReadingService postReadingService; - private readonly IRoomUpdatingRepository roomUpdatingRepository; - private readonly IPostUpdatingRepository repository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public PostUpdatingService( - IValidator validator, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IDateTimeProvider dateTimeProvider, - IPostReadingService postReadingService, - IRoomUpdatingRepository roomUpdatingRepository, - IPostUpdatingRepository repository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.dateTimeProvider = dateTimeProvider; - this.postReadingService = postReadingService; - this.roomUpdatingRepository = roomUpdatingRepository; - this.repository = repository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Update(UpdatePost updatePost) + public async Task Update(UpdatePost updatePost, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updatePost); - var post = await postReadingService.Get(updatePost.PostId); + await validator.ValidateAndThrowAsync(updatePost, cancellationToken); + var post = await postReadingService.Get(updatePost.PostId, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; - var room = await roomUpdatingRepository.GetRoom(post.RoomId, currentUserId); + var room = await roomUpdatingRepository.GetRoom(post.RoomId, currentUserId, cancellationToken); var updateBuilder = updateBuilderFactory.Create(updatePost.PostId); @@ -88,7 +65,7 @@ public async Task Update(UpdatePost updatePost) .Field(p => p.LastUpdateUserId, currentUserId); } - var updatedPost = await repository.Update(updateBuilder); + var updatedPost = await repository.Update(updateBuilder, cancellationToken); await producer.Send(EventType.ChangedPost, post.Id); return updatedPost; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingRepository.cs index c00b252c..1bc577cc 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -15,6 +16,7 @@ internal interface IReadersReadingRepository /// /// Game identifier /// User identifier + /// /// - Task> Get(Guid gameId, Guid userId); + Task> Get(Guid gameId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingService.cs index 32b1a7db..9018da00 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/IReadersReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -14,6 +15,7 @@ public interface IReadersReadingService /// Get all game readers /// /// Game identifiers + /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingRepository.cs index bedcc6ae..60e3afc9 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -11,27 +12,15 @@ namespace DM.Services.Gaming.BusinessProcesses.Readers.Reading; /// -internal class ReadersReadingRepository : IReadersReadingRepository +internal class ReadersReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IReadersReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public ReadersReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task> Get(Guid gameId, Guid userId) - { - return await dbContext.Readers + public async Task> Get(Guid gameId, Guid userId, CancellationToken cancellationToken) => + await dbContext.Readers .Where(r => r.GameId == gameId) .Select(g => g.User) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingService.cs index ef110e02..9aa4674f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Reading/ReadersReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Dto; @@ -8,27 +9,15 @@ namespace DM.Services.Gaming.BusinessProcesses.Readers.Reading; /// -internal class ReadersReadingService : IReadersReadingService +internal class ReadersReadingService( + IGameReadingService gameReadingService, + IReadersReadingRepository repository, + IIdentityProvider identityProvider) : IReadersReadingService { - private readonly IGameReadingService gameReadingService; - private readonly IReadersReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public ReadersReadingService( - IGameReadingService gameReadingService, - IReadersReadingRepository repository, - IIdentityProvider identityProvider) - { - this.gameReadingService = gameReadingService; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task> Get(Guid gameId) + public async Task> Get(Guid gameId, CancellationToken cancellationToken) { - await gameReadingService.GetGame(gameId); - return await repository.Get(gameId, identityProvider.Current.User.UserId); + await gameReadingService.GetGame(gameId, cancellationToken); + return await repository.Get(gameId, identityProvider.Current.User.UserId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingRepository.cs index 329dffb3..e506e35b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Games.Links; @@ -14,21 +15,24 @@ internal interface IReadingSubscribingRepository /// /// User identifier /// Game identifier + /// /// - Task HasSubscription(Guid userId, Guid gameId); + Task HasSubscription(Guid userId, Guid gameId, CancellationToken cancellationToken); /// /// Store game subscription /// /// + /// /// - Task Add(Reader reader); + Task Add(Reader reader, CancellationToken cancellationToken); /// /// Remove stored subscription /// /// /// + /// /// - Task Delete(Guid userId, Guid gameId); + Task Delete(Guid userId, Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingService.cs index 3135520d..a905c96b 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/IReadingSubscribingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; @@ -13,13 +14,15 @@ public interface IReadingSubscribingService /// Subscribe to a game /// /// Game identifier + /// /// - Task Subscribe(Guid gameId); + Task Subscribe(Guid gameId, CancellationToken cancellationToken); /// /// Unsubscribe from a game /// /// Game identifier + /// /// - Task Unsubscribe(Guid gameId); + Task Unsubscribe(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingRepository.cs index 523fd015..c1df7498 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Games.Links; @@ -7,33 +8,26 @@ namespace DM.Services.Gaming.BusinessProcesses.Readers.Subscribing; /// -internal class ReadingSubscribingRepository : IReadingSubscribingRepository +internal class ReadingSubscribingRepository( + DmDbContext dbContext) : IReadingSubscribingRepository { - private readonly DmDbContext dbContext; - - /// - public ReadingSubscribingRepository( - DmDbContext dbContext) - { - this.dbContext = dbContext; - } - /// - public Task HasSubscription(Guid userId, Guid gameId) => - dbContext.Readers.AnyAsync(r => r.UserId == userId && r.GameId == gameId); + public Task HasSubscription(Guid userId, Guid gameId, CancellationToken cancellationToken) => + dbContext.Readers.AnyAsync(r => r.UserId == userId && r.GameId == gameId, cancellationToken); /// - public Task Add(Reader reader) + public Task Add(Reader reader, CancellationToken cancellationToken) { dbContext.Readers.Add(reader); - return dbContext.SaveChangesAsync(); + return dbContext.SaveChangesAsync(cancellationToken); } /// - public async Task Delete(Guid userId, Guid gameId) + public async Task Delete(Guid userId, Guid gameId, CancellationToken cancellationToken) { - var reader = await dbContext.Readers.FirstAsync(r => r.GameId == gameId && r.UserId == userId); + var reader = await dbContext.Readers + .FirstAsync(r => r.GameId == gameId && r.UserId == userId, cancellationToken); dbContext.Readers.Remove(reader); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingService.cs index eeb92b87..2d61fd25 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Readers/Subscribing/ReadingSubscribingService.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -11,61 +12,45 @@ namespace DM.Services.Gaming.BusinessProcesses.Readers.Subscribing; /// -internal class ReadingSubscribingService : IReadingSubscribingService +internal class ReadingSubscribingService( + IIdentityProvider identityProvider, + IGameReadingService gameReadingService, + IReaderFactory readerFactory, + IReadingSubscribingRepository repository, + IIntentionManager intentionManager) : IReadingSubscribingService { - private readonly IGameReadingService gameReadingService; - private readonly IReaderFactory readerFactory; - private readonly IReadingSubscribingRepository repository; - private readonly IIntentionManager intentionManager; - private readonly IIdentityProvider identityProvider; - - /// - public ReadingSubscribingService( - IIdentityProvider identityProvider, - IGameReadingService gameReadingService, - IReaderFactory readerFactory, - IReadingSubscribingRepository repository, - IIntentionManager intentionManager) - { - this.gameReadingService = gameReadingService; - this.readerFactory = readerFactory; - this.repository = repository; - this.intentionManager = intentionManager; - this.identityProvider = identityProvider; - } - /// - public async Task Subscribe(Guid gameId) + public async Task Subscribe(Guid gameId, CancellationToken cancellationToken) { intentionManager.ThrowIfForbidden(GameIntention.Subscribe); - var game = await gameReadingService.GetGame(gameId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Subscribe, game); var identity = identityProvider.Current; var userId = identity.User.UserId; - if (await repository.HasSubscription(userId, gameId)) + if (await repository.HasSubscription(userId, gameId, cancellationToken)) { throw new HttpException(HttpStatusCode.Conflict, "User already subscribed to this game"); } var reader = readerFactory.Create(userId, gameId); - await repository.Add(reader); + await repository.Add(reader, cancellationToken); return identity.User; } /// - public async Task Unsubscribe(Guid gameId) + public async Task Unsubscribe(Guid gameId, CancellationToken cancellationToken) { intentionManager.ThrowIfForbidden(GameIntention.Subscribe); - var game = await gameReadingService.GetGame(gameId); + var game = await gameReadingService.GetGame(gameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Unsubscribe, game); var userId = identityProvider.Current.User.UserId; - if (!await repository.HasSubscription(userId, gameId)) + if (!await repository.HasSubscription(userId, gameId, cancellationToken)) { throw new HttpException(HttpStatusCode.Conflict, "User is not subscribed to this game"); } - await repository.Delete(userId, gameId); + await repository.Delete(userId, gameId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingRepository.cs index b28c07ca..4776977f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Internal; @@ -17,13 +18,15 @@ internal interface IRoomCreatingRepository /// /// /// + /// /// - Task Create(DbRoom room, IUpdateBuilder updateLastRoom); + Task Create(DbRoom room, IUpdateBuilder updateLastRoom, CancellationToken cancellationToken); /// /// Find last room in game /// /// Game identifier + /// /// - Task GetLastRoomInfo(Guid gameId); + Task GetLastRoomInfo(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingService.cs index 10b9fd76..f8d478cc 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/IRoomCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IRoomCreatingService /// Create new room /// /// DTO for room creating + /// /// - Task Create(CreateRoom createRoom); + Task Create(CreateRoom createRoom, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingRepository.cs index df0ac57e..80e413ae 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,40 +14,29 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Creating; /// -internal class RoomCreatingRepository : IRoomCreatingRepository +internal class RoomCreatingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomCreatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbRoom room, IUpdateBuilder updateLastRoom) + public async Task Create(DbRoom room, IUpdateBuilder updateLastRoom, + CancellationToken cancellationToken) { dbContext.Rooms.Add(room); updateLastRoom?.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Rooms .Where(r => r.RoomId == room.RoomId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } /// - public Task GetLastRoomInfo(Guid gameId) - { - return dbContext.Rooms + public Task GetLastRoomInfo(Guid gameId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(r => !r.IsRemoved && r.GameId == gameId) .OrderByDescending(r => r.OrderNumber) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingService.cs index 677af1d1..0e5a2b1a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Creating/RoomCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -15,46 +16,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Creating; /// -internal class RoomCreatingService : IRoomCreatingService +internal class RoomCreatingService( + IGameReadingService gameReadingService, + IValidator validator, + IIntentionManager intentionManager, + IRoomFactory roomFactory, + IUpdateBuilderFactory updateBuilderFactory, + IRoomCreatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer) : IRoomCreatingService { - private readonly IGameReadingService gameReadingService; - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IRoomFactory roomFactory; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IRoomCreatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - - /// - public RoomCreatingService( - IGameReadingService gameReadingService, - IValidator validator, - IIntentionManager intentionManager, - IRoomFactory roomFactory, - IUpdateBuilderFactory updateBuilderFactory, - IRoomCreatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer) - { - this.gameReadingService = gameReadingService; - this.validator = validator; - this.intentionManager = intentionManager; - this.roomFactory = roomFactory; - this.updateBuilderFactory = updateBuilderFactory; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - } - /// - public async Task Create(CreateRoom createRoom) + public async Task Create(CreateRoom createRoom, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(createRoom); - var game = await gameReadingService.GetGame(createRoom.GameId); + await validator.ValidateAndThrowAsync(createRoom, cancellationToken); + var game = await gameReadingService.GetGame(createRoom.GameId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, game); - var lastRoom = await repository.GetLastRoomInfo(createRoom.GameId); + var lastRoom = await repository.GetLastRoomInfo(createRoom.GameId, cancellationToken); var roomToCreate = lastRoom == null ? roomFactory.CreateFirst(createRoom) @@ -63,8 +42,8 @@ public async Task Create(CreateRoom createRoom) ? null : updateBuilderFactory.Create(lastRoom.Id).Field(r => r.NextRoomId, roomToCreate.RoomId); - var room = await repository.Create(roomToCreate, updateLastRoom); - await unreadCountersRepository.Create(room.Id, game.Id, UnreadEntryType.Message); + var room = await repository.Create(roomToCreate, updateLastRoom, cancellationToken); + await unreadCountersRepository.Create(room.Id, game.Id, UnreadEntryType.Message, cancellationToken); await producer.Send(EventType.NewRoom, room.Id); return room; diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/IRoomDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/IRoomDeletingService.cs index 609f5876..a9f12ae6 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/IRoomDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/IRoomDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Rooms.Deleting; @@ -12,6 +13,7 @@ public interface IRoomDeletingService /// Delete existing room /// /// Room identifier + /// /// - Task Delete(Guid roomId); + Task Delete(Guid roomId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/RoomDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/RoomDeletingService.cs index e1ce8ac5..122546c8 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/RoomDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Deleting/RoomDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -14,46 +15,27 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Deleting; /// -internal class RoomDeletingService : IRoomDeletingService +internal class RoomDeletingService( + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IRoomOrderPull roomOrderPull, + IRoomUpdatingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IInvokedEventProducer producer, + IIdentityProvider identityProvider) : IRoomDeletingService { - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IRoomOrderPull roomOrderPull; - private readonly IRoomUpdatingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IInvokedEventProducer producer; - private readonly IIdentityProvider identityProvider; - - /// - public RoomDeletingService( - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IRoomOrderPull roomOrderPull, - IRoomUpdatingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IInvokedEventProducer producer, - IIdentityProvider identityProvider) - { - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.roomOrderPull = roomOrderPull; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.producer = producer; - this.identityProvider = identityProvider; - } - /// - public async Task Delete(Guid roomId) + public async Task Delete(Guid roomId, CancellationToken cancellationToken) { - var room = await repository.GetRoom(roomId, identityProvider.Current.User.UserId); + var room = await repository.GetRoom(roomId, identityProvider.Current.User.UserId, cancellationToken); intentionManager.ThrowIfForbidden(GameIntention.Edit, room.Game); var updateRoom = updateBuilderFactory.Create(roomId).Field(r => r.IsRemoved, true); var (updateOldPreviousRoom, updateOldNextRoom) = roomOrderPull.GetPullChanges(room); - await repository.Update(updateRoom, updateOldNextRoom, updateOldPreviousRoom); - await unreadCountersRepository.Delete(roomId, UnreadEntryType.Message); + await repository.Update(updateRoom, updateOldNextRoom, updateOldPreviousRoom, + null, null, cancellationToken); + await unreadCountersRepository.Delete(roomId, UnreadEntryType.Message, cancellationToken); await producer.Send(EventType.DeletedRoom, roomId); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingRepository.cs index 80a3a9e9..1c021471 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -15,14 +16,16 @@ internal interface IRoomReadingRepository /// /// Game identifier /// Authenticated user identifier + /// /// - Task> GetAllAvailable(Guid gameId, Guid userId); + Task> GetAllAvailable(Guid gameId, Guid userId, CancellationToken cancellationToken); /// /// Get single existing available room /// /// Room identifier /// User identifier + /// /// - Task GetAvailable(Guid roomId, Guid userId); + Task GetAvailable(Guid roomId, Guid userId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingService.cs index da806b95..8d46be13 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/IRoomReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Output; @@ -14,13 +15,15 @@ public interface IRoomReadingService /// Get all available game rooms /// /// Game identifier + /// /// - Task> GetAll(Guid gameId); + Task> GetAll(Guid gameId, CancellationToken cancellationToken); /// /// Get single existing room /// /// Room identifier + /// /// - Task Get(Guid roomId); + Task Get(Guid roomId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingRepository.cs index c45969ec..d53eb117 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -12,38 +13,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Reading; /// -internal class RoomReadingRepository : IRoomReadingRepository +internal class RoomReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomReadingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task> GetAllAvailable(Guid gameId, Guid userId) - { - return await dbContext.Rooms + public async Task> GetAllAvailable(Guid gameId, Guid userId, CancellationToken cancellationToken) => + await dbContext.Rooms .Where(r => r.GameId == gameId) .Where(AccessibilityFilters.RoomAvailable(userId)) .OrderBy(r => r.OrderNumber) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); /// - public Task GetAvailable(Guid roomId, Guid userId) - { - return dbContext.Rooms + public Task GetAvailable(Guid roomId, Guid userId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(r => r.RoomId == roomId) .Where(AccessibilityFilters.RoomAvailable(userId)) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingService.cs index 96ef0b55..4af2bba5 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Reading/RoomReadingService.cs @@ -2,60 +2,48 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.BusinessProcesses.UnreadCounters; using DM.Services.Common.Extensions; using DM.Services.Core.Exceptions; +using DM.Services.DataAccess.BusinessObjects.Common; using DM.Services.Gaming.BusinessProcesses.Games.Reading; using DM.Services.Gaming.Dto.Output; namespace DM.Services.Gaming.BusinessProcesses.Rooms.Reading; /// -internal class RoomReadingService : IRoomReadingService +internal class RoomReadingService( + IGameReadingService gameReadingService, + IRoomReadingRepository repository, + IUnreadCountersRepository unreadCountersRepository, + IIdentityProvider identityProvider) : IRoomReadingService { - private readonly IGameReadingService gameReadingService; - private readonly IRoomReadingRepository repository; - private readonly IUnreadCountersRepository unreadCountersRepository; - private readonly IIdentityProvider identityProvider; - - /// - public RoomReadingService( - IGameReadingService gameReadingService, - IRoomReadingRepository repository, - IUnreadCountersRepository unreadCountersRepository, - IIdentityProvider identityProvider) - { - this.gameReadingService = gameReadingService; - this.repository = repository; - this.unreadCountersRepository = unreadCountersRepository; - this.identityProvider = identityProvider; - } - /// - public async Task> GetAll(Guid gameId) + public async Task> GetAll(Guid gameId, CancellationToken cancellationToken) { - await gameReadingService.GetGame(gameId); + await gameReadingService.GetGame(gameId, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; - var rooms = (await repository.GetAllAvailable(gameId, currentUserId)).ToArray(); + var rooms = (await repository.GetAllAvailable(gameId, currentUserId, cancellationToken)).ToArray(); await unreadCountersRepository.FillEntityCounters(rooms, currentUserId, - r => r.Id, r => r.UnreadPostsCount); + r => r.Id, r => r.UnreadPostsCount, UnreadEntryType.Message, cancellationToken); return rooms; } /// - public async Task Get(Guid roomId) + public async Task Get(Guid roomId, CancellationToken cancellationToken) { var currentUserId = identityProvider.Current.User.UserId; - var room = await repository.GetAvailable(roomId, currentUserId); + var room = await repository.GetAvailable(roomId, currentUserId, cancellationToken); if (room == null) { throw new HttpException(HttpStatusCode.Gone, "Room not found"); } await unreadCountersRepository.FillEntityCounters(new[] {room}, currentUserId, - r => r.Id, r => r.UnreadPostsCount); + r => r.Id, r => r.UnreadPostsCount, UnreadEntryType.Message, cancellationToken); return room; } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingRepository.cs index 1fef61cd..35d55b7c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.RelationalStorage; using DM.Services.Gaming.Dto.Internal; @@ -17,36 +18,40 @@ internal interface IRoomUpdatingRepository /// /// Room identifier /// User identifier + /// /// - Task GetRoom(Guid roomId, Guid userId); + Task GetRoom(Guid roomId, Guid userId, CancellationToken cancellationToken); /// /// Get room neighbours /// /// + /// /// - Task GetNeighbours(Guid roomId); + Task GetNeighbours(Guid roomId, CancellationToken cancellationToken); /// /// Update room and its neighbours /// /// - /// /// - /// + /// /// + /// + /// /// - Task Update( - IUpdateBuilder updateRoom, - IUpdateBuilder updateOldNextRoom = null, - IUpdateBuilder updateOldPreviousRoom = null, - IUpdateBuilder updateNewNextRoom = null, - IUpdateBuilder updateNewPreviousRoom = null); + Task Update(IUpdateBuilder updateRoom, + IUpdateBuilder updateOldNextRoom, + IUpdateBuilder updateOldPreviousRoom, + IUpdateBuilder updateNewNextRoom, + IUpdateBuilder updateNewPreviousRoom, + CancellationToken cancellationToken); /// /// Get first room of the game order info /// /// Game identifier + /// /// - Task GetFirstRoomInfo(Guid gameId); + Task GetFirstRoomInfo(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingService.cs index 852a4e6d..8ca9fb1f 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/IRoomUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Input; using DM.Services.Gaming.Dto.Output; @@ -13,6 +14,7 @@ public interface IRoomUpdatingService /// Update existing room /// /// DTO for room updating + /// /// - Task Update(UpdateRoom updateRoom); + Task Update(UpdateRoom updateRoom, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingRepository.cs index 412aaff3..f49bda34 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -14,38 +15,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Updating; /// -internal class RoomUpdatingRepository : IRoomUpdatingRepository +internal class RoomUpdatingRepository( + DmDbContext dbContext, + IMapper mapper) : IRoomUpdatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public RoomUpdatingRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public Task GetRoom(Guid roomId, Guid userId) - { - return dbContext.Rooms + public Task GetRoom(Guid roomId, Guid userId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(r => r.RoomId == roomId) .Where(AccessibilityFilters.RoomAvailable(userId)) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); /// - public Task GetNeighbours(Guid roomId) - { - return dbContext.Rooms + public Task GetNeighbours(Guid roomId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(r => r.RoomId == roomId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); - } + .FirstAsync(cancellationToken); /// public async Task Update( @@ -53,29 +40,28 @@ public async Task Update( IUpdateBuilder updateOldPreviousRoom, IUpdateBuilder updateOldNextRoom, IUpdateBuilder updateNewPreviousRoom, - IUpdateBuilder updateNewNextRoom) + IUpdateBuilder updateNewNextRoom, + CancellationToken cancellationToken) { var roomId = updateRoom.AttachTo(dbContext); updateOldPreviousRoom?.AttachTo(dbContext); updateOldNextRoom?.AttachTo(dbContext); updateNewPreviousRoom?.AttachTo(dbContext); updateNewNextRoom?.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Rooms .Where(r => r.RoomId == roomId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } /// - public Task GetFirstRoomInfo(Guid gameId) - { - return dbContext.Rooms + public Task GetFirstRoomInfo(Guid gameId, CancellationToken cancellationToken) => + dbContext.Rooms .Where(r => !r.IsRemoved && r.GameId == gameId) .OrderBy(r => r.OrderNumber) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingService.cs index 66697f2a..b3a97c38 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Rooms/Updating/RoomUpdatingService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -15,38 +16,20 @@ namespace DM.Services.Gaming.BusinessProcesses.Rooms.Updating; /// -internal class RoomUpdatingService : IRoomUpdatingService +internal class RoomUpdatingService( + IValidator validator, + IIntentionManager intentionManager, + IUpdateBuilderFactory updateBuilderFactory, + IRoomOrderPull roomOrderPull, + IRoomUpdatingRepository repository, + IIdentityProvider identityProvider) : IRoomUpdatingService { - private readonly IValidator validator; - private readonly IIntentionManager intentionManager; - private readonly IUpdateBuilderFactory updateBuilderFactory; - private readonly IRoomOrderPull roomOrderPull; - private readonly IRoomUpdatingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public RoomUpdatingService( - IValidator validator, - IIntentionManager intentionManager, - IUpdateBuilderFactory updateBuilderFactory, - IRoomOrderPull roomOrderPull, - IRoomUpdatingRepository repository, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.updateBuilderFactory = updateBuilderFactory; - this.roomOrderPull = roomOrderPull; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task Update(UpdateRoom updateRoom) + public async Task Update(UpdateRoom updateRoom, CancellationToken cancellationToken) { - await validator.ValidateAndThrowAsync(updateRoom); + await validator.ValidateAndThrowAsync(updateRoom, cancellationToken); var currentUserId = identityProvider.Current.User.UserId; - var room = await repository.GetRoom(updateRoom.RoomId, currentUserId); + var room = await repository.GetRoom(updateRoom.RoomId, currentUserId, cancellationToken); if (room == null) { throw new HttpException(HttpStatusCode.Gone, "Room not found"); @@ -61,15 +44,17 @@ public async Task Update(UpdateRoom updateRoom) if (updateRoom.PreviousRoomId == null || updateRoom.PreviousRoomId.Value == room.PreviousRoomId) { - return await repository.Update(roomUpdate); + return await repository.Update(roomUpdate, + null, null, null, null, cancellationToken); } if (!updateRoom.PreviousRoomId.Value.HasValue) { - return await InsertFirst(room, roomUpdate); + return await InsertFirst(room, roomUpdate, cancellationToken); } - var targetRoom = await repository.GetRoom(updateRoom.PreviousRoomId.Value.Value, currentUserId); + var targetRoom = await repository.GetRoom( + updateRoom.PreviousRoomId.Value.Value, currentUserId, cancellationToken); if (targetRoom.Game.Id != room.Game.Id) { throw new HttpBadRequestException(new Dictionary @@ -78,11 +63,11 @@ public async Task Update(UpdateRoom updateRoom) }); } - return await InsertAfter(room, targetRoom, roomUpdate); + return await InsertAfter(room, targetRoom, roomUpdate, cancellationToken); } private async Task InsertAfter(RoomToUpdate room, RoomToUpdate afterRoom, - IUpdateBuilder updateRoom) + IUpdateBuilder updateRoom, CancellationToken cancellationToken) { var (updateOldPreviousRoom, updateOldNextRoom) = roomOrderPull.GetPullChanges(room); var updateNewPreviousRoom = updateBuilderFactory.Create(afterRoom.Id) @@ -101,19 +86,25 @@ private async Task InsertAfter(RoomToUpdate room, RoomToUpdate afterRoom, : afterRoom.OrderNumber + 1); return await repository.Update(updateRoom, - updateOldNextRoom, updateOldPreviousRoom, updateNewNextRoom, updateNewPreviousRoom); + updateOldNextRoom, updateOldPreviousRoom, + updateNewNextRoom, updateNewPreviousRoom, + cancellationToken); } - private async Task InsertFirst(RoomToUpdate room, IUpdateBuilder updateRoom) + private async Task InsertFirst(RoomToUpdate room, IUpdateBuilder updateRoom, + CancellationToken cancellationToken) { var (updateOldPreviousRoom, updateOldNextRoom) = roomOrderPull.GetPullChanges(room); - var firstRoomInfo = await repository.GetFirstRoomInfo(room.Game.Id); + var firstRoomInfo = await repository.GetFirstRoomInfo(room.Game.Id, cancellationToken); var updateNewNextRoom = updateBuilderFactory.Create(firstRoomInfo.Id) .Field(r => r.PreviousRoomId, room.Id); updateRoom .Field(r => r.NextRoomId, firstRoomInfo.Id) .Field(r => r.OrderNumber, firstRoomInfo.OrderNumber - 1); - return await repository.Update(updateRoom, updateOldNextRoom, updateOldPreviousRoom, updateNewNextRoom); + return await repository.Update(updateRoom, + updateOldNextRoom, updateOldPreviousRoom, + updateNewNextRoom, null, + cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingRepository.cs index d5ab1266..fcbb588a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Shared; using DbAttributeSchema = DM.Services.DataAccess.BusinessObjects.Games.Characters.Attributes.AttributeSchema; @@ -13,5 +14,5 @@ internal interface ISchemaCreatingRepository /// Create new attribute schema /// /// - Task Create(DbAttributeSchema schema); + Task Create(DbAttributeSchema schema, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingService.cs index c743adc4..93b6389e 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/ISchemaCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Shared; @@ -12,6 +13,7 @@ public interface ISchemaCreatingService /// Create new attribute schema /// /// DTO for creating + /// /// - Task Create(AttributeSchema attributeSchema); + Task Create(AttributeSchema attributeSchema, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingRepository.cs index 9da0a375..8907b87c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingRepository.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -13,28 +14,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Creating; /// -internal class SchemaCreatingRepository : MongoCollectionRepository, ISchemaCreatingRepository +internal class SchemaCreatingRepository( + DmMongoClient client, + DmDbContext dbContext, + IMapper mapper) : MongoCollectionRepository(client), ISchemaCreatingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public SchemaCreatingRepository( - DmMongoClient client, - DmDbContext dbContext, - IMapper mapper) : base(client) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - /// - public async Task Create(DbAttributeSchema schema) + public async Task Create(DbAttributeSchema schema, CancellationToken cancellationToken) { - await Collection.InsertOneAsync(schema); + await Collection.InsertOneAsync(schema, cancellationToken: cancellationToken); var createdSchema = await Collection .Find(Filter.Eq(s => s.Id, schema.Id)) - .FirstAsync(); + .FirstAsync(cancellationToken); var result = mapper.Map(createdSchema); if (createdSchema.UserId.HasValue) @@ -42,7 +33,7 @@ public async Task Create(DbAttributeSchema schema) var author = await dbContext.Users .Where(u => u.UserId == createdSchema.UserId.Value) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); result.Author = author; } diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingService.cs index 5bc2f06d..d6f22363 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Creating/SchemaCreatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Common.Authorization; @@ -7,36 +8,20 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Creating; /// -internal class SchemaCreatingService : ISchemaCreatingService +internal class SchemaCreatingService( + ISchemaCreatingValidator validator, + IIntentionManager intentionManager, + ISchemaFactory factory, + ISchemaCreatingRepository repository, + IIdentityProvider identityProvider) : ISchemaCreatingService { - private readonly ISchemaCreatingValidator validator; - private readonly IIntentionManager intentionManager; - private readonly ISchemaFactory factory; - private readonly ISchemaCreatingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public SchemaCreatingService( - ISchemaCreatingValidator validator, - IIntentionManager intentionManager, - ISchemaFactory factory, - ISchemaCreatingRepository repository, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.intentionManager = intentionManager; - this.factory = factory; - this.repository = repository; - this.identityProvider = identityProvider; - } - /// - public async Task Create(AttributeSchema attributeSchema) + public async Task Create(AttributeSchema attributeSchema, CancellationToken cancellationToken) { validator.ValidateAndThrow(attributeSchema); intentionManager.ThrowIfForbidden(GameIntention.Create); var schemaToCreate = factory.CreateNew(attributeSchema, identityProvider.Current.User.UserId); - return await repository.Create(schemaToCreate); + return await repository.Create(schemaToCreate, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingRepository.cs index 6d1a197a..eb73113c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Schemas.Deleting; @@ -12,6 +13,7 @@ internal interface ISchemaDeletingRepository /// Delete existing attribute schema /// /// Schema identifier + /// /// - Task Delete(Guid schemaId); + Task Delete(Guid schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingService.cs index 2a398388..777c1648 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/ISchemaDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace DM.Services.Gaming.BusinessProcesses.Schemas.Deleting; @@ -12,6 +13,7 @@ public interface ISchemaDeletingService /// Delete existing attribute schema /// /// Attribute schema identifier + /// /// - Task Delete(Guid schemaId); + Task Delete(Guid schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingRepository.cs index 5774c66a..e055674a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.BusinessObjects.Games.Characters.Attributes; using DM.Services.DataAccess.MongoIntegration; @@ -6,13 +7,10 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Deleting; /// -internal class SchemaDeletingRepository : MongoCollectionRepository, ISchemaDeletingRepository +internal class SchemaDeletingRepository(DmMongoClient client) + : MongoCollectionRepository(client), ISchemaDeletingRepository { /// - public SchemaDeletingRepository(DmMongoClient client) : base(client) - { - } - - /// - public async Task Delete(Guid schemaId) => await Collection.DeleteOneAsync(Filter.Eq(s => s.Id, schemaId)); + public async Task Delete(Guid schemaId, CancellationToken cancellationToken) => + await Collection.DeleteOneAsync(Filter.Eq(s => s.Id, schemaId), cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingService.cs index e866bb75..11d8ecca 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Deleting/SchemaDeletingService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Gaming.Authorization; @@ -7,28 +8,16 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Deleting; /// -internal class SchemaDeletingService : ISchemaDeletingService +internal class SchemaDeletingService( + ISchemaReadingService readingService, + IIntentionManager intentionManager, + ISchemaDeletingRepository repository) : ISchemaDeletingService { - private readonly ISchemaReadingService readingService; - private readonly IIntentionManager intentionManager; - private readonly ISchemaDeletingRepository repository; - - /// - public SchemaDeletingService( - ISchemaReadingService readingService, - IIntentionManager intentionManager, - ISchemaDeletingRepository repository) - { - this.readingService = readingService; - this.intentionManager = intentionManager; - this.repository = repository; - } - /// - public async Task Delete(Guid schemaId) + public async Task Delete(Guid schemaId, CancellationToken cancellationToken) { - var schema = await readingService.Get(schemaId); + var schema = await readingService.Get(schemaId, cancellationToken); intentionManager.ThrowIfForbidden(AttributeSchemaIntention.Delete, schema); - await repository.Delete(schemaId); + await repository.Delete(schemaId, cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingRepository.cs index 2dd38fc1..84bac2e4 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Shared; @@ -14,13 +15,15 @@ internal interface ISchemaReadingRepository /// Get list of available schemas /// /// User identifier + /// /// - Task> GetSchemata(Guid userId); + Task> GetSchemata(Guid userId, CancellationToken cancellationToken); /// /// Get certain attribute schema /// /// Schema identifier + /// /// - Task GetSchema(Guid schemaId); + Task GetSchema(Guid schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingService.cs index 126e8190..94462be2 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/ISchemaReadingService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Shared; @@ -13,13 +14,15 @@ public interface ISchemaReadingService /// /// Get list of available schemas /// + /// /// - Task> Get(); + Task> Get(CancellationToken cancellationToken); /// /// Get certain attribute schema /// /// Schema identifier + /// /// - Task Get(Guid schemaId); + Task Get(Guid schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingRepository.cs index a9348123..6f79cb57 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -16,29 +17,18 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Reading; /// -internal class SchemaReadingRepository : - MongoCollectionRepository, - ISchemaReadingRepository +internal class SchemaReadingRepository( + DmDbContext dbContext, + DmMongoClient client, + IMapper mapper) + : MongoCollectionRepository(client), ISchemaReadingRepository { - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - /// - public SchemaReadingRepository( - DmDbContext dbContext, - DmMongoClient client, - IMapper mapper) : base(client) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - - /// - public async Task> GetSchemata(Guid userId) + public async Task> GetSchemata(Guid userId, CancellationToken cancellationToken) { var schemata = await Collection .Find(Filter.Eq(s => s.Type, SchemaType.Public) | Filter.Eq(s => s.UserId, userId)) - .ToListAsync(); + .ToListAsync(cancellationToken); if (!schemata.Any()) { @@ -49,7 +39,7 @@ public async Task> GetSchemata(Guid userId) .Where(s => s.UserId.HasValue) .Select(s => s.UserId.Value) .ToHashSet(); - var authors = (await GetSchemataAuthors(authorIds)).ToDictionary(u => u.UserId); + var authors = (await GetSchemataAuthors(authorIds, cancellationToken)).ToDictionary(u => u.UserId); var result = new List(schemata.Count); foreach (var schema in schemata) @@ -66,11 +56,11 @@ public async Task> GetSchemata(Guid userId) } /// - public async Task GetSchema(Guid schemaId) + public async Task GetSchema(Guid schemaId, CancellationToken cancellationToken) { var schema = await Collection .Find(Filter.Eq(s => s.Id, schemaId)) - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(cancellationToken); if (schema == null) { @@ -80,18 +70,17 @@ public async Task GetSchema(Guid schemaId) var result = mapper.Map(schema); if (schema.UserId.HasValue) { - result.Author = (await GetSchemataAuthors(new[] {schema.UserId.Value})).First(); + result.Author = (await GetSchemataAuthors(new[] {schema.UserId.Value}, cancellationToken)).First(); } return result; } /// - private async Task> GetSchemataAuthors(ICollection userIds) - { - return await dbContext.Users + private async Task> GetSchemataAuthors( + ICollection userIds, CancellationToken cancellationToken) => + await dbContext.Users .Where(u => userIds.Contains(u.UserId)) .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(); - } + .ToArrayAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingService.cs index 02ec1023..b80c737c 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Reading/SchemaReadingService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Exceptions; @@ -9,28 +10,19 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Reading; /// -internal class SchemaReadingService : ISchemaReadingService +internal class SchemaReadingService( + ISchemaReadingRepository repository, + IIdentityProvider identityProvider) : ISchemaReadingService { - private readonly ISchemaReadingRepository repository; - private readonly IIdentityProvider identityProvider; - - /// - public SchemaReadingService( - ISchemaReadingRepository repository, - IIdentityProvider identityProvider) - { - this.repository = repository; - this.identityProvider = identityProvider; - } - + /// /// - public async Task> Get() => - await repository.GetSchemata(identityProvider.Current.User.UserId); + public async Task> Get(CancellationToken cancellationToken) => + await repository.GetSchemata(identityProvider.Current.User.UserId, cancellationToken); /// - public async Task Get(Guid schemaId) + public async Task Get(Guid schemaId, CancellationToken cancellationToken) { - var attributeSchema = await repository.GetSchema(schemaId); + var attributeSchema = await repository.GetSchema(schemaId, cancellationToken); if (attributeSchema == null) { throw new HttpException(HttpStatusCode.Gone, "Schema not found"); diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingRepository.cs index d6c1b867..fba8eb71 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DbAttributeSchema = DM.Services.DataAccess.BusinessObjects.Games.Characters.Attributes.AttributeSchema; @@ -12,6 +13,7 @@ internal interface ISchemaUpdatingRepository /// Update existing attribute schema /// /// DAL model + /// /// - Task UpdateSchema(DbAttributeSchema schema); + Task UpdateSchema(DbAttributeSchema schema, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingService.cs index 29eef7ce..5cbbd36a 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/ISchemaUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Gaming.Dto.Shared; @@ -12,6 +13,7 @@ public interface ISchemaUpdatingService /// Update attribute schema /// /// DTO for updating + /// /// - Task Update(AttributeSchema attributeSchema); + Task Update(AttributeSchema attributeSchema, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingRepository.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingRepository.cs index b0ec05cd..4cfba912 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingRepository.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingRepository.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.DataAccess.MongoIntegration; using MongoDB.Driver; @@ -6,19 +7,16 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Updating; /// -internal class SchemaUpdatingRepository : MongoCollectionRepository, ISchemaUpdatingRepository +internal class SchemaUpdatingRepository(DmMongoClient client) + : MongoCollectionRepository(client), ISchemaUpdatingRepository { /// - public SchemaUpdatingRepository(DmMongoClient client) : base(client) + public async Task UpdateSchema(DbAttributeSchema schema, CancellationToken cancellationToken) { - } - - /// - public async Task UpdateSchema(DbAttributeSchema schema) - { - await Collection.ReplaceOneAsync(Filter.Eq(s => s.Id, schema.Id), schema); + await Collection.ReplaceOneAsync(Filter.Eq(s => s.Id, schema.Id), schema, + cancellationToken: cancellationToken); return await Collection .Find(Filter.Eq(s => s.Id, schema.Id)) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingService.cs b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingService.cs index 36dc36c3..19424ac4 100644 --- a/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingService.cs +++ b/src/DM.Services.Gaming/BusinessProcesses/Schemas/Updating/SchemaUpdatingService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Authentication.Implementation.UserIdentity; @@ -10,44 +11,24 @@ namespace DM.Services.Gaming.BusinessProcesses.Schemas.Updating; /// -internal class SchemaUpdatingService : ISchemaUpdatingService +internal class SchemaUpdatingService( + ISchemaCreatingValidator validator, + ISchemaReadingService readingService, + IIntentionManager intentionManager, + ISchemaFactory schemaFactory, + ISchemaUpdatingRepository repository, + IMapper mapper, + IIdentityProvider identityProvider) : ISchemaUpdatingService { - private readonly ISchemaCreatingValidator validator; - private readonly ISchemaReadingService readingService; - private readonly IIntentionManager intentionManager; - private readonly ISchemaFactory schemaFactory; - private readonly ISchemaUpdatingRepository repository; - private readonly IMapper mapper; - private readonly IIdentityProvider identityProvider; - - /// - public SchemaUpdatingService( - ISchemaCreatingValidator validator, - ISchemaReadingService readingService, - IIntentionManager intentionManager, - ISchemaFactory schemaFactory, - ISchemaUpdatingRepository repository, - IMapper mapper, - IIdentityProvider identityProvider) - { - this.validator = validator; - this.readingService = readingService; - this.intentionManager = intentionManager; - this.schemaFactory = schemaFactory; - this.repository = repository; - this.mapper = mapper; - this.identityProvider = identityProvider; - } - /// - public async Task Update(AttributeSchema attributeSchema) + public async Task Update(AttributeSchema attributeSchema, CancellationToken cancellationToken) { validator.ValidateAndThrow(attributeSchema); - var oldSchema = await readingService.Get(attributeSchema.Id); + var oldSchema = await readingService.Get(attributeSchema.Id, cancellationToken); intentionManager.ThrowIfForbidden(AttributeSchemaIntention.Edit, oldSchema); var schemaToUpdate = schemaFactory.CreateToUpdate(attributeSchema, identityProvider.Current.User.UserId); - var updatedSchema = await repository.UpdateSchema(schemaToUpdate); + var updatedSchema = await repository.UpdateSchema(schemaToUpdate, cancellationToken); return mapper.Map(updatedSchema); } } \ No newline at end of file diff --git a/src/DM.Services.Gaming/Dto/Input/CreateCharacterValidator.cs b/src/DM.Services.Gaming/Dto/Input/CreateCharacterValidator.cs index b4a33055..c40bc9ba 100644 --- a/src/DM.Services.Gaming/Dto/Input/CreateCharacterValidator.cs +++ b/src/DM.Services.Gaming/Dto/Input/CreateCharacterValidator.cs @@ -34,12 +34,12 @@ public CreateCharacterValidator( WhenAsync(validationRepository.GameRequiresAttributes, () => { RuleFor(c => c.Attributes) - .MustAsync(async (c, _, context, _) => + .MustAsync(async (c, _, context, ct) => { if (!context.RootContextData.TryGetValue(SchemaCacheKey, out var schemaWrapper) || schemaWrapper is not Dictionary specifications) { - var schema = await validationRepository.GetGameSchema(c.GameId); + var schema = await validationRepository.GetGameSchema(c.GameId, ct); specifications = schema.Specifications.ToDictionary(s => s.Id); context.RootContextData[SchemaCacheKey] = specifications; } @@ -56,12 +56,12 @@ public CreateCharacterValidator( .WithMessage($"{{{ErrorMessage}}}"); RuleForEach(c => c.Attributes) - .MustAsync(async (c, attribute, context, _) => + .MustAsync(async (c, attribute, context, ct) => { if (!context.RootContextData.TryGetValue(SchemaCacheKey, out var schemaWrapper) || schemaWrapper is not Dictionary specifications) { - var schema = await validationRepository.GetGameSchema(c.GameId); + var schema = await validationRepository.GetGameSchema(c.GameId, ct); specifications = schema.Specifications.ToDictionary(s => s.Id); context.RootContextData[SchemaCacheKey] = specifications; } diff --git a/src/DM.Services.Gaming/Dto/Input/UpdateCharacterValidator.cs b/src/DM.Services.Gaming/Dto/Input/UpdateCharacterValidator.cs index 399aea02..60467f2e 100644 --- a/src/DM.Services.Gaming/Dto/Input/UpdateCharacterValidator.cs +++ b/src/DM.Services.Gaming/Dto/Input/UpdateCharacterValidator.cs @@ -34,12 +34,12 @@ public UpdateCharacterValidator( When(c => c.Attributes != null && c.Attributes.Any(), () => RuleForEach(c => c.Attributes) - .MustAsync(async (c, attribute, context, _) => + .MustAsync(async (c, attribute, context, ct) => { if (!context.RootContextData.TryGetValue(SchemaCacheKey, out var schemaWrapper) || schemaWrapper is not Dictionary specifications) { - var schema = await validationRepository.GetCharacterSchema(c.CharacterId); + var schema = await validationRepository.GetCharacterSchema(c.CharacterId, ct); specifications = schema.Specifications.ToDictionary(s => s.Id); context.RootContextData[SchemaCacheKey] = specifications; } diff --git a/src/DM.Services.Uploading/BusinessProcesses/PublicImage/IPublicImageService.cs b/src/DM.Services.Uploading/BusinessProcesses/PublicImage/IPublicImageService.cs index 54dfeabd..0cc53d0a 100644 --- a/src/DM.Services.Uploading/BusinessProcesses/PublicImage/IPublicImageService.cs +++ b/src/DM.Services.Uploading/BusinessProcesses/PublicImage/IPublicImageService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Uploading.Dto; @@ -13,13 +14,16 @@ public interface IPublicImageService /// Upload original image and also its cropped it and resized to medium and small size versions /// /// + /// /// - Task<(Upload original, Upload medium, Upload small)> Upload(CreateUpload createUpload); + Task<(Upload original, Upload medium, Upload small)> Upload(CreateUpload createUpload, + CancellationToken cancellationToken); /// /// Prepare obsolete images for deleting /// /// + /// /// - Task PrepareObsoleteForDeleting(Guid entityId); + Task PrepareObsoleteForDeleting(Guid entityId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Uploading/BusinessProcesses/PublicImage/PublicImageService.cs b/src/DM.Services.Uploading/BusinessProcesses/PublicImage/PublicImageService.cs index c531ffe4..531947f7 100644 --- a/src/DM.Services.Uploading/BusinessProcesses/PublicImage/PublicImageService.cs +++ b/src/DM.Services.Uploading/BusinessProcesses/PublicImage/PublicImageService.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.UserIdentity; using DM.Services.Core.Implementation; @@ -47,7 +48,8 @@ public PublicImageService( private static readonly Size SmallSize = new(100, 100); /// - public async Task<(Upload original, Upload medium, Upload small)> Upload(CreateUpload createUpload) + public async Task<(Upload original, Upload medium, Upload small)> Upload(CreateUpload createUpload, + CancellationToken cancellationToken) { await validator.ValidateAndThrowAsync(createUpload); var (name, extension) = await nameGenerator.Generate(createUpload); @@ -77,5 +79,5 @@ public PublicImageService( } /// - public Task PrepareObsoleteForDeleting(Guid entityId) => repository.RemoveObsoleteUploads(entityId); + public Task PrepareObsoleteForDeleting(Guid entityId, CancellationToken cancellationToken) => repository.RemoveObsoleteUploads(entityId); } \ No newline at end of file diff --git a/src/DM.Web.API/BbRendering/BbConverter.cs b/src/DM.Web.API/BbRendering/BbConverter.cs index 834e6ce2..f634f9fc 100644 --- a/src/DM.Web.API/BbRendering/BbConverter.cs +++ b/src/DM.Web.API/BbRendering/BbConverter.cs @@ -9,20 +9,10 @@ namespace DM.Web.API.BbRendering; /// -internal class BbConverterFactory : JsonConverterFactory +internal class BbConverterFactory( + IHttpContextAccessor httpContextAccessor, + IBbParserProvider bbParserProvider) : JsonConverterFactory { - private readonly IHttpContextAccessor httpContextAccessor; - private readonly IBbParserProvider bbParserProvider; - - /// - public BbConverterFactory( - IHttpContextAccessor httpContextAccessor, - IBbParserProvider bbParserProvider) - { - this.httpContextAccessor = httpContextAccessor; - this.bbParserProvider = bbParserProvider; - } - /// public override bool CanConvert(Type typeToConvert) => typeToConvert.IsSubclassOf(typeof(BbText)); @@ -32,7 +22,7 @@ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializer var converter = (JsonConverter) Activator.CreateInstance( typeof(BbConverter<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, - null, new object[] {httpContextAccessor, bbParserProvider}, null); + null, [httpContextAccessor, bbParserProvider], null); return converter; } @@ -49,7 +39,8 @@ public override void Write(Utf8JsonWriter writer, TBbText bbText, JsonSerializer { var httpContext = httpContextAccessor.HttpContext; var renderMode = httpContext.Request.Headers.TryGetValue("X-Dm-Bb-Render-Mode", out var headerValues) && - headerValues.Any() && Enum.TryParse(headerValues.First(), out var requiredRenderMode) + headerValues.Count != 0 && + Enum.TryParse(headerValues.First(), out var requiredRenderMode) ? requiredRenderMode : BbRenderMode.Html; var value = bbText.Value; @@ -59,7 +50,7 @@ public override void Write(Utf8JsonWriter writer, TBbText bbText, JsonSerializer writer.WriteStringValue(bbParserProvider.CurrentSafePost.Parse(value).ToHtml()); return; } - + var parsedTree = bbText.ParseMode switch { BbParseMode.Common => bbParserProvider.CurrentCommon.Parse(value), @@ -76,7 +67,7 @@ public override void Write(Utf8JsonWriter writer, TBbText bbText, JsonSerializer BbRenderMode.Text => parsedTree.ToText(), _ => throw new ArgumentOutOfRangeException() }; - + writer.WriteStringValue(text); } } diff --git a/src/DM.Web.API/Controllers/v1/Account/AccountController.cs b/src/DM.Web.API/Controllers/v1/Account/AccountController.cs index 22681f26..495c694b 100644 --- a/src/DM.Web.API/Controllers/v1/Account/AccountController.cs +++ b/src/DM.Web.API/Controllers/v1/Account/AccountController.cs @@ -13,29 +13,13 @@ namespace DM.Web.API.Controllers.v1.Account; [ApiController] [Route("v1/account")] [ApiExplorerSettings(GroupName = "Account")] -public class AccountController : ControllerBase +public class AccountController( + IRegistrationApiService registrationApiService, + IActivationApiService activationApiService, + ILoginApiService loginApiService, + IPasswordResetApiService passwordResetApiService, + IEmailChangeApiService emailChangeApiService) : ControllerBase { - private readonly IRegistrationApiService registrationApiService; - private readonly IActivationApiService activationApiService; - private readonly ILoginApiService loginApiService; - private readonly IPasswordResetApiService passwordResetApiService; - private readonly IEmailChangeApiService emailChangeApiService; - - /// - public AccountController( - IRegistrationApiService registrationApiService, - IActivationApiService activationApiService, - ILoginApiService loginApiService, - IPasswordResetApiService passwordResetApiService, - IEmailChangeApiService emailChangeApiService) - { - this.registrationApiService = registrationApiService; - this.activationApiService = activationApiService; - this.loginApiService = loginApiService; - this.passwordResetApiService = passwordResetApiService; - this.emailChangeApiService = emailChangeApiService; - } - /// /// Register new user /// @@ -47,7 +31,7 @@ public AccountController( [ProducesResponseType(typeof(BadRequestError), 400)] public async Task Register([FromBody] Registration registration) { - await registrationApiService.Register(registration); + await registrationApiService.Register(registration, HttpContext.RequestAborted); return CreatedAtRoute(nameof(UserController.GetUser), new {login = registration.Login}, null); } @@ -58,11 +42,12 @@ public async Task Register([FromBody] Registration registration) /// User has been activated and logged in /// Token is invalid /// Token is expired - [HttpPut("{token}", Name = nameof(Activate))] + [HttpPut("{token:guid}", Name = nameof(Activate))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 400)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task Activate(Guid token) => Ok(await activationApiService.Activate(token)); + public async Task Activate(Guid token) => + Ok(await activationApiService.Activate(token, HttpContext.RequestAborted)); /// /// Get current user @@ -71,7 +56,8 @@ public async Task Register([FromBody] Registration registration) [HttpGet(Name = nameof(GetCurrent))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] - public async Task GetCurrent() => Ok(await loginApiService.GetCurrent()); + public async Task GetCurrent() => + Ok(await loginApiService.GetCurrent(HttpContext.RequestAborted)); /// /// Reset registered user password @@ -83,7 +69,7 @@ public async Task Register([FromBody] Registration registration) [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] public async Task ResetPassword([FromBody] ResetPassword resetPassword) => - Ok(await passwordResetApiService.Reset(resetPassword)); + Ok(await passwordResetApiService.Reset(resetPassword, HttpContext.RequestAborted)); /// /// Change registered user password @@ -95,7 +81,7 @@ public async Task ResetPassword([FromBody] ResetPassword resetPas [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] public async Task ChangePassword([FromBody] ChangePassword changePassword) => - Ok(await passwordResetApiService.Change(changePassword)); + Ok(await passwordResetApiService.Change(changePassword, HttpContext.RequestAborted)); /// /// Change registered user email @@ -107,5 +93,5 @@ public async Task ChangePassword([FromBody] ChangePassword change [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] public async Task ChangeEmail([FromBody] ChangeEmail changeEmail) => - Ok(await emailChangeApiService.Change(changeEmail)); + Ok(await emailChangeApiService.Change(changeEmail, HttpContext.RequestAborted)); } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Account/LoginController.cs b/src/DM.Web.API/Controllers/v1/Account/LoginController.cs index 4baf9090..fb9eb775 100644 --- a/src/DM.Web.API/Controllers/v1/Account/LoginController.cs +++ b/src/DM.Web.API/Controllers/v1/Account/LoginController.cs @@ -12,17 +12,9 @@ namespace DM.Web.API.Controllers.v1.Account; [ApiController] [Route("v1/account/login")] [ApiExplorerSettings(GroupName = "Account")] -public class LoginController : ControllerBase +public class LoginController( + ILoginApiService loginApiService) : ControllerBase { - private readonly ILoginApiService loginApiService; - - /// - public LoginController( - ILoginApiService loginApiService) - { - this.loginApiService = loginApiService; - } - /// /// Authenticate via credentials /// diff --git a/src/DM.Web.API/Controllers/v1/Common/SearchController.cs b/src/DM.Web.API/Controllers/v1/Common/SearchController.cs index e0c98357..0b804845 100644 --- a/src/DM.Web.API/Controllers/v1/Common/SearchController.cs +++ b/src/DM.Web.API/Controllers/v1/Common/SearchController.cs @@ -13,16 +13,10 @@ namespace DM.Web.API.Controllers.v1.Common; [ApiController] [Route("v1/search")] [ApiExplorerSettings(GroupName = "Common")] -public class SearchController : ControllerBase +public class SearchController( + IOptions options) : ControllerBase { - private readonly SearchServiceConfiguration searchServiceConfiguration; - - /// - public SearchController( - IOptions options) - { - searchServiceConfiguration = options.Value; - } + private readonly SearchServiceConfiguration searchServiceConfiguration = options.Value; /// /// diff --git a/src/DM.Web.API/Controllers/v1/Community/ChatController.cs b/src/DM.Web.API/Controllers/v1/Community/ChatController.cs index d20c27e7..3359b768 100644 --- a/src/DM.Web.API/Controllers/v1/Community/ChatController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/ChatController.cs @@ -13,17 +13,9 @@ namespace DM.Web.API.Controllers.v1.Community; [ApiController] [Route("v1/chat")] [ApiExplorerSettings(GroupName = "Messaging")] -public class ChatController : ControllerBase +public class ChatController( + IChatApiService chatApiService) : ControllerBase { - private readonly IChatApiService chatApiService; - - /// - public ChatController( - IChatApiService chatApiService) - { - this.chatApiService = chatApiService; - } - /// /// Get chat messages /// @@ -31,7 +23,7 @@ public ChatController( [HttpGet(Name = nameof(GetChatMessages))] [ProducesResponseType(typeof(ListEnvelope), 200)] public async Task GetChatMessages([FromQuery] PagingQuery q) => - Ok(await chatApiService.GetMessages(q)); + Ok(await chatApiService.GetMessages(q, HttpContext.RequestAborted)); /// /// Create new chat message @@ -48,7 +40,7 @@ public async Task GetChatMessages([FromQuery] PagingQuery q) => [ProducesResponseType(typeof(Envelope), 403)] public async Task PostChatMessage([FromBody] ChatMessage chatMessage) { - var result = await chatApiService.CreateMessage(chatMessage); + var result = await chatApiService.CreateMessage(chatMessage, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetChatMessage), new {id = result.Resource.Id}, result); } @@ -57,9 +49,9 @@ public async Task PostChatMessage([FromBody] ChatMessage chatMess /// /// /// Message not found - [HttpGet("{id}", Name = nameof(GetChatMessage))] + [HttpGet("{id:guid}", Name = nameof(GetChatMessage))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(Envelope), 410)] public async Task GetChatMessage(Guid id) => - Ok(await chatApiService.GetMessage(id)); + Ok(await chatApiService.GetMessage(id, HttpContext.RequestAborted)); } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Community/MessagingController.cs b/src/DM.Web.API/Controllers/v1/Community/MessagingController.cs index 1506eb33..d9fea3e2 100644 --- a/src/DM.Web.API/Controllers/v1/Community/MessagingController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/MessagingController.cs @@ -13,17 +13,9 @@ namespace DM.Web.API.Controllers.v1.Community; [ApiController] [Route("v1")] [ApiExplorerSettings(GroupName = "Messaging")] -public class MessagingController : ControllerBase +public class MessagingController( + IMessagingApiService apiService) : ControllerBase { - private readonly IMessagingApiService apiService; - - /// - public MessagingController( - IMessagingApiService apiService) - { - this.apiService = apiService; - } - /// /// Get user conversations /// @@ -34,7 +26,7 @@ public MessagingController( [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] public async Task GetConversations([FromQuery] PagingQuery q) => - Ok(await apiService.GetConversations(q)); + Ok(await apiService.GetConversations(q, HttpContext.RequestAborted)); /// /// Get conversation with user @@ -49,7 +41,7 @@ public async Task GetConversations([FromQuery] PagingQuery q) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetVisaviConversation(string login) { - var conversation = await apiService.GetConversation(login); + var conversation = await apiService.GetConversation(login, HttpContext.RequestAborted); return RedirectToRoute(nameof(GetConversation), new {id = conversation.Resource.Id}); } @@ -59,13 +51,13 @@ public async Task GetVisaviConversation(string login) /// /// User must be authenticated /// Dialogue not found - [HttpGet("dialogues/{id}", Name = nameof(GetConversation))] + [HttpGet("dialogues/{id:guid}", Name = nameof(GetConversation))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetConversation(Guid id) => - Ok(await apiService.GetConversation(id)); + Ok(await apiService.GetConversation(id, HttpContext.RequestAborted)); /// /// Get single conversation messages @@ -73,13 +65,13 @@ public async Task GetConversation(Guid id) => /// /// User must be authenticated /// Dialogue not found - [HttpGet("dialogues/{id}/messages", Name = nameof(GetMessages))] + [HttpGet("dialogues/{id:guid}/messages", Name = nameof(GetMessages))] [AuthenticationRequired] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetMessages(Guid id, [FromQuery] PagingQuery q) => - Ok(await apiService.GetMessages(id, q)); + Ok(await apiService.GetMessages(id, q, HttpContext.RequestAborted)); /// /// Create message in conversation @@ -89,7 +81,7 @@ public async Task GetMessages(Guid id, [FromQuery] PagingQuery q) /// User must be authenticated /// User is not allowed to create message in this conversation /// Dialogue not found - [HttpPost("dialogues/{id}/messages", Name = nameof(PostMessage))] + [HttpPost("dialogues/{id:guid}/messages", Name = nameof(PostMessage))] [AuthenticationRequired] [ProducesResponseType(typeof(ListEnvelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -98,7 +90,7 @@ public async Task GetMessages(Guid id, [FromQuery] PagingQuery q) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostMessage(Guid id, [FromBody] Message message) { - var result = await apiService.CreateMessage(id, message); + var result = await apiService.CreateMessage(id, message, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetMessage), new {id = result.Resource.Id}, result); } @@ -107,11 +99,11 @@ public async Task PostMessage(Guid id, [FromBody] Message message /// /// /// Dialogue not found - [HttpDelete("dialogues/{id}/messages/unread")] + [HttpDelete("dialogues/{id:guid}/messages/unread")] [AuthenticationRequired] public async Task MarkAsRead(Guid id) { - await apiService.MarkAsRead(id); + await apiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } @@ -121,12 +113,13 @@ public async Task MarkAsRead(Guid id) /// /// User must be authenticated /// Message not found - [HttpGet("messages/{id}", Name = nameof(GetMessage))] + [HttpGet("messages/{id:guid}", Name = nameof(GetMessage))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetMessage(Guid id) => Ok(await apiService.GetMessage(id)); + public async Task GetMessage(Guid id) => + Ok(await apiService.GetMessage(id, HttpContext.RequestAborted)); /// /// Delete single message @@ -134,14 +127,14 @@ public async Task MarkAsRead(Guid id) /// /// User must be authenticated /// Message not found - [HttpDelete("messages/{id}", Name = nameof(DeleteMessage))] + [HttpDelete("messages/{id:guid}", Name = nameof(DeleteMessage))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteMessage(Guid id) { - await apiService.DeleteMessage(id); + await apiService.DeleteMessage(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Community/PollController.cs b/src/DM.Web.API/Controllers/v1/Community/PollController.cs index dc605f6c..15c0bf33 100644 --- a/src/DM.Web.API/Controllers/v1/Community/PollController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/PollController.cs @@ -12,17 +12,9 @@ namespace DM.Web.API.Controllers.v1.Community; [ApiController] [Route("v1/polls")] [ApiExplorerSettings(GroupName = "Community")] -public class PollController : ControllerBase +public class PollController( + IPollApiService apiService) : ControllerBase { - private readonly IPollApiService apiService; - - /// - public PollController( - IPollApiService apiService) - { - this.apiService = apiService; - } - /// /// Get list of polls /// @@ -30,7 +22,8 @@ public PollController( /// [HttpGet(Name = nameof(GetPolls))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetPolls([FromQuery] PollsQuery q) => Ok(await apiService.Get(q)); + public async Task GetPolls([FromQuery] PollsQuery q) => + Ok(await apiService.Get(q, HttpContext.RequestAborted)); /// /// Create new poll @@ -48,7 +41,7 @@ public PollController( [ProducesResponseType(typeof(BadRequestError), 403)] public async Task PostPoll([FromBody] Poll poll) { - var result = await apiService.Create(poll); + var result = await apiService.Create(poll, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetPoll), new {id = result.Resource.Id}, result); } @@ -58,10 +51,11 @@ public async Task PostPoll([FromBody] Poll poll) /// /// /// Poll not found - [HttpGet("{id}", Name = nameof(GetPoll))] + [HttpGet("{id:guid}", Name = nameof(GetPoll))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetPoll(Guid id) => Ok(await apiService.Get(id)); + public async Task GetPoll(Guid id) => + Ok(await apiService.Get(id, HttpContext.RequestAborted)); /// /// Vote for the poll option @@ -72,12 +66,12 @@ public async Task PostPoll([FromBody] Poll poll) /// User must be authenticated /// User is not authorized to vote for this poll /// Poll not found - [HttpPut("{id}", Name = nameof(PutPollVote))] + [HttpPut("{id:guid}", Name = nameof(PutPollVote))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutPollVote(Guid id, [FromQuery] Guid optionId) => - Ok(await apiService.Vote(id, optionId)); + Ok(await apiService.Vote(id, optionId, HttpContext.RequestAborted)); } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Community/ReviewController.cs b/src/DM.Web.API/Controllers/v1/Community/ReviewController.cs index b6c89d67..2abbcc34 100644 --- a/src/DM.Web.API/Controllers/v1/Community/ReviewController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/ReviewController.cs @@ -12,17 +12,9 @@ namespace DM.Web.API.Controllers.v1.Community; [ApiController] [Route("v1/reviews")] [ApiExplorerSettings(GroupName = "Community")] -public class ReviewController : ControllerBase +public class ReviewController( + IReviewApiService reviewApiService) : ControllerBase { - private readonly IReviewApiService reviewApiService; - - /// - public ReviewController( - IReviewApiService reviewApiService) - { - this.reviewApiService = reviewApiService; - } - /// /// Get list of reviews /// @@ -30,7 +22,8 @@ public ReviewController( /// [HttpGet(Name = nameof(GetReviews))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetReviews([FromQuery] ReviewsQuery q) => Ok(await reviewApiService.Get(q)); + public async Task GetReviews([FromQuery] ReviewsQuery q) => + Ok(await reviewApiService.Get(q, HttpContext.RequestAborted)); /// /// Create new review @@ -43,7 +36,7 @@ public ReviewController( [AuthenticationRequired] public async Task CreateReview([FromBody] Review review) { - var result = await reviewApiService.Create(review); + var result = await reviewApiService.Create(review, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetReview), new {id = result.Resource.Id}, result); } @@ -53,10 +46,11 @@ public async Task CreateReview([FromBody] Review review) /// /// /// Review not found - [HttpGet("{id}", Name = nameof(GetReview))] + [HttpGet("{id:guid}", Name = nameof(GetReview))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetReview(Guid id) => Ok(await reviewApiService.Get(id)); + public async Task GetReview(Guid id) => + Ok(await reviewApiService.Get(id, HttpContext.RequestAborted)); /// /// Update review @@ -66,7 +60,7 @@ public async Task CreateReview([FromBody] Review review) /// User must be authenticated /// User is not authorized to update this review /// Review not found - [HttpPatch("{id}", Name = nameof(PutReview))] + [HttpPatch("{id:guid}", Name = nameof(PutReview))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -74,7 +68,7 @@ public async Task CreateReview([FromBody] Review review) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutReview(Guid id, [FromBody] Review review) => - Ok(await reviewApiService.Update(id, review)); + Ok(await reviewApiService.Update(id, review, HttpContext.RequestAborted)); /// /// Delete review @@ -82,14 +76,14 @@ public async Task PutReview(Guid id, [FromBody] Review review) => /// /// User must be authenticated /// Review not found - [HttpDelete("{id}", Name = nameof(DeleteReview))] + [HttpDelete("{id:guid}", Name = nameof(DeleteReview))] [AuthenticationRequired] [ProducesResponseType(240)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteReview(Guid id) { - await reviewApiService.Delete(id); + await reviewApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Community/UserController.cs b/src/DM.Web.API/Controllers/v1/Community/UserController.cs index 48a2e7d8..73484d41 100644 --- a/src/DM.Web.API/Controllers/v1/Community/UserController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/UserController.cs @@ -11,17 +11,9 @@ namespace DM.Web.API.Controllers.v1.Community; [ApiController] [Route("v1/users")] [ApiExplorerSettings(GroupName = "Community")] -public class UserController : ControllerBase +public class UserController( + IUserApiService userApiService) : ControllerBase { - private readonly IUserApiService userApiService; - - /// - public UserController( - IUserApiService userApiService) - { - this.userApiService = userApiService; - } - /// /// Get list of community users /// @@ -29,7 +21,7 @@ public UserController( [HttpGet("")] [ProducesResponseType(typeof(ListEnvelope), 200)] public async Task GetUsers([FromQuery] UsersQuery query) => - Ok(await userApiService.GetUsers(query)); + Ok(await userApiService.GetUsers(query, HttpContext.RequestAborted)); /// /// Get certain user @@ -40,7 +32,8 @@ public async Task GetUsers([FromQuery] UsersQuery query) => [HttpGet("{login}", Name = nameof(GetUser))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetUser(string login) => Ok(await userApiService.GetUser(login)); + public async Task GetUser(string login) => + Ok(await userApiService.GetUser(login, HttpContext.RequestAborted)); /// /// Get certain user details @@ -51,7 +44,8 @@ public async Task GetUsers([FromQuery] UsersQuery query) => [HttpGet("{login}/details", Name = nameof(GetUserDetails))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetUserDetails(string login) => Ok(await userApiService.GetUserDetails(login)); + public async Task GetUserDetails(string login) => + Ok(await userApiService.GetUserDetails(login, HttpContext.RequestAborted)); /// /// Update user details @@ -71,5 +65,5 @@ public async Task GetUsers([FromQuery] UsersQuery query) => [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutUserDetails(string login, [FromBody] UserDetails user) => - Ok(await userApiService.UpdateUser(login, user)); + Ok(await userApiService.UpdateUser(login, user, HttpContext.RequestAborted)); } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Community/UserUploadController.cs b/src/DM.Web.API/Controllers/v1/Community/UserUploadController.cs index a01f3a59..5094c96f 100644 --- a/src/DM.Web.API/Controllers/v1/Community/UserUploadController.cs +++ b/src/DM.Web.API/Controllers/v1/Community/UserUploadController.cs @@ -13,17 +13,9 @@ namespace DM.Web.API.Controllers.v1.Community; /// [Route("v1/users")] [ApiExplorerSettings(GroupName = "Community")] -public class UserUploadController : ControllerBase +public class UserUploadController( + IUserApiService userApiService) : ControllerBase { - private readonly IUserApiService userApiService; - - /// - public UserUploadController( - IUserApiService userApiService) - { - this.userApiService = userApiService; - } - /// /// Post user profile picture /// @@ -47,5 +39,5 @@ public async Task PostUserUpload(string login, FileMimeTypeNames.Image.Jpeg, FileMimeTypeNames.Image.Png, ErrorMessage = "File must be a gif/jpg/png image")] IFormFile file) => - Ok(await userApiService.UploadProfilePicture(login, file)); + Ok(await userApiService.UploadProfilePicture(login, file, HttpContext.RequestAborted)); } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Fora/CommentController.cs b/src/DM.Web.API/Controllers/v1/Fora/CommentController.cs index fc6c759d..7e257742 100644 --- a/src/DM.Web.API/Controllers/v1/Fora/CommentController.cs +++ b/src/DM.Web.API/Controllers/v1/Fora/CommentController.cs @@ -11,32 +11,23 @@ namespace DM.Web.API.Controllers.v1.Fora; /// [ApiController] -[Route("v1/forum/comments")] +[Route("v1/forum/comments/{id:guid}")] [ApiExplorerSettings(GroupName = "Forum")] -public class CommentController : ControllerBase +public class CommentController( + ICommentApiService commentApiService, + ILikeApiService likeApiService) : ControllerBase { - private readonly ICommentApiService commentApiService; - private readonly ILikeApiService likeApiService; - - /// - public CommentController( - ICommentApiService commentApiService, - ILikeApiService likeApiService) - { - this.commentApiService = commentApiService; - this.likeApiService = likeApiService; - } - /// /// Get comment /// /// /// /// Comment not found - [HttpGet("{id}", Name = nameof(GetForumComment))] + [HttpGet("", Name = nameof(GetForumComment))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetForumComment(Guid id) => Ok(await commentApiService.Get(id)); + public async Task GetForumComment(Guid id) => + Ok(await commentApiService.Get(id, HttpContext.RequestAborted)); /// /// Update comment @@ -48,7 +39,7 @@ public CommentController( /// User must be authenticated /// User is not allowed to change this comment /// Comment not found - [HttpPatch("{id}", Name = nameof(PutForumComment))] + [HttpPatch("", Name = nameof(PutForumComment))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -56,7 +47,7 @@ public CommentController( [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutForumComment(Guid id, [FromBody] Comment comment) => - Ok(await commentApiService.Update(id, comment)); + Ok(await commentApiService.Update(id, comment, HttpContext.RequestAborted)); /// /// Delete comment @@ -66,7 +57,7 @@ public async Task PutForumComment(Guid id, [FromBody] Comment com /// User must be authenticated /// User is not allowed to change this comment /// Comment not found - [HttpDelete("{id}", Name = nameof(DeleteForumComment))] + [HttpDelete("", Name = nameof(DeleteForumComment))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -74,7 +65,7 @@ public async Task PutForumComment(Guid id, [FromBody] Comment com [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteForumComment(Guid id) { - await commentApiService.Delete(id); + await commentApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -87,7 +78,7 @@ public async Task DeleteForumComment(Guid id) /// User is not allowed to like the comment /// User already liked this comment /// Comment not found - [HttpPost("{id}/likes", Name = nameof(PostForumCommentLike))] + [HttpPost("likes", Name = nameof(PostForumCommentLike))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -96,7 +87,7 @@ public async Task DeleteForumComment(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostForumCommentLike(Guid id) { - var result = await likeApiService.LikeComment(id); + var result = await likeApiService.LikeComment(id, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetForumComment), new {id}, result); } @@ -109,7 +100,7 @@ public async Task PostForumCommentLike(Guid id) /// User is not allowed to remove like from this comment /// User has no like for this comment /// Comment not found - [HttpDelete("{id}/likes", Name = nameof(DeleteForumCommentLike))] + [HttpDelete("likes", Name = nameof(DeleteForumCommentLike))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -118,7 +109,7 @@ public async Task PostForumCommentLike(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteForumCommentLike(Guid id) { - await likeApiService.DislikeComment(id); + await likeApiService.DislikeComment(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Fora/ForumController.cs b/src/DM.Web.API/Controllers/v1/Fora/ForumController.cs index ba688e6c..4a307452 100644 --- a/src/DM.Web.API/Controllers/v1/Fora/ForumController.cs +++ b/src/DM.Web.API/Controllers/v1/Fora/ForumController.cs @@ -12,33 +12,20 @@ namespace DM.Web.API.Controllers.v1.Fora; [ApiController] [Route("v1/fora")] [ApiExplorerSettings(GroupName = "Forum")] -public class ForumController : ControllerBase +public class ForumController( + IForumApiService forumApiService, + ITopicApiService topicApiService, + ICommentApiService commentApiService, + IModeratorsApiService moderatorsApiService) : ControllerBase { - private readonly IForumApiService forumApiService; - private readonly ITopicApiService topicApiService; - private readonly ICommentApiService commentApiService; - private readonly IModeratorsApiService moderatorsApiService; - - /// - public ForumController( - IForumApiService forumApiService, - ITopicApiService topicApiService, - ICommentApiService commentApiService, - IModeratorsApiService moderatorsApiService) - { - this.forumApiService = forumApiService; - this.topicApiService = topicApiService; - this.commentApiService = commentApiService; - this.moderatorsApiService = moderatorsApiService; - } - /// /// Get list of available fora /// /// [HttpGet(Name = nameof(GetFora))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetFora() => Ok(await forumApiService.Get()); + public async Task GetFora() => + Ok(await forumApiService.Get(HttpContext.RequestAborted)); /// /// Get certain forum @@ -49,7 +36,8 @@ public ForumController( [HttpGet("{id}", Name = nameof(GetForum))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetForum(string id) => Ok(await forumApiService.Get(id)); + public async Task GetForum(string id) => + Ok(await forumApiService.Get(id, HttpContext.RequestAborted)); /// /// Mark all forum comments as read @@ -65,7 +53,7 @@ public ForumController( [ProducesResponseType(typeof(GeneralError), 410)] public async Task ReadForumComments(string id) { - await commentApiService.MarkAsRead(id); + await commentApiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } @@ -78,7 +66,8 @@ public async Task ReadForumComments(string id) [HttpGet("{id}/moderators", Name = nameof(GetModerators))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetModerators(string id) => Ok(await moderatorsApiService.GetModerators(id)); + public async Task GetModerators(string id) => + Ok(await moderatorsApiService.GetModerators(id, HttpContext.RequestAborted)); /// /// Get list of forum topics @@ -93,7 +82,7 @@ public async Task ReadForumComments(string id) [ProducesResponseType(typeof(BadRequestError), 400)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetTopics(string id, [FromQuery] TopicsQuery q) => - Ok(await topicApiService.Get(id, q)); + Ok(await topicApiService.Get(id, q, HttpContext.RequestAborted)); /// /// Post new topic @@ -114,7 +103,7 @@ public async Task GetTopics(string id, [FromQuery] TopicsQuery q) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostTopic(string id, [FromBody] Topic topic) { - var result = await topicApiService.Create(id, topic); + var result = await topicApiService.Create(id, topic, HttpContext.RequestAborted); return CreatedAtRoute(nameof(TopicController.GetTopic), new {id = result.Resource.Id}, result); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Fora/TopicController.cs b/src/DM.Web.API/Controllers/v1/Fora/TopicController.cs index 1133aafc..249b4d55 100644 --- a/src/DM.Web.API/Controllers/v1/Fora/TopicController.cs +++ b/src/DM.Web.API/Controllers/v1/Fora/TopicController.cs @@ -13,35 +13,24 @@ namespace DM.Web.API.Controllers.v1.Fora; /// [ApiController] -[Route("v1/topics")] +[Route("v1/topics/{id:guid}")] [ApiExplorerSettings(GroupName = "Forum")] -public class TopicController : ControllerBase +public class TopicController( + ITopicApiService topicApiService, + ILikeApiService likeApiService, + ICommentApiService commentApiService) : ControllerBase { - private readonly ITopicApiService topicApiService; - private readonly ILikeApiService likeApiService; - private readonly ICommentApiService commentApiService; - - /// - public TopicController( - ITopicApiService topicApiService, - ILikeApiService likeApiService, - ICommentApiService commentApiService) - { - this.topicApiService = topicApiService; - this.likeApiService = likeApiService; - this.commentApiService = commentApiService; - } - /// /// Get certain topic /// /// /// /// Topic not found - [HttpGet("{id}", Name = nameof(GetTopic))] + [HttpGet("", Name = nameof(GetTopic))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetTopic(Guid id) => Ok(await topicApiService.Get(id)); + public async Task GetTopic(Guid id) => + Ok(await topicApiService.Get(id, HttpContext.RequestAborted)); /// /// Put topic changes @@ -49,11 +38,11 @@ public TopicController( /// /// Topic /// - /// Some of topic changed properties were invalid or passed id was not recognized + /// Some of the topic changed properties were invalid or passed id was not recognized /// User must be authenticated /// User is not authorized to change some properties of this topic /// Topic not found - [HttpPatch("{id}", Name = nameof(PutTopic))] + [HttpPatch("", Name = nameof(PutTopic))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -61,7 +50,7 @@ public TopicController( [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutTopic(Guid id, [FromBody] Topic topic) => - Ok(await topicApiService.Update(id, topic)); + Ok(await topicApiService.Update(id, topic, HttpContext.RequestAborted)); /// /// Delete certain topic @@ -71,7 +60,7 @@ public async Task PutTopic(Guid id, [FromBody] Topic topic) => /// User must be authenticated /// User is not allowed to remove the topic /// Topic not found - [HttpDelete("{id}", Name = nameof(DeleteTopic))] + [HttpDelete("", Name = nameof(DeleteTopic))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -79,7 +68,7 @@ public async Task PutTopic(Guid id, [FromBody] Topic topic) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteTopic(Guid id) { - await topicApiService.Delete(id); + await topicApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -93,15 +82,18 @@ public async Task DeleteTopic(Guid id) /// User is not allowed to like the topic /// User already liked this topic /// Topic not found - [HttpPost("{id}/likes", Name = nameof(PostTopicLike))] + [HttpPost("likes", Name = nameof(PostTopicLike))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 409)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task PostTopicLike(Guid id) => - CreatedAtRoute(nameof(GetTopic), new {id}, await likeApiService.LikeTopic(id)); + public async Task PostTopicLike(Guid id) + { + var result = await likeApiService.LikeTopic(id, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetTopic), new { id }, result); + } /// /// Delete like @@ -112,7 +104,7 @@ public async Task PostTopicLike(Guid id) => /// User is not allowed to remove like from this topic /// User has no like for this topic /// Topic not found - [HttpDelete("{id}/likes", Name = nameof(DeleteTopicLike))] + [HttpDelete("likes", Name = nameof(DeleteTopicLike))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -121,7 +113,7 @@ public async Task PostTopicLike(Guid id) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteTopicLike(Guid id) { - await likeApiService.DislikeTopic(id); + await likeApiService.DislikeTopic(id, HttpContext.RequestAborted); return NoContent(); } @@ -132,11 +124,11 @@ public async Task DeleteTopicLike(Guid id) /// /// /// Topic not found - [HttpGet("{id}/comments", Name = nameof(GetForumComments))] + [HttpGet("comments", Name = nameof(GetForumComments))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetForumComments(Guid id, [FromQuery] PagingQuery q) => - Ok(await commentApiService.Get(id, q)); + Ok(await commentApiService.Get(id, q, HttpContext.RequestAborted)); /// /// Post new comment @@ -148,7 +140,7 @@ public async Task GetForumComments(Guid id, [FromQuery] PagingQue /// User must be authenticated /// User is not allowed to comment this topic /// Topic not found - [HttpPost("{id}/comments", Name = nameof(PostForumComment))] + [HttpPost("comments", Name = nameof(PostForumComment))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -157,7 +149,7 @@ public async Task GetForumComments(Guid id, [FromQuery] PagingQue [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostForumComment(Guid id, [FromBody] Comment comment) { - var result = await commentApiService.Create(id, comment); + var result = await commentApiService.Create(id, comment, HttpContext.RequestAborted); return CreatedAtRoute(nameof(CommentController.GetForumComment), new {id = result.Resource.Id}, result); } @@ -168,14 +160,14 @@ public async Task PostForumComment(Guid id, [FromBody] Comment co /// /// User must be authenticated /// Topic not found - [HttpDelete("{id}/comments/unread", Name = nameof(ReadTopicComments))] + [HttpDelete("comments/unread", Name = nameof(ReadTopicComments))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task ReadTopicComments(Guid id) { - await commentApiService.MarkAsRead(id); + await commentApiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Gaming/AttributeSchemaController.cs b/src/DM.Web.API/Controllers/v1/Gaming/AttributeSchemaController.cs index 92213a8f..884b0ddf 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/AttributeSchemaController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/AttributeSchemaController.cs @@ -12,24 +12,17 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1/schemata")] [ApiExplorerSettings(GroupName = "Game")] -public class AttributeSchemaController : ControllerBase +public class AttributeSchemaController( + ISchemaApiService schemaApiService) : ControllerBase { - private readonly ISchemaApiService schemaApiService; - - /// - public AttributeSchemaController( - ISchemaApiService schemaApiService) - { - this.schemaApiService = schemaApiService; - } - /// /// Get list of game attribute schemas /// /// [HttpGet(Name = nameof(GetSchemas))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetSchemas() => Ok(await schemaApiService.Get()); + public async Task GetSchemas() => + Ok(await schemaApiService.Get(HttpContext.RequestAborted)); /// /// Post new attribute schema @@ -47,7 +40,7 @@ public AttributeSchemaController( [ProducesResponseType(typeof(GeneralError), 403)] public async Task PostSchema([FromBody] AttributeSchema schema) { - var result = await schemaApiService.Create(schema); + var result = await schemaApiService.Create(schema, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetSchema), new {id = result.Resource.Id}, result); } @@ -57,10 +50,11 @@ public async Task PostSchema([FromBody] AttributeSchema schema) /// /// /// Schema not found - [HttpGet("{id}", Name = nameof(GetSchema))] + [HttpGet("{id:guid}", Name = nameof(GetSchema))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetSchema(Guid id) => Ok(await schemaApiService.Get(id)); + public async Task GetSchema(Guid id) => + Ok(await schemaApiService.Get(id, HttpContext.RequestAborted)); /// /// Update existing attribute schema @@ -72,7 +66,7 @@ public async Task PostSchema([FromBody] AttributeSchema schema) /// User must be authenticated /// User is not allowed to update this attribute schema /// Schema not found - [HttpPatch("{id}", Name = nameof(PutSchema))] + [HttpPatch("{id:guid}", Name = nameof(PutSchema))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -80,7 +74,7 @@ public async Task PostSchema([FromBody] AttributeSchema schema) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutSchema(Guid id, [FromBody] AttributeSchema schema) => - Ok(await schemaApiService.Update(id, schema)); + Ok(await schemaApiService.Update(id, schema, HttpContext.RequestAborted)); /// /// Delete existing attribute schema @@ -90,7 +84,7 @@ public async Task PutSchema(Guid id, [FromBody] AttributeSchema s /// User must be authenticated /// User is not allowed to delete this attribute schema /// Schema not found - [HttpDelete("{id}", Name = nameof(DeleteSchema))] + [HttpDelete("{id:guid}", Name = nameof(DeleteSchema))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -98,7 +92,7 @@ public async Task PutSchema(Guid id, [FromBody] AttributeSchema s [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteSchema(Guid id) { - await schemaApiService.Delete(id); + await schemaApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Gaming/CharacterController.cs b/src/DM.Web.API/Controllers/v1/Gaming/CharacterController.cs index 5c15a67d..e8f5eebd 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/CharacterController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/CharacterController.cs @@ -12,27 +12,20 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1")] [ApiExplorerSettings(GroupName = "Game")] -public class CharacterController : ControllerBase +public class CharacterController( + ICharacterApiService characterApiService) : ControllerBase { - private readonly ICharacterApiService characterApiService; - - /// - public CharacterController( - ICharacterApiService characterApiService) - { - this.characterApiService = characterApiService; - } - /// /// Get list of game characters /// /// /// /// Game not found - [HttpGet("games/{id}/characters", Name = nameof(GetCharacters))] + [HttpGet("games/{id:guid}/characters", Name = nameof(GetCharacters))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetCharacters(Guid id) => Ok(await characterApiService.GetAll(id)); + public async Task GetCharacters(Guid id) => + Ok(await characterApiService.GetAll(id, HttpContext.RequestAborted)); /// /// Post new character @@ -44,7 +37,7 @@ public CharacterController( /// User must be authenticated /// User is not authorized to create a character in this game /// Game not found - [HttpPost("games/{id}/characters", Name = nameof(PostCharacter))] + [HttpPost("games/{id:guid}/characters", Name = nameof(PostCharacter))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -53,9 +46,8 @@ public CharacterController( [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostCharacter(Guid id, [FromBody] Character character) { - var result = await characterApiService.Create(id, character); - return CreatedAtRoute(nameof(GetCharacter), - new {id = result.Resource.Id}, result); + var result = await characterApiService.Create(id, character, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetCharacter), new {id = result.Resource.Id}, result); } /// @@ -66,14 +58,14 @@ public async Task PostCharacter(Guid id, [FromBody] Character cha /// User must be authenticated /// User is not authorized to read characters in this game /// Game not found - [HttpDelete("game/{id}/characters/unread", Name = nameof(ReadGameCharacters))] + [HttpDelete("game/{id:guid}/characters/unread", Name = nameof(ReadGameCharacters))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task ReadGameCharacters(Guid id) { - await characterApiService.MarkAsRead(id); + await characterApiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } @@ -83,9 +75,10 @@ public async Task ReadGameCharacters(Guid id) /// /// /// Character not found - [HttpGet("characters/{id}", Name = nameof(GetCharacter))] + [HttpGet("characters/{id:guid}", Name = nameof(GetCharacter))] [ProducesResponseType(typeof(Envelope), 200)] - public async Task GetCharacter(Guid id) => Ok(await characterApiService.Get(id)); + public async Task GetCharacter(Guid id) => + Ok(await characterApiService.Get(id, HttpContext.RequestAborted)); /// /// Put character changes @@ -97,7 +90,7 @@ public async Task ReadGameCharacters(Guid id) /// User must be authenticated /// User is not authorized to change some properties of this character /// Character not found - [HttpPatch("characters/{id}", Name = nameof(PutCharacter))] + [HttpPatch("characters/{id:guid}", Name = nameof(PutCharacter))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -105,7 +98,7 @@ public async Task ReadGameCharacters(Guid id) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutCharacter(Guid id, [FromBody] Character character) => - Ok(await characterApiService.Update(id, character)); + Ok(await characterApiService.Update(id, character, HttpContext.RequestAborted)); /// /// Delete certain character @@ -115,7 +108,7 @@ public async Task PutCharacter(Guid id, [FromBody] Character char /// User must be authenticated /// User is not allowed to remove the character /// Character not found - [HttpDelete("characters/{id}", Name = nameof(DeleteCharacter))] + [HttpDelete("characters/{id:guid}", Name = nameof(DeleteCharacter))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -123,7 +116,7 @@ public async Task PutCharacter(Guid id, [FromBody] Character char [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteCharacter(Guid id) { - await characterApiService.Delete(id); + await characterApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Gaming/CommentController.cs b/src/DM.Web.API/Controllers/v1/Gaming/CommentController.cs index a0ece12b..d5cc25eb 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/CommentController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/CommentController.cs @@ -14,20 +14,10 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1/games")] [ApiExplorerSettings(GroupName = "Game")] -public class CommentController : ControllerBase +public class CommentController( + ICommentApiService commentApiService, + ILikeApiService likeApiService) : ControllerBase { - private readonly ICommentApiService commentApiService; - private readonly ILikeApiService likeApiService; - - /// - public CommentController( - ICommentApiService commentApiService, - ILikeApiService likeApiService) - { - this.commentApiService = commentApiService; - this.likeApiService = likeApiService; - } - /// /// Get list of comments /// @@ -35,11 +25,11 @@ public CommentController( /// /// /// Game not found - [HttpGet("{id}/comments", Name = nameof(GetGameComments))] + [HttpGet("{id:guid}/comments", Name = nameof(GetGameComments))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetGameComments(Guid id, [FromQuery] PagingQuery q) => - Ok(await commentApiService.Get(id, q)); + Ok(await commentApiService.Get(id, q, HttpContext.RequestAborted)); /// /// Post new game comment @@ -51,7 +41,7 @@ public async Task GetGameComments(Guid id, [FromQuery] PagingQuer /// User must be authenticated /// User is not authorized to create a comment in this game /// Game not found - [HttpPost("{id}/comments", Name = nameof(PostGameComment))] + [HttpPost("{id:guid}/comments", Name = nameof(PostGameComment))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -60,7 +50,7 @@ public async Task GetGameComments(Guid id, [FromQuery] PagingQuer [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostGameComment(Guid id, [FromBody] Comment comment) { - var result = await commentApiService.Create(id, comment); + var result = await commentApiService.Create(id, comment, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetGameComment), new {id = result.Resource.Id}, result); } @@ -72,14 +62,14 @@ public async Task PostGameComment(Guid id, [FromBody] Comment com /// User must be authenticated /// User is not authorized to read comments in this game /// Game not found - [HttpDelete("{id}/comments/unread", Name = nameof(ReadGameComments))] + [HttpDelete("{id:guid}/comments/unread", Name = nameof(ReadGameComments))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task ReadGameComments(Guid id) { - await commentApiService.MarkAsRead(id); + await commentApiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } @@ -89,10 +79,11 @@ public async Task ReadGameComments(Guid id) /// /// /// Comment not found - [HttpGet("comments/{id}", Name = nameof(GetGameComment))] + [HttpGet("comments/{id:guid}", Name = nameof(GetGameComment))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetGameComment(Guid id) => Ok(await commentApiService.Get(id)); + public async Task GetGameComment(Guid id) => + Ok(await commentApiService.Get(id, HttpContext.RequestAborted)); /// /// Update comment @@ -104,7 +95,7 @@ public async Task ReadGameComments(Guid id) /// User must be authenticated /// User is not allowed to change this comment /// Comment not found - [HttpPatch("comments/{id}", Name = nameof(PutGameComment))] + [HttpPatch("comments/{id:guid}", Name = nameof(PutGameComment))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -112,7 +103,7 @@ public async Task ReadGameComments(Guid id) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutGameComment(Guid id, [FromBody] Comment comment) => - Ok(await commentApiService.Update(id, comment)); + Ok(await commentApiService.Update(id, comment, HttpContext.RequestAborted)); /// /// Delete comment @@ -122,7 +113,7 @@ public async Task PutGameComment(Guid id, [FromBody] Comment comm /// User must be authenticated /// User is not allowed to change this comment /// Comment not found - [HttpDelete("comments/{id}", Name = nameof(DeleteGameComment))] + [HttpDelete("comments/{id:guid}", Name = nameof(DeleteGameComment))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -130,7 +121,7 @@ public async Task PutGameComment(Guid id, [FromBody] Comment comm [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteGameComment(Guid id) { - await commentApiService.Delete(id); + await commentApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -143,7 +134,7 @@ public async Task DeleteGameComment(Guid id) /// User is not allowed to like the comment /// User already liked this comment /// Comment not found - [HttpPost("comments/{id}/likes", Name = nameof(PostGameCommentLike))] + [HttpPost("comments/{id:guid}/likes", Name = nameof(PostGameCommentLike))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -152,7 +143,7 @@ public async Task DeleteGameComment(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostGameCommentLike(Guid id) { - var result = await likeApiService.LikeComment(id); + var result = await likeApiService.LikeComment(id, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetGameComment), new {id}, result); } @@ -165,7 +156,7 @@ public async Task PostGameCommentLike(Guid id) /// User is not allowed to remove like from this comment /// User has no like for this comment /// Comment not found - [HttpDelete("comments/{id}/likes", Name = nameof(DeleteGameCommentLike))] + [HttpDelete("comments/{id:guid}/likes", Name = nameof(DeleteGameCommentLike))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -174,7 +165,7 @@ public async Task PostGameCommentLike(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteGameCommentLike(Guid id) { - await likeApiService.DislikeComment(id); + await likeApiService.DislikeComment(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Gaming/GameController.cs b/src/DM.Web.API/Controllers/v1/Gaming/GameController.cs index 9f6fe6d1..5085af79 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/GameController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/GameController.cs @@ -13,30 +13,19 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1/games")] [ApiExplorerSettings(GroupName = "Game")] -public class GameController : ControllerBase +public class GameController( + IGameApiService gameApiService, + IReaderApiService readerApiService, + IBlacklistApiService blacklistApiService) : ControllerBase { - private readonly IGameApiService gameApiService; - private readonly IReaderApiService readerApiService; - private readonly IBlacklistApiService blacklistApiService; - - /// - public GameController( - IGameApiService gameApiService, - IReaderApiService readerApiService, - IBlacklistApiService blacklistApiService) - { - this.gameApiService = gameApiService; - this.readerApiService = readerApiService; - this.blacklistApiService = blacklistApiService; - } - /// /// Get list of games /// /// [HttpGet(Name = nameof(GetGames))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetGames([FromQuery] GamesQuery q) => Ok(await gameApiService.Get(q)); + public async Task GetGames([FromQuery] GamesQuery q) => + Ok(await gameApiService.Get(q, HttpContext.RequestAborted)); /// /// Get list of user own games @@ -47,7 +36,8 @@ public GameController( [AuthenticationRequired] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] - public async Task GetOwnGames() => Ok(await gameApiService.GetOwn()); + public async Task GetOwnGames() => + Ok(await gameApiService.GetOwn(HttpContext.RequestAborted)); /// /// Get list of all game tags @@ -55,7 +45,8 @@ public GameController( /// [HttpGet("popular", Name = nameof(GetPopularGames))] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetPopularGames() => Ok(await gameApiService.GetPopular()); + public async Task GetPopularGames() => + Ok(await gameApiService.GetPopular(HttpContext.RequestAborted)); /// /// Get list of all game tags @@ -63,7 +54,8 @@ public GameController( /// [HttpGet("tags")] [ProducesResponseType(typeof(ListEnvelope), 200)] - public async Task GetTags() => Ok(await gameApiService.GetTags()); + public async Task GetTags() => + Ok(await gameApiService.GetTags(HttpContext.RequestAborted)); /// /// Get certain game @@ -71,10 +63,11 @@ public GameController( /// /// /// Game not found - [HttpGet("{id}", Name = nameof(GetGame))] + [HttpGet("{id:guid}", Name = nameof(GetGame))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetGame(Guid id) => Ok(await gameApiService.Get(id)); + public async Task GetGame(Guid id) => + Ok(await gameApiService.Get(id, HttpContext.RequestAborted)); /// /// Get certain game details @@ -82,10 +75,11 @@ public GameController( /// /// /// Game not found - [HttpGet("{id}/details", Name = nameof(GetGameDetails))] + [HttpGet("{id:guid}/details", Name = nameof(GetGameDetails))] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetGameDetails(Guid id) => Ok(await gameApiService.GetDetails(id)); + public async Task GetGameDetails(Guid id) => + Ok(await gameApiService.GetDetails(id, HttpContext.RequestAborted)); /// /// Post new game @@ -105,7 +99,7 @@ public GameController( [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostGame([FromBody] Game game) { - var result = await gameApiService.Create(game); + var result = await gameApiService.Create(game, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetGameDetails), new {id = result.Resource.Id}, result); } @@ -119,7 +113,7 @@ public async Task PostGame([FromBody] Game game) /// User must be authenticated /// User is not authorized to change some properties of this game /// Game not found - [HttpPatch("{id}/details", Name = nameof(PutGame))] + [HttpPatch("{id:guid}/details", Name = nameof(PutGame))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -127,7 +121,7 @@ public async Task PostGame([FromBody] Game game) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutGame(Guid id, [FromBody] Game game) => - Ok(await gameApiService.Update(id, game)); + Ok(await gameApiService.Update(id, game, HttpContext.RequestAborted)); /// /// Delete certain game @@ -136,7 +130,7 @@ public async Task PutGame(Guid id, [FromBody] Game game) => /// User must be authenticated /// User is not allowed to remove the game /// Game not found - [HttpDelete("{id}", Name = nameof(DeleteGame))] + [HttpDelete("{id:guid}", Name = nameof(DeleteGame))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -144,7 +138,7 @@ public async Task PutGame(Guid id, [FromBody] Game game) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteGame(Guid id) { - await gameApiService.Delete(id); + await gameApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -154,10 +148,11 @@ public async Task DeleteGame(Guid id) /// /// /// Game not found - [HttpGet("{id}/readers", Name = nameof(GetReaders))] + [HttpGet("{id:guid}/readers", Name = nameof(GetReaders))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetReaders(Guid id) => Ok(await readerApiService.Get(id)); + public async Task GetReaders(Guid id) => + Ok(await readerApiService.Get(id, HttpContext.RequestAborted)); /// /// Subscribe to the game as a reader @@ -168,15 +163,18 @@ public async Task DeleteGame(Guid id) /// User is not authorized to subscribe to this game /// User is already subscribed to this game /// Game not found - [HttpPost("{id}/readers", Name = nameof(PostReader))] + [HttpPost("{id:guid}/readers", Name = nameof(PostReader))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 409)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task PostReader(Guid id) => - CreatedAtRoute(nameof(GetGame), new {id}, await readerApiService.Subscribe(id)); + public async Task PostReader(Guid id) + { + var result = await readerApiService.Subscribe(id, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetGame), new { id }, result); + } /// /// Unsubscribe from the game as a reader @@ -187,7 +185,7 @@ public async Task PostReader(Guid id) => /// User is not authorized to unsubscribe from this game /// User is not subscribed to this game /// Game not found - [HttpDelete("{id}/readers", Name = nameof(DeleteReader))] + [HttpDelete("{id:guid}/readers", Name = nameof(DeleteReader))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -196,7 +194,7 @@ public async Task PostReader(Guid id) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteReader(Guid id) { - await readerApiService.Unsubscribe(id); + await readerApiService.Unsubscribe(id, HttpContext.RequestAborted); return NoContent(); } @@ -208,13 +206,14 @@ public async Task DeleteReader(Guid id) /// User must be authenticated /// User is not authorized to read blacklist of this game /// Game not found - [HttpGet("{id}/blacklist/users", Name = nameof(GetBlacklist))] + [HttpGet("{id:guid}/blacklist/users", Name = nameof(GetBlacklist))] [AuthenticationRequired] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetBlacklist(Guid id) => Ok(await blacklistApiService.Get(id)); + public async Task GetBlacklist(Guid id) => + Ok(await blacklistApiService.Get(id, HttpContext.RequestAborted)); /// /// Post new blacklisted user @@ -227,7 +226,7 @@ public async Task DeleteReader(Guid id) /// User is not authorized to blacklist users in this game /// User is already blacklisted /// Game not found - [HttpPost("{id}/blacklist/users", Name = nameof(PostBlacklist))] + [HttpPost("{id:guid}/blacklist/users", Name = nameof(PostBlacklist))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -237,7 +236,7 @@ public async Task DeleteReader(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostBlacklist(Guid id, [FromBody] User user) { - var result = await blacklistApiService.Create(id, user); + var result = await blacklistApiService.Create(id, user, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetBlacklist), new {id}, result); } @@ -251,7 +250,7 @@ public async Task PostBlacklist(Guid id, [FromBody] User user) /// User is not authorized to un-blacklist users in this game /// User is not in the blacklist /// Game not found - [HttpDelete("{id}/blacklist/users/{login}", Name = nameof(DeleteBlacklist))] + [HttpDelete("{id:guid}/blacklist/users/{login}", Name = nameof(DeleteBlacklist))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -260,7 +259,7 @@ public async Task PostBlacklist(Guid id, [FromBody] User user) [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteBlacklist(Guid id, string login) { - await blacklistApiService.Delete(id, login); + await blacklistApiService.Delete(id, login, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Controllers/v1/Gaming/PostController.cs b/src/DM.Web.API/Controllers/v1/Gaming/PostController.cs index 2a679a53..5d0a01ed 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/PostController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/PostController.cs @@ -13,17 +13,9 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1")] [ApiExplorerSettings(GroupName = "Game")] -public class PostController : ControllerBase +public class PostController( + IPostApiService postApiService) : ControllerBase { - private readonly IPostApiService postApiService; - - /// - public PostController( - IPostApiService postApiService) - { - this.postApiService = postApiService; - } - /// /// Get list of posts /// @@ -31,11 +23,11 @@ public PostController( /// /// /// Room not found - [HttpGet("rooms/{id}/posts", Name = nameof(GetPosts))] + [HttpGet("rooms/{id:guid}/posts", Name = nameof(GetPosts))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task GetPosts(Guid id, [FromQuery] PagingQuery q) => - Ok(await postApiService.Get(id, q)); + Ok(await postApiService.Get(id, q, HttpContext.RequestAborted)); /// /// Post new post @@ -47,7 +39,7 @@ public async Task GetPosts(Guid id, [FromQuery] PagingQuery q) => /// User must be authenticated /// User is not allowed to create post in this room /// Room not found - [HttpPost("rooms/{id}/posts", Name = nameof(PostPost))] + [HttpPost("rooms/{id:guid}/posts", Name = nameof(PostPost))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -56,9 +48,8 @@ public async Task GetPosts(Guid id, [FromQuery] PagingQuery q) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostPost(Guid id, [FromBody] Post post) { - var result = await postApiService.Create(id, post); - return CreatedAtRoute(nameof(GetPost), - new {id = result.Resource.Id}, result); + var result = await postApiService.Create(id, post, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetPost), new {id = result.Resource.Id}, result); } /// @@ -68,14 +59,14 @@ public async Task PostPost(Guid id, [FromBody] Post post) /// /// User must be authenticated /// Room not found - [HttpDelete("rooms/{id}/posts/unread", Name = nameof(MarkPostsAsRead))] + [HttpDelete("rooms/{id:guid}/posts/unread", Name = nameof(MarkPostsAsRead))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task MarkPostsAsRead(Guid id) { - await postApiService.MarkAsRead(id); + await postApiService.MarkAsRead(id, HttpContext.RequestAborted); return NoContent(); } @@ -85,9 +76,10 @@ public async Task MarkPostsAsRead(Guid id) /// /// /// Post not found - [HttpGet("posts/{id}", Name = nameof(GetPost))] + [HttpGet("posts/{id:guid}", Name = nameof(GetPost))] [ProducesResponseType(typeof(Envelope), 200)] - public async Task GetPost(Guid id) => Ok(await postApiService.Get(id)); + public async Task GetPost(Guid id) => + Ok(await postApiService.Get(id, HttpContext.RequestAborted)); /// /// Put post changes @@ -99,7 +91,7 @@ public async Task MarkPostsAsRead(Guid id) /// User must be authenticated /// User is not authorized to change some properties of this post /// Post not found - [HttpPatch("posts/{id}", Name = nameof(PutPost))] + [HttpPatch("posts/{id:guid}", Name = nameof(PutPost))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -107,7 +99,7 @@ public async Task MarkPostsAsRead(Guid id) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutPost(Guid id, [FromBody] Post post) => - Ok(await postApiService.Update(id, post)); + Ok(await postApiService.Update(id, post, HttpContext.RequestAborted)); /// /// Delete certain post @@ -117,7 +109,7 @@ public async Task PutPost(Guid id, [FromBody] Post post) => /// User must be authenticated /// User is not allowed to remove the post /// Post not found - [HttpDelete("posts/{id}", Name = nameof(DeletePost))] + [HttpDelete("posts/{id:guid}", Name = nameof(DeletePost))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -125,7 +117,7 @@ public async Task PutPost(Guid id, [FromBody] Post post) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeletePost(Guid id) { - await postApiService.Delete(id); + await postApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -134,7 +126,7 @@ public async Task DeletePost(Guid id) /// /// /// Post not found - [HttpGet("posts/{id}/votes", Name = nameof(GetPostVotes))] + [HttpGet("posts/{id:guid}/votes", Name = nameof(GetPostVotes))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] public Task GetPostVotes(Guid id) => throw new NotImplementedException(); @@ -148,7 +140,7 @@ public async Task DeletePost(Guid id) /// User is not allowed to vote for the post /// User already voted for this post /// Post not found - [HttpPost("posts/{id}/votes", Name = nameof(PostVote))] + [HttpPost("posts/{id:guid}/votes", Name = nameof(PostVote))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] diff --git a/src/DM.Web.API/Controllers/v1/Gaming/RoomController.cs b/src/DM.Web.API/Controllers/v1/Gaming/RoomController.cs index 5e286d50..32fd445f 100644 --- a/src/DM.Web.API/Controllers/v1/Gaming/RoomController.cs +++ b/src/DM.Web.API/Controllers/v1/Gaming/RoomController.cs @@ -12,33 +12,22 @@ namespace DM.Web.API.Controllers.v1.Gaming; [ApiController] [Route("v1")] [ApiExplorerSettings(GroupName = "Game")] -public class RoomController : ControllerBase +public class RoomController( + IRoomApiService roomApiService, + IRoomClaimApiService claimApiService, + IPendingPostApiService pendingPostApiService) : ControllerBase { - private readonly IRoomApiService roomApiService; - private readonly IRoomClaimApiService claimApiService; - private readonly IPendingPostApiService pendingPostApiService; - - /// - public RoomController( - IRoomApiService roomApiService, - IRoomClaimApiService claimApiService, - IPendingPostApiService pendingPostApiService) - { - this.roomApiService = roomApiService; - this.claimApiService = claimApiService; - this.pendingPostApiService = pendingPostApiService; - } - /// /// Get list of game rooms /// /// /// /// Game not found - [HttpGet("games/{id}/rooms", Name = nameof(GetRooms))] + [HttpGet("games/{id:guid}/rooms", Name = nameof(GetRooms))] [ProducesResponseType(typeof(ListEnvelope), 200)] [ProducesResponseType(typeof(GeneralError), 410)] - public async Task GetRooms(Guid id) => Ok(await roomApiService.GetAll(id)); + public async Task GetRooms(Guid id) => + Ok(await roomApiService.GetAll(id, HttpContext.RequestAborted)); /// /// Post new character @@ -50,7 +39,7 @@ public RoomController( /// User must be authenticated /// User is not authorized to create a room in this game /// Game not found - [HttpPost("games/{id}/rooms", Name = nameof(PostRoom))] + [HttpPost("games/{id:guid}/rooms", Name = nameof(PostRoom))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -59,9 +48,8 @@ public RoomController( [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostRoom(Guid id, [FromBody] Room room) { - var result = await roomApiService.Create(id, room); - return CreatedAtRoute(nameof(GetRoom), - new {id = result.Resource.Id}, result); + var result = await roomApiService.Create(id, room, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetRoom), new {id = result.Resource.Id}, result); } /// @@ -70,9 +58,10 @@ public async Task PostRoom(Guid id, [FromBody] Room room) /// /// /// Room not found - [HttpGet("rooms/{id}", Name = nameof(GetRoom))] + [HttpGet("rooms/{id:guid}", Name = nameof(GetRoom))] [ProducesResponseType(typeof(Envelope), 200)] - public async Task GetRoom(Guid id) => Ok(await roomApiService.Get(id)); + public async Task GetRoom(Guid id) => + Ok(await roomApiService.Get(id, HttpContext.RequestAborted)); /// /// Put room changes @@ -84,7 +73,7 @@ public async Task PostRoom(Guid id, [FromBody] Room room) /// User must be authenticated /// User is not authorized to change some properties of this room /// Room not found - [HttpPatch("rooms/{id}", Name = nameof(PutRoom))] + [HttpPatch("rooms/{id:guid}", Name = nameof(PutRoom))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -92,7 +81,7 @@ public async Task PostRoom(Guid id, [FromBody] Room room) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task PutRoom(Guid id, [FromBody] Room room) => - Ok(await roomApiService.Update(id, room)); + Ok(await roomApiService.Update(id, room, HttpContext.RequestAborted)); /// /// Delete certain room @@ -102,7 +91,7 @@ public async Task PutRoom(Guid id, [FromBody] Room room) => /// User must be authenticated /// User is not allowed to remove the room /// Room not found - [HttpDelete("rooms/{id}", Name = nameof(DeleteRoom))] + [HttpDelete("rooms/{id:guid}", Name = nameof(DeleteRoom))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -110,7 +99,7 @@ public async Task PutRoom(Guid id, [FromBody] Room room) => [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteRoom(Guid id) { - await roomApiService.Delete(id); + await roomApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -125,7 +114,7 @@ public async Task DeleteRoom(Guid id) /// User is not allowed to create claims in this room /// Claim already exists /// Room not found - [HttpPost("rooms/{id}/claims", Name = nameof(PostClaim))] + [HttpPost("rooms/{id:guid}/claims", Name = nameof(PostClaim))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -135,9 +124,8 @@ public async Task DeleteRoom(Guid id) [ProducesResponseType(typeof(GeneralError), 410)] public async Task PostClaim(Guid id, [FromBody] RoomClaim claim) { - var result = await claimApiService.Create(id, claim); - return CreatedAtRoute(nameof(GetRoom), - new {id}, result); + var result = await claimApiService.Create(id, claim, HttpContext.RequestAborted); + return CreatedAtRoute(nameof(GetRoom), new {id}, result); } /// @@ -150,7 +138,7 @@ public async Task PostClaim(Guid id, [FromBody] RoomClaim claim) /// User must be authenticated /// User is not allowed to update this claim /// Claim not found - [HttpPatch("rooms/claims/{id}", Name = nameof(UpdateClaim))] + [HttpPatch("rooms/claims/{id:guid}", Name = nameof(UpdateClaim))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 200)] [ProducesResponseType(typeof(BadRequestError), 400)] @@ -158,7 +146,7 @@ public async Task PostClaim(Guid id, [FromBody] RoomClaim claim) [ProducesResponseType(typeof(GeneralError), 403)] [ProducesResponseType(typeof(GeneralError), 410)] public async Task UpdateClaim(Guid id, [FromBody] RoomClaim claim) => - Ok(await claimApiService.Update(id, claim)); + Ok(await claimApiService.Update(id, claim, HttpContext.RequestAborted)); /// /// Delete room claim @@ -168,7 +156,7 @@ public async Task UpdateClaim(Guid id, [FromBody] RoomClaim claim /// User must be authenticated /// User is not allowed to delete this claim /// Claim not found - [HttpDelete("rooms/claims/{id}", Name = nameof(DeleteClaim))] + [HttpDelete("rooms/claims/{id:guid}", Name = nameof(DeleteClaim))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -176,7 +164,7 @@ public async Task UpdateClaim(Guid id, [FromBody] RoomClaim claim [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeleteClaim(Guid id) { - await claimApiService.Delete(id); + await claimApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } @@ -188,15 +176,15 @@ public async Task DeleteClaim(Guid id) /// /// Some of claim parameters were invalid /// User must be authenticated - /// User is not allowed to create post pendings in this room + /// User is not allowed to create post anticipations in this room /// Post pending already exists /// Room not found - [HttpPost("rooms/{id}/pendings", Name = nameof(CreatePendingPost))] + [HttpPost("rooms/{id:guid}/anticipations", Name = nameof(CreatePendingPost))] [AuthenticationRequired] [ProducesResponseType(typeof(Envelope), 201)] public async Task CreatePendingPost(Guid id, [FromBody] PendingPost pendingPost) { - var result = await pendingPostApiService.Create(id, pendingPost); + var result = await pendingPostApiService.Create(id, pendingPost, HttpContext.RequestAborted); return CreatedAtRoute(nameof(GetRoom), new {id}, result); } @@ -208,7 +196,7 @@ public async Task CreatePendingPost(Guid id, [FromBody] PendingPo /// User must be authenticated /// User is not allowed to delete this pending post /// Pending post not found - [HttpDelete("rooms/pendings/{id}", Name = nameof(DeletePendingPost))] + [HttpDelete("rooms/anticipations/{id:guid}", Name = nameof(DeletePendingPost))] [AuthenticationRequired] [ProducesResponseType(204)] [ProducesResponseType(typeof(GeneralError), 401)] @@ -216,7 +204,7 @@ public async Task CreatePendingPost(Guid id, [FromBody] PendingPo [ProducesResponseType(typeof(GeneralError), 410)] public async Task DeletePendingPost(Guid id) { - await pendingPostApiService.Delete(id); + await pendingPostApiService.Delete(id, HttpContext.RequestAborted); return NoContent(); } } \ No newline at end of file diff --git a/src/DM.Web.API/Notifications/NotificationHub.cs b/src/DM.Web.API/Notifications/NotificationHub.cs index 02a4dc91..135d8fa3 100644 --- a/src/DM.Web.API/Notifications/NotificationHub.cs +++ b/src/DM.Web.API/Notifications/NotificationHub.cs @@ -24,7 +24,7 @@ public override Task OnConnectedAsync() var (hasToken, token) = TryExtractAuthToken(); if (hasToken) { - connectionService.Add(token, Context.ConnectionId); + connectionService.Add(token, Context.ConnectionId, Context.ConnectionAborted); } return base.OnConnectedAsync(); @@ -36,7 +36,7 @@ public override Task OnDisconnectedAsync(Exception exception) var (hasToken, token) = TryExtractAuthToken(); if (hasToken) { - connectionService.Remove(token, Context.ConnectionId); + connectionService.Remove(token, Context.ConnectionId, Context.ConnectionAborted); } return base.OnDisconnectedAsync(exception); @@ -45,8 +45,8 @@ public override Task OnDisconnectedAsync(Exception exception) private (bool success, string token) TryExtractAuthToken() { string token; - if (!Context.GetHttpContext().Request.Query.TryGetValue("access_token", out var queryValues) || - !queryValues.Any() || string.IsNullOrEmpty(token = queryValues.First())) + if (Context.GetHttpContext()?.Request.Query.TryGetValue("access_token", out var queryValues) is not true || + queryValues.Count == 0 || string.IsNullOrEmpty(token = queryValues.First())) { return (false, null); } diff --git a/src/DM.Web.API/Services/Community/ChatApiService.cs b/src/DM.Web.API/Services/Community/ChatApiService.cs index fe7a9158..49ca31f2 100644 --- a/src/DM.Web.API/Services/Community/ChatApiService.cs +++ b/src/DM.Web.API/Services/Community/ChatApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Chat.Creating; @@ -11,42 +12,33 @@ namespace DM.Web.API.Services.Community; /// -internal class ChatApiService : IChatApiService +internal class ChatApiService( + IChatReadingService readingService, + IChatCreatingService creatingService, + IMapper mapper) : IChatApiService { - private readonly IChatReadingService readingService; - private readonly IChatCreatingService creatingService; - private readonly IMapper mapper; - - /// - public ChatApiService( - IChatReadingService readingService, - IChatCreatingService creatingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.mapper = mapper; - } - /// - public async Task> GetMessages(PagingQuery query) + public async Task> GetMessages( + PagingQuery query, CancellationToken cancellationToken) { - var (messages, paging) = await readingService.GetMessages(query); + var (messages, paging) = await readingService.GetMessages(query, cancellationToken); return new ListEnvelope(messages.Select(mapper.Map), new Paging(paging)); } /// - public async Task> CreateMessage(ChatMessage message) + public async Task> CreateMessage( + ChatMessage message, CancellationToken cancellationToken) { var createMessage = mapper.Map(message); - var createdMessage = await creatingService.Create(createMessage); + var createdMessage = await creatingService.Create(createMessage, cancellationToken); return new Envelope(mapper.Map(createdMessage)); } /// - public async Task> GetMessage(Guid id) + public async Task> GetMessage( + Guid id, CancellationToken cancellationToken) { - var message = await readingService.GetMessage(id); + var message = await readingService.GetMessage(id, cancellationToken); return new Envelope(mapper.Map(message)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/IChatApiService.cs b/src/DM.Web.API/Services/Community/IChatApiService.cs index c83b191f..b4f961c7 100644 --- a/src/DM.Web.API/Services/Community/IChatApiService.cs +++ b/src/DM.Web.API/Services/Community/IChatApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Web.API.Dto.Contracts; @@ -15,20 +16,23 @@ public interface IChatApiService /// Get list of chat messages /// /// Search query + /// /// - Task> GetMessages(PagingQuery query); + Task> GetMessages(PagingQuery query, CancellationToken cancellationToken); /// /// Create new chat message /// /// Message + /// /// - Task> CreateMessage(ChatMessage message); + Task> CreateMessage(ChatMessage message, CancellationToken cancellationToken); /// /// Get single chat message /// /// Message identifier + /// /// - Task> GetMessage(Guid id); + Task> GetMessage(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/IMessagingApiService.cs b/src/DM.Web.API/Services/Community/IMessagingApiService.cs index 16d23f36..465d9ddb 100644 --- a/src/DM.Web.API/Services/Community/IMessagingApiService.cs +++ b/src/DM.Web.API/Services/Community/IMessagingApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Web.API.Dto.Contracts; @@ -15,57 +16,67 @@ public interface IMessagingApiService /// Get list of user conversations /// /// Paging query + /// /// - Task> GetConversations(PagingQuery query); + Task> GetConversations(PagingQuery query, CancellationToken cancellationToken); /// /// Get single conversation /// /// Conversation identifier + /// /// - Task> GetConversation(Guid id); + Task> GetConversation(Guid id, CancellationToken cancellationToken); /// /// Get visavi conversation with user /// /// + /// /// - Task> GetConversation(string login); + Task> GetConversation(string login, CancellationToken cancellationToken); /// /// Get list of conversation messages /// /// Conversation identifier /// Paging query + /// /// - Task> GetMessages(Guid conversationId, PagingQuery query); + Task> GetMessages(Guid conversationId, PagingQuery query, + CancellationToken cancellationToken); /// /// Create new message /// /// Conversation identifier /// Message + /// /// - Task> CreateMessage(Guid conversationId, Message message); + Task> CreateMessage(Guid conversationId, Message message, + CancellationToken cancellationToken); /// /// Get single message /// /// Message identifier + /// /// - Task> GetMessage(Guid messageId); + Task> GetMessage(Guid messageId, CancellationToken cancellationToken); /// /// Delete single message /// /// Message identifier + /// /// - Task DeleteMessage(Guid messageId); + Task DeleteMessage(Guid messageId, CancellationToken cancellationToken); /// /// Mark all conversation messages as read /// /// Conversation identifier + /// /// - Task MarkAsRead(Guid conversationId); + Task MarkAsRead(Guid conversationId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/IPollApiService.cs b/src/DM.Web.API/Services/Community/IPollApiService.cs index b8009c37..22a30375 100644 --- a/src/DM.Web.API/Services/Community/IPollApiService.cs +++ b/src/DM.Web.API/Services/Community/IPollApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Community; using DM.Web.API.Dto.Contracts; @@ -14,28 +15,32 @@ public interface IPollApiService /// Get polls /// /// + /// /// - Task> Get(PollsQuery query); + Task> Get(PollsQuery query, CancellationToken cancellationToken); /// /// Get single poll /// /// + /// /// - Task> Get(Guid id); + Task> Get(Guid id, CancellationToken cancellationToken); /// /// Create new poll /// /// + /// /// - Task> Create(Poll poll); + Task> Create(Poll poll, CancellationToken cancellationToken); /// /// Vote for the poll option /// /// Poll identifier /// Option identifier + /// /// - Task> Vote(Guid pollId, Guid optionId); + Task> Vote(Guid pollId, Guid optionId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/IReviewApiService.cs b/src/DM.Web.API/Services/Community/IReviewApiService.cs index 4caefd79..9407e53e 100644 --- a/src/DM.Web.API/Services/Community/IReviewApiService.cs +++ b/src/DM.Web.API/Services/Community/IReviewApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Community; using DM.Web.API.Dto.Contracts; @@ -14,35 +15,40 @@ public interface IReviewApiService /// Get available reviews /// /// + /// /// - Task> Get(ReviewsQuery query); + Task> Get(ReviewsQuery query, CancellationToken cancellationToken); /// /// Get single review /// /// + /// /// - Task> Get(Guid id); + Task> Get(Guid id, CancellationToken cancellationToken); /// /// Create new review /// /// + /// /// - Task> Create(Review review); + Task> Create(Review review, CancellationToken cancellationToken); /// /// Update existing review /// /// /// + /// /// - Task> Update(Guid id, Review review); + Task> Update(Guid id, Review review, CancellationToken cancellationToken); /// /// Delete existing review /// /// + /// /// - Task Delete(Guid id); + Task Delete(Guid id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/MessagingApiService.cs b/src/DM.Web.API/Services/Community/MessagingApiService.cs index 934e72ab..744abd4d 100644 --- a/src/DM.Web.API/Services/Community/MessagingApiService.cs +++ b/src/DM.Web.API/Services/Community/MessagingApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Messaging.Creating; @@ -13,76 +14,67 @@ namespace DM.Web.API.Services.Community; /// -internal class MessagingApiService : IMessagingApiService +internal class MessagingApiService( + IConversationReadingService conversationReadingService, + IMessageReadingService messageReadingService, + IMessageCreatingService messageCreatingService, + IMessageDeletingService messageDeletingService, + IMapper mapper) : IMessagingApiService { - private readonly IConversationReadingService conversationReadingService; - private readonly IMessageReadingService messageReadingService; - private readonly IMessageCreatingService messageCreatingService; - private readonly IMessageDeletingService messageDeletingService; - private readonly IMapper mapper; - - /// - public MessagingApiService( - IConversationReadingService conversationReadingService, - IMessageReadingService messageReadingService, - IMessageCreatingService messageCreatingService, - IMessageDeletingService messageDeletingService, - IMapper mapper) - { - this.conversationReadingService = conversationReadingService; - this.messageReadingService = messageReadingService; - this.messageCreatingService = messageCreatingService; - this.messageDeletingService = messageDeletingService; - this.mapper = mapper; - } - /// - public async Task> GetConversations(PagingQuery query) + public async Task> GetConversations( + PagingQuery query, CancellationToken cancellationToken) { - var (conversations, paging) = await conversationReadingService.Get(query); + var (conversations, paging) = await conversationReadingService.Get(query, cancellationToken); return new ListEnvelope(conversations.Select(mapper.Map), new Paging(paging)); } /// - public async Task> GetConversation(Guid id) + public async Task> GetConversation( + Guid id, CancellationToken cancellationToken) { - var conversation = await conversationReadingService.Get(id); + var conversation = await conversationReadingService.Get(id, cancellationToken); return new Envelope(mapper.Map(conversation)); } /// - public async Task> GetConversation(string login) + public async Task> GetConversation( + string login, CancellationToken cancellationToken) { - var conversation = await conversationReadingService.GetOrCreate(login); + var conversation = await conversationReadingService.GetOrCreate(login, cancellationToken); return new Envelope(mapper.Map(conversation)); } /// - public async Task> GetMessages(Guid conversationId, PagingQuery query) + public async Task> GetMessages( + Guid conversationId, PagingQuery query, CancellationToken cancellationToken) { - var (messages, paging) = await messageReadingService.Get(conversationId, query); + var (messages, paging) = await messageReadingService.Get(conversationId, query, cancellationToken); return new ListEnvelope(messages.Select(mapper.Map), new Paging(paging)); } /// - public async Task> CreateMessage(Guid conversationId, Message message) + public async Task> CreateMessage( + Guid conversationId, Message message, CancellationToken cancellationToken) { var createMessage = mapper.Map(message); createMessage.ConversationId = conversationId; - var createdMessage = await messageCreatingService.Create(createMessage); + var createdMessage = await messageCreatingService.Create(createMessage, cancellationToken); return new Envelope(mapper.Map(createdMessage)); } /// - public async Task> GetMessage(Guid messageId) + public async Task> GetMessage(Guid messageId, CancellationToken cancellationToken) { - var message = await messageReadingService.Get(messageId); + var message = await messageReadingService.Get(messageId, cancellationToken); return new Envelope(mapper.Map(message)); } /// - public Task DeleteMessage(Guid messageId) => messageDeletingService.Delete(messageId); + public Task DeleteMessage(Guid messageId, CancellationToken cancellationToken) => + messageDeletingService.Delete(messageId, cancellationToken); /// - public Task MarkAsRead(Guid conversationId) => conversationReadingService.MarkAsRead(conversationId); + public Task MarkAsRead(Guid conversationId, CancellationToken cancellationToken) => + conversationReadingService.MarkAsRead(conversationId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/PollApiService.cs b/src/DM.Web.API/Services/Community/PollApiService.cs index ecde193b..f4ed6071 100644 --- a/src/DM.Web.API/Services/Community/PollApiService.cs +++ b/src/DM.Web.API/Services/Community/PollApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Polls.Creating; @@ -12,52 +13,38 @@ namespace DM.Web.API.Services.Community; /// -internal class PollApiService : IPollApiService +internal class PollApiService( + IPollReadingService readingService, + IPollCreatingService creatingService, + IPollVotingService votingService, + IMapper mapper) : IPollApiService { - private readonly IPollReadingService readingService; - private readonly IPollCreatingService creatingService; - private readonly IPollVotingService votingService; - private readonly IMapper mapper; - - /// - public PollApiService( - IPollReadingService readingService, - IPollCreatingService creatingService, - IPollVotingService votingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.votingService = votingService; - this.mapper = mapper; - } - /// - public async Task> Get(PollsQuery query) + public async Task> Get(PollsQuery query, CancellationToken cancellationToken) { - var (polls, paging) = await readingService.Get(query, query.OnlyActive); + var (polls, paging) = await readingService.Get(query, query.OnlyActive, cancellationToken); return new ListEnvelope(polls.Select(mapper.Map), new Paging(paging)); } /// - public async Task> Get(Guid id) + public async Task> Get(Guid id, CancellationToken cancellationToken) { - var poll = await readingService.Get(id); + var poll = await readingService.Get(id, cancellationToken); return new Envelope(mapper.Map(poll)); } /// - public async Task> Create(Poll poll) + public async Task> Create(Poll poll, CancellationToken cancellationToken) { var createPoll = mapper.Map(poll); - var createdPoll = await creatingService.Create(createPoll); + var createdPoll = await creatingService.Create(createPoll, cancellationToken); return new Envelope(mapper.Map(createdPoll)); } /// - public async Task> Vote(Guid pollId, Guid optionId) + public async Task> Vote(Guid pollId, Guid optionId, CancellationToken cancellationToken) { - var poll = await votingService.Vote(pollId, optionId); + var poll = await votingService.Vote(pollId, optionId, cancellationToken); return new Envelope(mapper.Map(poll)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Community/ReviewApiService.cs b/src/DM.Web.API/Services/Community/ReviewApiService.cs index 70e32d0f..7e7ea90f 100644 --- a/src/DM.Web.API/Services/Community/ReviewApiService.cs +++ b/src/DM.Web.API/Services/Community/ReviewApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Reviews.Creating; @@ -13,60 +14,45 @@ namespace DM.Web.API.Services.Community; /// -internal class ReviewApiService : IReviewApiService +internal class ReviewApiService( + IReviewReadingService readingService, + IReviewCreatingService creatingService, + IReviewUpdatingService updatingService, + IReviewDeletingService deletingService, + IMapper mapper) : IReviewApiService { - private readonly IReviewReadingService readingService; - private readonly IReviewCreatingService creatingService; - private readonly IReviewUpdatingService updatingService; - private readonly IReviewDeletingService deletingService; - private readonly IMapper mapper; - - /// - public ReviewApiService( - IReviewReadingService readingService, - IReviewCreatingService creatingService, - IReviewUpdatingService updatingService, - IReviewDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(ReviewsQuery query) + public async Task> Get(ReviewsQuery query, CancellationToken cancellationToken) { - var (reviews, paging) = await readingService.Get(query, query.OnlyApproved); + var (reviews, paging) = await readingService.Get(query, query.OnlyApproved, cancellationToken); return new ListEnvelope(reviews.Select(mapper.Map), new Paging(paging)); } /// - public async Task> Get(Guid id) + public async Task> Get(Guid id, CancellationToken cancellationToken) { - var review = await readingService.Get(id); + var review = await readingService.Get(id, cancellationToken); return new Envelope(mapper.Map(review)); } /// - public async Task> Create(Review review) + public async Task> Create(Review review, CancellationToken cancellationToken) { var createReview = mapper.Map(review); - var createdReview = await creatingService.Create(createReview); + var createdReview = await creatingService.Create(createReview, cancellationToken); return new Envelope(mapper.Map(createdReview)); } /// - public async Task> Update(Guid id, Review review) + public async Task> Update(Guid id, Review review, CancellationToken cancellationToken) { var updateReview = mapper.Map(review); updateReview.ReviewId = id; - var updatedReview = await updatingService.Update(updateReview); + var updatedReview = await updatingService.Update(updateReview, cancellationToken); return new Envelope(mapper.Map(updatedReview)); } /// - public Task Delete(Guid id) => deletingService.Delete(id); + public Task Delete(Guid id, CancellationToken cancellationToken) => + deletingService.Delete(id, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/CommentApiService.cs b/src/DM.Web.API/Services/Fora/CommentApiService.cs index 8830fb6d..f063bb07 100644 --- a/src/DM.Web.API/Services/Fora/CommentApiService.cs +++ b/src/DM.Web.API/Services/Fora/CommentApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Common.Dto; @@ -14,67 +15,57 @@ namespace DM.Web.API.Services.Fora; /// -internal class CommentApiService : ICommentApiService +internal class CommentApiService( + ICommentaryReadingService readingService, + ICommentaryCreatingService creatingService, + ICommentaryUpdatingService updatingService, + ICommentaryDeletingService deletingService, + IMapper mapper) : ICommentApiService { - private readonly ICommentaryReadingService readingService; - private readonly ICommentaryCreatingService creatingService; - private readonly ICommentaryUpdatingService updatingService; - private readonly ICommentaryDeletingService deletingService; - private readonly IMapper mapper; - - /// - public CommentApiService( - ICommentaryReadingService readingService, - ICommentaryCreatingService creatingService, - ICommentaryUpdatingService updatingService, - ICommentaryDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(Guid topicId, PagingQuery query) + public async Task> Get( + Guid topicId, PagingQuery query, CancellationToken cancellationToken) { - var (comments, paging) = await readingService.Get(topicId, query); + var (comments, paging) = await readingService.Get(topicId, query, cancellationToken); return new ListEnvelope(comments.Select(mapper.Map), new Paging(paging)); } /// - public async Task> Create(Guid topicId, Comment comment) + public async Task> Create( + Guid topicId, Comment comment, CancellationToken cancellationToken) { var createComment = mapper.Map(comment); createComment.EntityId = topicId; - var createdComment = await creatingService.Create(createComment); + var createdComment = await creatingService.Create(createComment, cancellationToken); return new Envelope(mapper.Map(createdComment)); } /// - public async Task> Get(Guid commentId) + public async Task> Get(Guid commentId, CancellationToken cancellationToken) { - var comment = await readingService.Get(commentId); + var comment = await readingService.Get(commentId, cancellationToken); return new Envelope(mapper.Map(comment)); } /// - public async Task> Update(Guid commentId, Comment comment) + public async Task> Update( + Guid commentId, Comment comment, CancellationToken cancellationToken) { var updateComment = mapper.Map(comment); updateComment.CommentId = commentId; - var updatedComment = await updatingService.Update(updateComment); + var updatedComment = await updatingService.Update(updateComment, cancellationToken); return new Envelope(mapper.Map(updatedComment)); } /// - public Task Delete(Guid commentId) => deletingService.Delete(commentId); + public Task Delete(Guid commentId, CancellationToken cancellationToken) => + deletingService.Delete(commentId, cancellationToken); /// - public Task MarkAsRead(Guid topicId) => readingService.MarkAsRead(topicId); + public Task MarkAsRead(Guid topicId, CancellationToken cancellationToken) => + readingService.MarkAsRead(topicId, cancellationToken); /// - public Task MarkAsRead(string forumId) => readingService.MarkAsRead(forumId); + public Task MarkAsRead(string forumId, CancellationToken cancellationToken) => + readingService.MarkAsRead(forumId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/ForumApiService.cs b/src/DM.Web.API/Services/Fora/ForumApiService.cs index 67b5caa7..84a667ea 100644 --- a/src/DM.Web.API/Services/Fora/ForumApiService.cs +++ b/src/DM.Web.API/Services/Fora/ForumApiService.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Forum.BusinessProcesses.Fora; @@ -8,31 +9,22 @@ namespace DM.Web.API.Services.Fora; /// -internal class ForumApiService : IForumApiService +internal class ForumApiService( + IForumReadingService forumService, + IMapper mapper) : IForumApiService { - private readonly IForumReadingService forumService; - private readonly IMapper mapper; - - /// - public ForumApiService( - IForumReadingService forumService, - IMapper mapper) - { - this.forumService = forumService; - this.mapper = mapper; - } - + /// /// - public async Task> Get() + public async Task> Get(CancellationToken cancellationToken) { - var fora = await forumService.GetForaList(); + var fora = await forumService.GetForaList(cancellationToken); return new ListEnvelope(fora.Select(mapper.Map)); } /// - public async Task> Get(string id) + public async Task> Get(string id, CancellationToken cancellationToken) { - var forum = await forumService.GetSingleForum(id); + var forum = await forumService.GetSingleForum(id, cancellationToken); return new Envelope(mapper.Map(forum)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/ICommentApiService.cs b/src/DM.Web.API/Services/Fora/ICommentApiService.cs index 10060048..8aa91d0a 100644 --- a/src/DM.Web.API/Services/Fora/ICommentApiService.cs +++ b/src/DM.Web.API/Services/Fora/ICommentApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Web.API.Dto.Contracts; @@ -16,50 +17,57 @@ public interface ICommentApiService /// /// Topic identifier /// Paging query + /// /// Envelope of commentaries list - Task> Get(Guid topicId, PagingQuery query); + Task> Get(Guid topicId, PagingQuery query, CancellationToken cancellationToken); /// /// Create new comment /// /// Topic identifier /// Comment model + /// /// Envelope of created comment - Task> Create(Guid topicId, Comment comment); + Task> Create(Guid topicId, Comment comment, CancellationToken cancellationToken); /// /// Get comment by identifier /// /// Comment identifier + /// /// - Task> Get(Guid commentId); + Task> Get(Guid commentId, CancellationToken cancellationToken); /// /// Update comment by API DTO model /// /// Comment identifier /// Comment DTO model + /// /// - Task> Update(Guid commentId, Comment comment); + Task> Update(Guid commentId, Comment comment, CancellationToken cancellationToken); /// /// Delete comment /// /// Comment identifier + /// /// - Task Delete(Guid commentId); + Task Delete(Guid commentId, CancellationToken cancellationToken); /// /// Mark topic comments as read /// /// Topic identifier + /// /// - Task MarkAsRead(Guid topicId); + Task MarkAsRead(Guid topicId, CancellationToken cancellationToken); /// /// Mark all forum comments as read /// /// Forum identifier + /// /// - Task MarkAsRead(string forumId); + Task MarkAsRead(string forumId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/IForumApiService.cs b/src/DM.Web.API/Services/Fora/IForumApiService.cs index a66b6f67..f8d0b787 100644 --- a/src/DM.Web.API/Services/Fora/IForumApiService.cs +++ b/src/DM.Web.API/Services/Fora/IForumApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Fora; @@ -12,13 +13,15 @@ public interface IForumApiService /// /// Get list of available fora /// + /// /// Envelope with fora list - Task> Get(); + Task> Get(CancellationToken cancellationToken); /// /// Get forum by id /// /// Forum id + /// /// Envelope with forum - Task> Get(string id); + Task> Get(string id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/ILikeApiService.cs b/src/DM.Web.API/Services/Fora/ILikeApiService.cs index 247aee4d..421e5cd2 100644 --- a/src/DM.Web.API/Services/Fora/ILikeApiService.cs +++ b/src/DM.Web.API/Services/Fora/ILikeApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,27 +15,31 @@ public interface ILikeApiService /// Like the topic /// /// Topic identifier + /// /// Envelope for user who just liked the topic - Task> LikeTopic(Guid topicId); + Task> LikeTopic(Guid topicId, CancellationToken cancellationToken); /// /// Remove user's like from topic /// /// Topic identifier + /// /// - Task DislikeTopic(Guid topicId); + Task DislikeTopic(Guid topicId, CancellationToken cancellationToken); /// /// Like the commentary /// /// Commentary identifier + /// /// Envelope for user who just liked the commentary - Task> LikeComment(Guid commentId); + Task> LikeComment(Guid commentId, CancellationToken cancellationToken); /// /// Remove user's like from commentary /// /// Commentary identifier + /// /// - Task DislikeComment(Guid commentId); + Task DislikeComment(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/IModeratorsApiService.cs b/src/DM.Web.API/Services/Fora/IModeratorsApiService.cs index 345aef4e..17d04390 100644 --- a/src/DM.Web.API/Services/Fora/IModeratorsApiService.cs +++ b/src/DM.Web.API/Services/Fora/IModeratorsApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -13,6 +14,7 @@ public interface IModeratorsApiService /// Get list of forum moderators /// /// Forum id + /// /// Envelope of moderators list - Task> GetModerators(string id); + Task> GetModerators(string id, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/ITopicApiService.cs b/src/DM.Web.API/Services/Fora/ITopicApiService.cs index 37cf521b..eaf9d97e 100644 --- a/src/DM.Web.API/Services/Fora/ITopicApiService.cs +++ b/src/DM.Web.API/Services/Fora/ITopicApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Fora; @@ -15,36 +16,41 @@ public interface ITopicApiService /// /// Forum identifier /// Search query + /// /// Envelope of topics list - Task> Get(string forumId, TopicsQuery query); + Task> Get(string forumId, TopicsQuery query, CancellationToken cancellationToken); /// /// Get topic /// /// Topic identifier + /// /// Envelope of topic - Task> Get(Guid topicId); + Task> Get(Guid topicId, CancellationToken cancellationToken); /// /// Create new topic /// /// Forum identifier /// Topic model + /// /// Envelope of created topic - Task> Create(string forumId, Topic topic); + Task> Create(string forumId, Topic topic, CancellationToken cancellationToken); /// /// Updates topic /// /// Topic identifier /// Topic model + /// /// Envelop of updated topic - Task> Update(Guid topicId, Topic topic); + Task> Update(Guid topicId, Topic topic, CancellationToken cancellationToken); /// /// Removes topic /// /// Topic identifier + /// /// - Task Delete(Guid topicId); + Task Delete(Guid topicId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/LikeApiService.cs b/src/DM.Web.API/Services/Fora/LikeApiService.cs index 57e870c8..353951b0 100644 --- a/src/DM.Web.API/Services/Fora/LikeApiService.cs +++ b/src/DM.Web.API/Services/Fora/LikeApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Forum.BusinessProcesses.Likes; @@ -8,37 +9,29 @@ namespace DM.Web.API.Services.Fora; /// -internal class LikeApiService : ILikeApiService +internal class LikeApiService( + ILikeService likeService, + IMapper mapper) : ILikeApiService { - private readonly ILikeService likeService; - private readonly IMapper mapper; - - /// - public LikeApiService( - ILikeService likeService, - IMapper mapper) - { - this.likeService = likeService; - this.mapper = mapper; - } - /// - public async Task> LikeTopic(Guid topicId) + public async Task> LikeTopic(Guid topicId, CancellationToken cancellationToken) { - var likedByUser = await likeService.LikeTopic(topicId); + var likedByUser = await likeService.LikeTopic(topicId, cancellationToken); return new Envelope(mapper.Map(likedByUser)); } /// - public Task DislikeTopic(Guid topicId) => likeService.DislikeTopic(topicId); + public Task DislikeTopic(Guid topicId, CancellationToken cancellationToken) => + likeService.DislikeTopic(topicId, cancellationToken); /// - public async Task> LikeComment(Guid commentId) + public async Task> LikeComment(Guid commentId, CancellationToken cancellationToken) { - var likedByUser = await likeService.LikeComment(commentId); + var likedByUser = await likeService.LikeComment(commentId, cancellationToken); return new Envelope(mapper.Map(likedByUser)); } /// - public Task DislikeComment(Guid commentId) => likeService.DislikeComment(commentId); + public Task DislikeComment(Guid commentId, CancellationToken cancellationToken) => + likeService.DislikeComment(commentId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/ModeratorsApiService.cs b/src/DM.Web.API/Services/Fora/ModeratorsApiService.cs index cabea00c..cb41a799 100644 --- a/src/DM.Web.API/Services/Fora/ModeratorsApiService.cs +++ b/src/DM.Web.API/Services/Fora/ModeratorsApiService.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Forum.BusinessProcesses.Moderation; @@ -8,24 +9,14 @@ namespace DM.Web.API.Services.Fora; /// -internal class ModeratorsApiService : IModeratorsApiService +internal class ModeratorsApiService( + IModeratorsReadingService moderatorsReadingService, + IMapper mapper) : IModeratorsApiService { - private readonly IModeratorsReadingService moderatorsReadingService; - private readonly IMapper mapper; - - /// - public ModeratorsApiService( - IModeratorsReadingService moderatorsReadingService, - IMapper mapper) - { - this.moderatorsReadingService = moderatorsReadingService; - this.mapper = mapper; - } - /// - public async Task> GetModerators(string id) + public async Task> GetModerators(string id, CancellationToken cancellationToken) { - var moderators = await moderatorsReadingService.GetModerators(id); + var moderators = await moderatorsReadingService.GetModerators(id, cancellationToken); return new ListEnvelope(moderators.Select(mapper.Map)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Fora/TopicApiService.cs b/src/DM.Web.API/Services/Fora/TopicApiService.cs index 45d66e59..fce9febc 100644 --- a/src/DM.Web.API/Services/Fora/TopicApiService.cs +++ b/src/DM.Web.API/Services/Fora/TopicApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Forum.BusinessProcesses.Topics.Creating; @@ -15,64 +16,50 @@ namespace DM.Web.API.Services.Fora; /// -internal class TopicApiService : ITopicApiService +internal class TopicApiService( + ITopicReadingService topicReadingService, + ITopicCreatingService topicCreatingService, + ITopicUpdatingService topicUpdatingService, + ITopicDeletingService topicDeletingService, + IMapper mapper) : ITopicApiService { - private readonly ITopicReadingService topicReadingService; - private readonly ITopicCreatingService topicCreatingService; - private readonly ITopicUpdatingService topicUpdatingService; - private readonly ITopicDeletingService topicDeletingService; - private readonly IMapper mapper; - - /// - public TopicApiService( - ITopicReadingService topicReadingService, - ITopicCreatingService topicCreatingService, - ITopicUpdatingService topicUpdatingService, - ITopicDeletingService topicDeletingService, - IMapper mapper) - { - this.topicReadingService = topicReadingService; - this.topicCreatingService = topicCreatingService; - this.topicUpdatingService = topicUpdatingService; - this.topicDeletingService = topicDeletingService; - this.mapper = mapper; - } - /// - public async Task> Get(string forumId, TopicsQuery query) + public async Task> Get( + string forumId, TopicsQuery query, CancellationToken cancellationToken) { var (topics, paging) = query.Attached - ? (await topicReadingService.GetAttachedTopics(forumId), null) - : await topicReadingService.GetTopicsList(forumId, mapper.Map(query)); + ? (await topicReadingService.GetAttachedTopics(forumId, cancellationToken), null) + : await topicReadingService.GetTopicsList(forumId, mapper.Map(query), cancellationToken); return new ListEnvelope(topics.Select(mapper.Map), paging == null ? null : new Paging(paging)); } /// - public async Task> Get(Guid topicId) + public async Task> Get(Guid topicId, CancellationToken cancellationToken) { - var topic = await topicReadingService.GetTopic(topicId); + var topic = await topicReadingService.GetTopic(topicId, cancellationToken); return new Envelope(mapper.Map(topic)); } /// - public async Task> Create(string forumId, Topic topic) + public async Task> Create(string forumId, Topic topic, CancellationToken cancellationToken) { var createTopic = mapper.Map(topic); createTopic.ForumTitle = forumId; - var createdTopic = await topicCreatingService.CreateTopic(createTopic); + var createdTopic = await topicCreatingService.CreateTopic(createTopic, cancellationToken); return new Envelope(mapper.Map(createdTopic)); } /// - public async Task> Update(Guid topicId, Topic topic) + public async Task> Update(Guid topicId, Topic topic, CancellationToken cancellationToken) { var updateTopic = mapper.Map(topic); updateTopic.TopicId = topicId; - var updatedTopic = await topicUpdatingService.UpdateTopic(updateTopic); + var updatedTopic = await topicUpdatingService.UpdateTopic(updateTopic, cancellationToken); return new Envelope(mapper.Map(updatedTopic)); } /// - public Task Delete(Guid topicId) => topicDeletingService.DeleteTopic(topicId); + public Task Delete(Guid topicId, CancellationToken cancellationToken) => + topicDeletingService.DeleteTopic(topicId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/BlacklistApiService.cs b/src/DM.Web.API/Services/Gaming/BlacklistApiService.cs index 2c570624..4c8916fd 100644 --- a/src/DM.Web.API/Services/Gaming/BlacklistApiService.cs +++ b/src/DM.Web.API/Services/Gaming/BlacklistApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Blacklist.Creating; @@ -12,43 +13,29 @@ namespace DM.Web.API.Services.Gaming; /// -internal class BlacklistApiService : IBlacklistApiService +internal class BlacklistApiService( + IBlacklistReadingService readingService, + IBlacklistCreatingService creatingService, + IBlacklistDeletingService deletingService, + IMapper mapper) : IBlacklistApiService { - private readonly IBlacklistReadingService readingService; - private readonly IBlacklistCreatingService creatingService; - private readonly IBlacklistDeletingService deletingService; - private readonly IMapper mapper; - - /// - public BlacklistApiService( - IBlacklistReadingService readingService, - IBlacklistCreatingService creatingService, - IBlacklistDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(Guid gameId) + public async Task> Get(Guid gameId, CancellationToken cancellationToken) { - var users = await readingService.Get(gameId); + var users = await readingService.Get(gameId, cancellationToken); return new ListEnvelope(users.Select(mapper.Map)); } /// - public async Task> Create(Guid gameId, User user) + public async Task> Create(Guid gameId, User user, CancellationToken cancellationToken) { var createBlacklistLink = mapper.Map(user); createBlacklistLink.GameId = gameId; - var result = await creatingService.Create(createBlacklistLink); + var result = await creatingService.Create(createBlacklistLink, cancellationToken); return new Envelope(mapper.Map(result)); } /// - public Task Delete(Guid gameId, string login) => - deletingService.Delete(new OperateBlacklistLink {GameId = gameId, Login = login}); + public Task Delete(Guid gameId, string login, CancellationToken cancellationToken) => + deletingService.Delete(new OperateBlacklistLink {GameId = gameId, Login = login}, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/CharacterApiService.cs b/src/DM.Web.API/Services/Gaming/CharacterApiService.cs index 95f1326e..8989ff1a 100644 --- a/src/DM.Web.API/Services/Gaming/CharacterApiService.cs +++ b/src/DM.Web.API/Services/Gaming/CharacterApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Characters.Creating; @@ -13,64 +14,52 @@ namespace DM.Web.API.Services.Gaming; /// -internal class CharacterApiService : ICharacterApiService +internal class CharacterApiService( + ICharacterReadingService readingService, + ICharacterCreatingService creatingService, + ICharacterUpdatingService updatingService, + ICharacterDeletingService deletingService, + IMapper mapper) : ICharacterApiService { - private readonly ICharacterReadingService readingService; - private readonly ICharacterCreatingService creatingService; - private readonly ICharacterUpdatingService updatingService; - private readonly ICharacterDeletingService deletingService; - private readonly IMapper mapper; - - /// - public CharacterApiService( - ICharacterReadingService readingService, - ICharacterCreatingService creatingService, - ICharacterUpdatingService updatingService, - ICharacterDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> GetAll(Guid gameId) + public async Task> GetAll(Guid gameId, CancellationToken cancellationToken) { - var characters = await readingService.GetCharacters(gameId); + var characters = await readingService.GetCharacters(gameId, cancellationToken); return new ListEnvelope(characters.Select(mapper.Map)); } /// - public async Task> Get(Guid characterId) + public async Task> Get(Guid characterId, CancellationToken cancellationToken) { - var character = await readingService.GetCharacter(characterId); + var character = await readingService.GetCharacter(characterId, cancellationToken); return new Envelope(mapper.Map(character)); } /// - public async Task> Create(Guid gameId, Character character) + public async Task> Create( + Guid gameId, Character character, CancellationToken cancellationToken) { var createCharacter = mapper.Map(character); createCharacter.GameId = gameId; - var createdCharacter = await creatingService.Create(createCharacter); + var createdCharacter = await creatingService.Create(createCharacter, cancellationToken); return new Envelope(mapper.Map(createdCharacter)); } /// - public async Task> Update(Guid characterId, Character character) + public async Task> Update( + Guid characterId, Character character, CancellationToken cancellationToken) { var updateCharacter = mapper.Map(character); updateCharacter.CharacterId = characterId; - var updatedCharacter = await updatingService.Update(updateCharacter); + var updatedCharacter = await updatingService.Update(updateCharacter, cancellationToken); return new Envelope(mapper.Map(updatedCharacter)); } /// - public Task Delete(Guid characterId) => deletingService.Delete(characterId); + public Task Delete(Guid characterId, CancellationToken cancellationToken) => + deletingService.Delete(characterId, cancellationToken); /// - public Task MarkAsRead(Guid gameId) => readingService.MarkAsRead(gameId); + public Task MarkAsRead(Guid gameId, CancellationToken cancellationToken) => + readingService.MarkAsRead(gameId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/CommentApiService.cs b/src/DM.Web.API/Services/Gaming/CommentApiService.cs index 352814c0..e34aceb1 100644 --- a/src/DM.Web.API/Services/Gaming/CommentApiService.cs +++ b/src/DM.Web.API/Services/Gaming/CommentApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Common.Dto; @@ -14,64 +15,53 @@ namespace DM.Web.API.Services.Gaming; /// -internal class CommentApiService : ICommentApiService +internal class CommentApiService( + ICommentaryReadingService readingService, + ICommentaryCreatingService creatingService, + ICommentaryUpdatingService updatingService, + ICommentaryDeletingService deletingService, + IMapper mapper) : ICommentApiService { - private readonly ICommentaryReadingService readingService; - private readonly ICommentaryCreatingService creatingService; - private readonly ICommentaryUpdatingService updatingService; - private readonly ICommentaryDeletingService deletingService; - private readonly IMapper mapper; - - /// - public CommentApiService( - ICommentaryReadingService readingService, - ICommentaryCreatingService creatingService, - ICommentaryUpdatingService updatingService, - ICommentaryDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(Guid gameId, PagingQuery query) + public async Task> Get( + Guid gameId, PagingQuery query, CancellationToken cancellationToken) { - var (comments, paging, _) = await readingService.Get(gameId, query); + var (comments, paging, _) = await readingService.Get(gameId, query, cancellationToken); return new ListEnvelope(comments.Select(mapper.Map), new Paging(paging)); } /// - public async Task> Create(Guid gameId, Comment comment) + public async Task> Create( + Guid gameId, Comment comment, CancellationToken cancellationToken) { var createComment = mapper.Map(comment); createComment.EntityId = gameId; - var createdComment = await creatingService.Create(createComment); + var createdComment = await creatingService.Create(createComment, cancellationToken); return new Envelope(mapper.Map(createdComment)); } /// - public async Task> Get(Guid commentId) + public async Task> Get(Guid commentId, CancellationToken cancellationToken) { - var comment = await readingService.Get(commentId); + var comment = await readingService.Get(commentId, cancellationToken); return new Envelope(mapper.Map(comment)); } /// - public async Task> Update(Guid commentId, Comment comment) + public async Task> Update( + Guid commentId, Comment comment, CancellationToken cancellationToken) { var updateComment = mapper.Map(comment); updateComment.CommentId = commentId; - var updatedComment = await updatingService.Update(updateComment); + var updatedComment = await updatingService.Update(updateComment, cancellationToken); return new Envelope(mapper.Map(updatedComment)); } /// - public Task Delete(Guid commentId) => deletingService.Delete(commentId); + public Task Delete(Guid commentId, CancellationToken cancellationToken) => + deletingService.Delete(commentId, cancellationToken); /// - public Task MarkAsRead(Guid gameId) => readingService.MarkAsRead(gameId); + public Task MarkAsRead(Guid gameId, CancellationToken cancellationToken) => + readingService.MarkAsRead(gameId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/GameApiService.cs b/src/DM.Web.API/Services/Gaming/GameApiService.cs index 863c9b01..71d2a1a3 100644 --- a/src/DM.Web.API/Services/Gaming/GameApiService.cs +++ b/src/DM.Web.API/Services/Gaming/GameApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Games.Creating; @@ -16,89 +17,77 @@ namespace DM.Web.API.Services.Gaming; /// -internal class GameApiService : IGameApiService +internal class GameApiService( + IGameReadingService readingService, + IGameCreatingService creatingService, + IGameUpdatingService updatingService, + IGameDeletingService deletingService, + IMapper mapper) : IGameApiService { - private readonly IGameReadingService readingService; - private readonly IGameCreatingService creatingService; - private readonly IGameUpdatingService updatingService; - private readonly IGameDeletingService deletingService; - private readonly IMapper mapper; - - /// - public GameApiService( - IGameReadingService readingService, - IGameCreatingService creatingService, - IGameUpdatingService updatingService, - IGameDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(GameApiQuery gamesQuery) + public async Task> Get(GameApiQuery gamesQuery, CancellationToken cancellationToken) { var query = mapper.Map(gamesQuery); - var (games, paging) = await readingService.GetGames(query); + var (games, paging) = await readingService.GetGames(query, cancellationToken); return new ListEnvelope(games.Select(mapper.Map), new Paging(paging)); } + /// /// - public async Task> GetOwn() + public async Task> GetOwn(CancellationToken cancellationToken) { - var games = await readingService.GetOwnGames(); + var games = await readingService.GetOwnGames(cancellationToken); return new ListEnvelope(games.Select(mapper.Map)); } + /// /// - public async Task> GetPopular() + public async Task> GetPopular(CancellationToken cancellationToken) { - var games = await readingService.GetPopularGames(); + var games = await readingService.GetPopularGames(cancellationToken); return new ListEnvelope(games.Select(mapper.Map)); } /// - public async Task> Get(Guid gameId) + public async Task> Get(Guid gameId, CancellationToken cancellationToken) { - var game = await readingService.GetGame(gameId); + var game = await readingService.GetGame(gameId, cancellationToken); return new Envelope(mapper.Map(game)); } /// - public async Task> GetDetails(Guid gameId) + public async Task> GetDetails(Guid gameId, CancellationToken cancellationToken) { - var game = await readingService.GetGameDetails(gameId); + var game = await readingService.GetGameDetails(gameId, cancellationToken); return new Envelope(mapper.Map(game)); } /// - public async Task> Create(Game game) + public async Task> Create(Game game, CancellationToken cancellationToken) { var createGame = mapper.Map(game); - var createdGame = await creatingService.Create(createGame); + var createdGame = await creatingService.Create(createGame, cancellationToken); return new Envelope(mapper.Map(createdGame)); } /// - public async Task> Update(Guid gameId, Game game) + public async Task> Update(Guid gameId, Game game, CancellationToken cancellationToken) { var updateGame = mapper.Map(game); updateGame.GameId = gameId; - var updatedGame = await updatingService.Update(updateGame); + var updatedGame = await updatingService.Update(updateGame, cancellationToken); return new Envelope(mapper.Map(updatedGame)); } /// - public Task Delete(Guid gameId) => deletingService.DeleteGame(gameId); + public Task Delete(Guid gameId, CancellationToken cancellationToken) => + deletingService.DeleteGame(gameId, cancellationToken); + /// /// - public async Task> GetTags() + public async Task> GetTags(CancellationToken cancellationToken) { - var tags = await readingService.GetTags(); + var tags = await readingService.GetTags(cancellationToken); return new ListEnvelope(tags.Select(mapper.Map)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/IBlacklistApiService.cs b/src/DM.Web.API/Services/Gaming/IBlacklistApiService.cs index e73d23e4..e6b83225 100644 --- a/src/DM.Web.API/Services/Gaming/IBlacklistApiService.cs +++ b/src/DM.Web.API/Services/Gaming/IBlacklistApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,22 +15,25 @@ public interface IBlacklistApiService /// Get list of blacklisted users for the game /// /// Game identifier + /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); /// /// Add user to the game blacklist /// /// Game identifier /// User to blacklist + /// /// - Task> Create(Guid gameId, User user); + Task> Create(Guid gameId, User user, CancellationToken cancellationToken); /// /// Remove user from the blacklist /// /// Game identifier /// User login + /// /// - Task Delete(Guid gameId, string login); + Task Delete(Guid gameId, string login, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/ICharacterApiService.cs b/src/DM.Web.API/Services/Gaming/ICharacterApiService.cs index cfa994e8..3e35656e 100644 --- a/src/DM.Web.API/Services/Gaming/ICharacterApiService.cs +++ b/src/DM.Web.API/Services/Gaming/ICharacterApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games; @@ -14,43 +15,49 @@ public interface ICharacterApiService /// Get list of game characters /// /// Game identifier + /// /// - Task> GetAll(Guid gameId); + Task> GetAll(Guid gameId, CancellationToken cancellationToken); /// /// Get single character /// /// Character identifier + /// /// - Task> Get(Guid characterId); + Task> Get(Guid characterId, CancellationToken cancellationToken); /// /// Create new character /// /// Game identifier /// Character API model + /// /// - Task> Create(Guid gameId, Character character); + Task> Create(Guid gameId, Character character, CancellationToken cancellationToken); /// /// Update existing character /// /// Character identifier /// Character API model + /// /// - Task> Update(Guid characterId, Character character); + Task> Update(Guid characterId, Character character, CancellationToken cancellationToken); /// /// Delete existing character /// /// Character identifier + /// /// - Task Delete(Guid characterId); + Task Delete(Guid characterId, CancellationToken cancellationToken); /// /// Mark all characters as read /// /// Game identifier + /// /// - Task MarkAsRead(Guid gameId); + Task MarkAsRead(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/ICommentApiService.cs b/src/DM.Web.API/Services/Gaming/ICommentApiService.cs index 76123bd0..c209165e 100644 --- a/src/DM.Web.API/Services/Gaming/ICommentApiService.cs +++ b/src/DM.Web.API/Services/Gaming/ICommentApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Web.API.Dto.Contracts; @@ -16,43 +17,49 @@ public interface ICommentApiService /// /// Game identifier /// Paging query + /// /// Envelope of commentaries list - Task> Get(Guid gameId, PagingQuery query); + Task> Get(Guid gameId, PagingQuery query, CancellationToken cancellationToken); /// /// Create new comment /// /// Game identifier /// Comment model + /// /// Envelope of created comment - Task> Create(Guid gameId, Comment comment); + Task> Create(Guid gameId, Comment comment, CancellationToken cancellationToken); /// /// Get comment by identifier /// /// Comment identifier + /// /// - Task> Get(Guid commentId); + Task> Get(Guid commentId, CancellationToken cancellationToken); /// /// Update comment by API DTO model /// /// Comment identifier /// Comment DTO model + /// /// - Task> Update(Guid commentId, Comment comment); + Task> Update(Guid commentId, Comment comment, CancellationToken cancellationToken); /// /// Delete comment /// /// Comment identifier + /// /// - Task Delete(Guid commentId); + Task Delete(Guid commentId, CancellationToken cancellationToken); /// /// Mark all game comments as read /// /// + /// /// - Task MarkAsRead(Guid gameId); + Task MarkAsRead(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/IGameApiService.cs b/src/DM.Web.API/Services/Gaming/IGameApiService.cs index 3af18465..8c0e363e 100644 --- a/src/DM.Web.API/Services/Gaming/IGameApiService.cs +++ b/src/DM.Web.API/Services/Gaming/IGameApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games; @@ -15,60 +16,69 @@ public interface IGameApiService /// Get list of searched games /// /// Search query + /// /// Envelope for games list - Task> Get(GamesQuery gamesQuery); + Task> Get(GamesQuery gamesQuery, CancellationToken cancellationToken); /// /// Get user owned games /// + /// /// - Task> GetOwn(); + Task> GetOwn(CancellationToken cancellationToken); /// /// Get most popular games /// + /// /// - Task> GetPopular(); + Task> GetPopular(CancellationToken cancellationToken); /// /// Get certain game /// /// Game identifier + /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); /// /// Get certain game details /// /// Game identifier + /// /// - Task> GetDetails(Guid gameId); + Task> GetDetails(Guid gameId, CancellationToken cancellationToken); /// /// Create new game /// /// Game API model + /// /// Envelope for created game - Task> Create(Game game); + Task> Create(Game game, CancellationToken cancellationToken); /// /// Update existing game /// /// Game identifier /// Game API model + /// /// Envelope for updated game - Task> Update(Guid gameId, Game game); + Task> Update(Guid gameId, Game game, CancellationToken cancellationToken); /// /// Delete existing game /// /// Game identifier + /// /// - Task Delete(Guid gameId); + Task Delete(Guid gameId, CancellationToken cancellationToken); /// /// Get all available game tags /// + /// /// - Task> GetTags(); + Task> GetTags(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/ILikeApiService.cs b/src/DM.Web.API/Services/Gaming/ILikeApiService.cs index 35eaa633..15ad35c8 100644 --- a/src/DM.Web.API/Services/Gaming/ILikeApiService.cs +++ b/src/DM.Web.API/Services/Gaming/ILikeApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,13 +15,15 @@ public interface ILikeApiService /// Like the commentary /// /// Commentary identifier + /// /// Envelope for user who just liked the commentary - Task> LikeComment(Guid commentId); + Task> LikeComment(Guid commentId, CancellationToken cancellationToken); /// /// Remove user's like from commentary /// /// Commentary identifier + /// /// - Task DislikeComment(Guid commentId); + Task DislikeComment(Guid commentId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/IPostApiService.cs b/src/DM.Web.API/Services/Gaming/IPostApiService.cs index 3e3fd593..087768b9 100644 --- a/src/DM.Web.API/Services/Gaming/IPostApiService.cs +++ b/src/DM.Web.API/Services/Gaming/IPostApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Core.Dto; using DM.Web.API.Dto.Contracts; @@ -16,42 +17,47 @@ public interface IPostApiService /// /// Room identifier /// Search query + /// /// - Task> Get(Guid roomId, PagingQuery query); + Task> Get(Guid roomId, PagingQuery query, CancellationToken cancellationToken); /// /// Get single post /// /// Post identifier + /// /// - Task> Get(Guid postId); + Task> Get(Guid postId, CancellationToken cancellationToken); /// /// Create new post /// /// Room identifier /// Post model + /// /// - Task> Create(Guid roomId, Post post); + Task> Create(Guid roomId, Post post, CancellationToken cancellationToken); /// /// Update existing post /// /// Post identifier /// Post model + /// /// - Task> Update(Guid postId, Post post); + Task> Update(Guid postId, Post post, CancellationToken cancellationToken); /// /// Delete existing post /// /// Post identifier + /// /// - Task Delete(Guid postId); + Task Delete(Guid postId, CancellationToken cancellationToken); /// /// Mark all room posts as read /// /// - Task MarkAsRead(Guid roomId); + Task MarkAsRead(Guid roomId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/IReaderApiService.cs b/src/DM.Web.API/Services/Gaming/IReaderApiService.cs index 180113af..975a06d0 100644 --- a/src/DM.Web.API/Services/Gaming/IReaderApiService.cs +++ b/src/DM.Web.API/Services/Gaming/IReaderApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,19 +15,21 @@ public interface IReaderApiService /// Get list of game readers /// /// - Task> Get(Guid gameId); + Task> Get(Guid gameId, CancellationToken cancellationToken); /// /// Subscribe to a game as a reader /// /// Game identifier + /// /// - Task> Subscribe(Guid gameId); + Task> Subscribe(Guid gameId, CancellationToken cancellationToken); /// /// Unsubscribe from a game /// /// Game identifier + /// /// - Task Unsubscribe(Guid gameId); + Task Unsubscribe(Guid gameId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/ISchemaApiService.cs b/src/DM.Web.API/Services/Gaming/ISchemaApiService.cs index cb7f19b0..f75d9629 100644 --- a/src/DM.Web.API/Services/Gaming/ISchemaApiService.cs +++ b/src/DM.Web.API/Services/Gaming/ISchemaApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games.Attributes; @@ -13,35 +14,41 @@ public interface ISchemaApiService /// /// Get all available attribute schemas /// + /// /// - Task> Get(); + Task> Get(CancellationToken cancellationToken); /// /// Get single attribute schema /// /// Schema identifier + /// /// - Task> Get(Guid schemaId); + Task> Get(Guid schemaId, CancellationToken cancellationToken); /// /// Create new attribute schema /// /// Schema DTO + /// /// - Task> Create(AttributeSchema schema); + Task> Create(AttributeSchema schema, CancellationToken cancellationToken); /// /// Update existing attribute schema /// /// Schema identifier /// Schema DTO + /// /// - Task> Update(Guid schemaId, AttributeSchema schema); + Task> Update(Guid schemaId, AttributeSchema schema, + CancellationToken cancellationToken); /// /// Delete existing attribute schema /// /// + /// /// - Task Delete(Guid schemaId); + Task Delete(Guid schemaId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/LikeApiService.cs b/src/DM.Web.API/Services/Gaming/LikeApiService.cs index 3431f78e..b2c28801 100644 --- a/src/DM.Web.API/Services/Gaming/LikeApiService.cs +++ b/src/DM.Web.API/Services/Gaming/LikeApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Likes; @@ -8,27 +9,18 @@ namespace DM.Web.API.Services.Gaming; /// -internal class LikeApiService : ILikeApiService +internal class LikeApiService( + ILikeService likeService, + IMapper mapper) : ILikeApiService { - private readonly ILikeService likeService; - private readonly IMapper mapper; - - /// - public LikeApiService( - ILikeService likeService, - IMapper mapper) - { - this.likeService = likeService; - this.mapper = mapper; - } - /// - public async Task> LikeComment(Guid commentId) + public async Task> LikeComment(Guid commentId, CancellationToken cancellationToken) { - var user = await likeService.LikeComment(commentId); + var user = await likeService.LikeComment(commentId, cancellationToken); return new Envelope(mapper.Map(user)); } /// - public Task DislikeComment(Guid commentId) => likeService.DislikeComment(commentId); + public Task DislikeComment(Guid commentId, CancellationToken cancellationToken) => + likeService.DislikeComment(commentId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/PostApiService.cs b/src/DM.Web.API/Services/Gaming/PostApiService.cs index 1aafd840..23f7deb1 100644 --- a/src/DM.Web.API/Services/Gaming/PostApiService.cs +++ b/src/DM.Web.API/Services/Gaming/PostApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Core.Dto; @@ -14,64 +15,51 @@ namespace DM.Web.API.Services.Gaming; /// -internal class PostApiService : IPostApiService +internal class PostApiService( + IPostReadingService readingService, + IPostCreatingService creatingService, + IPostUpdatingService updatingService, + IPostDeletingService deletingService, + IMapper mapper) : IPostApiService { - private readonly IPostReadingService readingService; - private readonly IPostCreatingService creatingService; - private readonly IPostUpdatingService updatingService; - private readonly IPostDeletingService deletingService; - private readonly IMapper mapper; - - /// - public PostApiService( - IPostReadingService readingService, - IPostCreatingService creatingService, - IPostUpdatingService updatingService, - IPostDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Get(Guid roomId, PagingQuery query) + public async Task> Get( + Guid roomId, PagingQuery query, CancellationToken cancellationToken) { - var (posts, paging) = await readingService.Get(roomId, query); + var (posts, paging) = await readingService.Get(roomId, query, cancellationToken); return new ListEnvelope(posts.Select(mapper.Map), new Paging(paging)); } /// - public async Task> Get(Guid postId) + public async Task> Get(Guid postId, CancellationToken cancellationToken) { - var post = await readingService.Get(postId); + var post = await readingService.Get(postId, cancellationToken); return new Envelope(mapper.Map(post)); } /// - public async Task> Create(Guid roomId, Post post) + public async Task> Create(Guid roomId, Post post, CancellationToken cancellationToken) { var createPost = mapper.Map(post); createPost.RoomId = roomId; - var createdPost = await creatingService.Create(createPost); + var createdPost = await creatingService.Create(createPost, cancellationToken); return new Envelope(mapper.Map(createdPost)); } /// - public async Task> Update(Guid postId, Post post) + public async Task> Update(Guid postId, Post post, CancellationToken cancellationToken) { var updatePost = mapper.Map(post); updatePost.PostId = postId; - var updatedPost = await updatingService.Update(updatePost); + var updatedPost = await updatingService.Update(updatePost, cancellationToken); return new Envelope(mapper.Map(updatedPost)); } /// - public Task Delete(Guid postId) => deletingService.Delete(postId); + public Task Delete(Guid postId, CancellationToken cancellationToken) => + deletingService.Delete(postId, cancellationToken); /// - public Task MarkAsRead(Guid roomId) => readingService.MarkAsRead(roomId); + public Task MarkAsRead(Guid roomId, CancellationToken cancellationToken) => + readingService.MarkAsRead(roomId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/ReaderApiService.cs b/src/DM.Web.API/Services/Gaming/ReaderApiService.cs index 8f231bd6..1741b12d 100644 --- a/src/DM.Web.API/Services/Gaming/ReaderApiService.cs +++ b/src/DM.Web.API/Services/Gaming/ReaderApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Readers.Reading; @@ -10,37 +11,26 @@ namespace DM.Web.API.Services.Gaming; /// -internal class ReaderApiService : IReaderApiService +internal class ReaderApiService( + IReadersReadingService readingService, + IReadingSubscribingService subscribingService, + IMapper mapper) : IReaderApiService { - private readonly IReadersReadingService readingService; - private readonly IReadingSubscribingService subscribingService; - private readonly IMapper mapper; - - /// - public ReaderApiService( - IReadersReadingService readingService, - IReadingSubscribingService subscribingService, - IMapper mapper) - { - this.readingService = readingService; - this.subscribingService = subscribingService; - this.mapper = mapper; - } - /// - public async Task> Get(Guid gameId) + public async Task> Get(Guid gameId, CancellationToken cancellationToken) { - var readers = await readingService.Get(gameId); + var readers = await readingService.Get(gameId, cancellationToken); return new ListEnvelope(readers.Select(mapper.Map)); } /// - public async Task> Subscribe(Guid gameId) + public async Task> Subscribe(Guid gameId, CancellationToken cancellationToken) { - var reader = await subscribingService.Subscribe(gameId); + var reader = await subscribingService.Subscribe(gameId, cancellationToken); return new Envelope(mapper.Map(reader)); } /// - public Task Unsubscribe(Guid gameId) => subscribingService.Unsubscribe(gameId); + public Task Unsubscribe(Guid gameId, CancellationToken cancellationToken) => + subscribingService.Unsubscribe(gameId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/IPendingPostApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/IPendingPostApiService.cs index 2a5b1bb7..2830d172 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/IPendingPostApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/IPendingPostApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games; @@ -15,13 +16,16 @@ public interface IPendingPostApiService /// /// Room identifier /// API DTO model + /// /// - Task> Create(Guid roomId, PendingPost pendingPost); + Task> Create(Guid roomId, PendingPost pendingPost, + CancellationToken cancellationToken); /// /// Delete existing pending post /// /// Pending post identifier + /// /// - Task Delete(Guid pendingPostId); + Task Delete(Guid pendingPostId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/IRoomApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/IRoomApiService.cs index 88d45438..3edabc8d 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/IRoomApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/IRoomApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games; @@ -14,36 +15,41 @@ public interface IRoomApiService /// Get list of all available game rooms /// /// Game identifier + /// /// - Task> GetAll(Guid gameId); + Task> GetAll(Guid gameId, CancellationToken cancellationToken); /// /// Get single room /// /// Room identifier + /// /// - Task> Get(Guid roomId); + Task> Get(Guid roomId, CancellationToken cancellationToken); /// /// Create new room /// /// Game identifier /// Room model + /// /// - Task> Create(Guid gameId, Room room); + Task> Create(Guid gameId, Room room, CancellationToken cancellationToken); /// /// Update existing room /// /// Room identifier /// Room model + /// /// - Task> Update(Guid roomId, Room room); + Task> Update(Guid roomId, Room room, CancellationToken cancellationToken); /// /// Delete existing room /// /// Room identifier + /// /// - Task Delete(Guid roomId); + Task Delete(Guid roomId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/IRoomClaimApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/IRoomClaimApiService.cs index a8e3aa60..c79b429f 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/IRoomClaimApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/IRoomClaimApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Games; @@ -15,21 +16,24 @@ public interface IRoomClaimApiService /// /// Room identifier /// Claim + /// /// - Task> Create(Guid roomId, RoomClaim claim); + Task> Create(Guid roomId, RoomClaim claim, CancellationToken cancellationToken); /// /// Update existing room claim /// /// Claim identifier /// Claim + /// /// - Task> Update(Guid claimId, RoomClaim claim); + Task> Update(Guid claimId, RoomClaim claim, CancellationToken cancellationToken); /// /// Delete existing room claim /// /// + /// /// - Task Delete(Guid claimId); + Task Delete(Guid claimId, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/PendingPostApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/PendingPostApiService.cs index b8574e3b..4e201045 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/PendingPostApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/PendingPostApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Pending.Creating; @@ -10,32 +11,22 @@ namespace DM.Web.API.Services.Gaming.Rooms; /// -internal class PendingPostApiService : IPendingPostApiService +internal class PendingPostApiService( + IPendingPostCreatingService creatingService, + IPendingPostDeletingService deletingService, + IMapper mapper) : IPendingPostApiService { - private readonly IPendingPostCreatingService creatingService; - private readonly IPendingPostDeletingService deletingService; - private readonly IMapper mapper; - - /// - public PendingPostApiService( - IPendingPostCreatingService creatingService, - IPendingPostDeletingService deletingService, - IMapper mapper) - { - this.creatingService = creatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Create(Guid roomId, PendingPost pendingPost) + public async Task> Create( + Guid roomId, PendingPost pendingPost, CancellationToken cancellationToken) { var createPendingPost = mapper.Map(pendingPost); createPendingPost.RoomId = roomId; - var createdPendingPost = await creatingService.Create(createPendingPost); + var createdPendingPost = await creatingService.Create(createPendingPost, cancellationToken); return new Envelope(mapper.Map(createdPendingPost)); } /// - public Task Delete(Guid pendingPostId) => deletingService.Delete(pendingPostId); + public Task Delete(Guid pendingPostId, CancellationToken cancellationToken) => + deletingService.Delete(pendingPostId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/RoomApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/RoomApiService.cs index 2684a3b4..6d556473 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/RoomApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/RoomApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Rooms.Creating; @@ -13,61 +14,46 @@ namespace DM.Web.API.Services.Gaming.Rooms; /// -internal class RoomApiService : IRoomApiService +internal class RoomApiService( + IRoomReadingService readingService, + IRoomCreatingService creatingService, + IRoomUpdatingService updatingService, + IRoomDeletingService deletingService, + IMapper mapper) : IRoomApiService { - private readonly IRoomReadingService readingService; - private readonly IRoomCreatingService creatingService; - private readonly IRoomUpdatingService updatingService; - private readonly IRoomDeletingService deletingService; - private readonly IMapper mapper; - - /// - public RoomApiService( - IRoomReadingService readingService, - IRoomCreatingService creatingService, - IRoomUpdatingService updatingService, - IRoomDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> GetAll(Guid gameId) + public async Task> GetAll(Guid gameId, CancellationToken cancellationToken) { - var rooms = await readingService.GetAll(gameId); + var rooms = await readingService.GetAll(gameId, cancellationToken); return new ListEnvelope(rooms.Select(mapper.Map)); } /// - public async Task> Get(Guid roomId) + public async Task> Get(Guid roomId, CancellationToken cancellationToken) { - var room = await readingService.Get(roomId); + var room = await readingService.Get(roomId, cancellationToken); return new Envelope(mapper.Map(room)); } /// - public async Task> Create(Guid gameId, Room room) + public async Task> Create(Guid gameId, Room room, CancellationToken cancellationToken) { var createRoom = mapper.Map(room); createRoom.GameId = gameId; - var createdRoom = await creatingService.Create(createRoom); + var createdRoom = await creatingService.Create(createRoom, cancellationToken); return new Envelope(mapper.Map(createdRoom)); } /// - public async Task> Update(Guid roomId, Room room) + public async Task> Update(Guid roomId, Room room, CancellationToken cancellationToken) { var updateRoom = mapper.Map(room); updateRoom.RoomId = roomId; - var updatedRoom = await updatingService.Update(updateRoom); + var updatedRoom = await updatingService.Update(updateRoom, cancellationToken); return new Envelope(mapper.Map(updatedRoom)); } /// - public Task Delete(Guid roomId) => deletingService.Delete(roomId); + public Task Delete(Guid roomId, CancellationToken cancellationToken) => + deletingService.Delete(roomId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/Rooms/RoomClaimApiService.cs b/src/DM.Web.API/Services/Gaming/Rooms/RoomClaimApiService.cs index 1be0eab9..e5efb02e 100644 --- a/src/DM.Web.API/Services/Gaming/Rooms/RoomClaimApiService.cs +++ b/src/DM.Web.API/Services/Gaming/Rooms/RoomClaimApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Claims.Creating; @@ -11,44 +12,33 @@ namespace DM.Web.API.Services.Gaming.Rooms; /// -internal class RoomClaimApiService : IRoomClaimApiService +internal class RoomClaimApiService( + IRoomClaimsCreatingService creatingService, + IRoomClaimsUpdatingService updatingService, + IRoomClaimsDeletingService deletingService, + IMapper mapper) : IRoomClaimApiService { - private readonly IRoomClaimsCreatingService creatingService; - private readonly IRoomClaimsUpdatingService updatingService; - private readonly IRoomClaimsDeletingService deletingService; - private readonly IMapper mapper; - - /// - public RoomClaimApiService( - IRoomClaimsCreatingService creatingService, - IRoomClaimsUpdatingService updatingService, - IRoomClaimsDeletingService deletingService, - IMapper mapper) - { - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - /// - public async Task> Create(Guid roomId, RoomClaim claim) + public async Task> Create( + Guid roomId, RoomClaim claim, CancellationToken cancellationToken) { var createRoomClaim = mapper.Map(claim); createRoomClaim.RoomId = roomId; - var createdRoomClaim = await creatingService.Create(createRoomClaim); + var createdRoomClaim = await creatingService.Create(createRoomClaim, cancellationToken); return new Envelope(mapper.Map(createdRoomClaim)); } /// - public async Task> Update(Guid claimId, RoomClaim claim) + public async Task> Update( + Guid claimId, RoomClaim claim, CancellationToken cancellationToken) { var updateRoomClaim = mapper.Map(claim); updateRoomClaim.ClaimId = claimId; - var updatedRoomClaim = await updatingService.Update(updateRoomClaim); + var updatedRoomClaim = await updatingService.Update(updateRoomClaim, cancellationToken); return new Envelope(mapper.Map(updatedRoomClaim)); } /// - public Task Delete(Guid claimId) => deletingService.Delete(claimId); + public Task Delete(Guid claimId, CancellationToken cancellationToken) => + deletingService.Delete(claimId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Gaming/SchemaApiService.cs b/src/DM.Web.API/Services/Gaming/SchemaApiService.cs index 2423611f..43a7dfb9 100644 --- a/src/DM.Web.API/Services/Gaming/SchemaApiService.cs +++ b/src/DM.Web.API/Services/Gaming/SchemaApiService.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Gaming.BusinessProcesses.Schemas.Creating; @@ -13,60 +14,48 @@ namespace DM.Web.API.Services.Gaming; /// -internal class SchemaApiService : ISchemaApiService +internal class SchemaApiService( + ISchemaReadingService readingService, + ISchemaCreatingService creatingService, + ISchemaUpdatingService updatingService, + ISchemaDeletingService deletingService, + IMapper mapper) : ISchemaApiService { - private readonly ISchemaReadingService readingService; - private readonly ISchemaCreatingService creatingService; - private readonly ISchemaUpdatingService updatingService; - private readonly ISchemaDeletingService deletingService; - private readonly IMapper mapper; - - /// - public SchemaApiService( - ISchemaReadingService readingService, - ISchemaCreatingService creatingService, - ISchemaUpdatingService updatingService, - ISchemaDeletingService deletingService, - IMapper mapper) - { - this.readingService = readingService; - this.creatingService = creatingService; - this.updatingService = updatingService; - this.deletingService = deletingService; - this.mapper = mapper; - } - + /// /// - public async Task> Get() + public async Task> Get(CancellationToken cancellationToken) { - var schemata = await readingService.Get(); + var schemata = await readingService.Get(cancellationToken); return new ListEnvelope(schemata.Select(mapper.Map)); } /// - public async Task> Get(Guid schemaId) + public async Task> Get(Guid schemaId, CancellationToken cancellationToken) { - var schema = await readingService.Get(schemaId); + var schema = await readingService.Get(schemaId, cancellationToken); return new Envelope(mapper.Map(schema)); } /// - public async Task> Create(AttributeSchema schema) + public async Task> Create( + AttributeSchema schema, CancellationToken cancellationToken) { var createSchema = mapper.Map(schema); - var createdSchema = await creatingService.Create(createSchema); + var createdSchema = await creatingService.Create(createSchema, cancellationToken); return new Envelope(mapper.Map(createdSchema)); } /// - public async Task> Update(Guid schemaId, AttributeSchema schema) + public async Task> Update( + Guid schemaId, AttributeSchema schema, CancellationToken cancellationToken) { var updateSchema = mapper.Map(schema); updateSchema.Id = schemaId; - var updatedSchema = await updatingService.Update(updateSchema); + var updatedSchema = await updatingService.Update(updateSchema, cancellationToken); return new Envelope(mapper.Map(updatedSchema)); } /// - public Task Delete(Guid schemaId) => deletingService.Delete(schemaId); + public Task Delete(Guid schemaId, CancellationToken cancellationToken) => + deletingService.Delete(schemaId, cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/ActivationApiService.cs b/src/DM.Web.API/Services/Users/ActivationApiService.cs index 5732c673..0738a644 100644 --- a/src/DM.Web.API/Services/Users/ActivationApiService.cs +++ b/src/DM.Web.API/Services/Users/ActivationApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Authentication.Implementation; @@ -9,28 +10,16 @@ namespace DM.Web.API.Services.Users; /// -internal class ActivationApiService : IActivationApiService +internal class ActivationApiService( + IActivationService activationService, + IAuthenticationService authenticationService, + IMapper mapper) : IActivationApiService { - private readonly IActivationService activationService; - private readonly IAuthenticationService authenticationService; - private readonly IMapper mapper; - - /// - public ActivationApiService( - IActivationService activationService, - IAuthenticationService authenticationService, - IMapper mapper) - { - this.activationService = activationService; - this.authenticationService = authenticationService; - this.mapper = mapper; - } - /// - public async Task> Activate(Guid token) + public async Task> Activate(Guid token, CancellationToken cancellationToken) { - var userId = await activationService.Activate(token); - var identity = await authenticationService.Authenticate(userId); + var userId = await activationService.Activate(token, cancellationToken); + var identity = await authenticationService.Authenticate(userId, cancellationToken); return new Envelope(mapper.Map(identity.User)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/EmailChangeApiService.cs b/src/DM.Web.API/Services/Users/EmailChangeApiService.cs index dac7e0e0..e19621eb 100644 --- a/src/DM.Web.API/Services/Users/EmailChangeApiService.cs +++ b/src/DM.Web.API/Services/Users/EmailChangeApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Account.EmailChange; @@ -7,25 +8,15 @@ namespace DM.Web.API.Services.Users; /// -internal class EmailChangeApiService : IEmailChangeApiService +internal class EmailChangeApiService( + IEmailChangeService service, + IMapper mapper) : IEmailChangeApiService { - private readonly IEmailChangeService service; - private readonly IMapper mapper; - - /// - public EmailChangeApiService( - IEmailChangeService service, - IMapper mapper) - { - this.service = service; - this.mapper = mapper; - } - /// - public async Task> Change(ChangeEmail changeEmail) + public async Task> Change(ChangeEmail changeEmail, CancellationToken cancellationToken) { var emailChange = mapper.Map(changeEmail); - var user = await service.Change(emailChange); + var user = await service.Change(emailChange, cancellationToken); return new Envelope(mapper.Map(user)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/IActivationApiService.cs b/src/DM.Web.API/Services/Users/IActivationApiService.cs index 692d93c4..0ec379bc 100644 --- a/src/DM.Web.API/Services/Users/IActivationApiService.cs +++ b/src/DM.Web.API/Services/Users/IActivationApiService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,6 +15,7 @@ public interface IActivationApiService /// Activate user and authenticate /// /// Activation token + /// /// - Task> Activate(Guid token); + Task> Activate(Guid token, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/IEmailChangeApiService.cs b/src/DM.Web.API/Services/Users/IEmailChangeApiService.cs index ad904665..e397e3e7 100644 --- a/src/DM.Web.API/Services/Users/IEmailChangeApiService.cs +++ b/src/DM.Web.API/Services/Users/IEmailChangeApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -13,6 +14,7 @@ public interface IEmailChangeApiService /// Change user email /// /// + /// /// - Task> Change(ChangeEmail changeEmail); + Task> Change(ChangeEmail changeEmail, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/ILoginApiService.cs b/src/DM.Web.API/Services/Users/ILoginApiService.cs index d8991a32..667404fc 100644 --- a/src/DM.Web.API/Services/Users/ILoginApiService.cs +++ b/src/DM.Web.API/Services/Users/ILoginApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -37,6 +38,7 @@ public interface ILoginApiService /// /// Get current user /// + /// /// Current user - Task> GetCurrent(); + Task> GetCurrent(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/IPasswordResetApiService.cs b/src/DM.Web.API/Services/Users/IPasswordResetApiService.cs index 000fc637..2cb89da1 100644 --- a/src/DM.Web.API/Services/Users/IPasswordResetApiService.cs +++ b/src/DM.Web.API/Services/Users/IPasswordResetApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -13,13 +14,15 @@ public interface IPasswordResetApiService /// Reset user password /// /// + /// /// - Task> Reset(ResetPassword resetPassword); + Task> Reset(ResetPassword resetPassword, CancellationToken cancellationToken); /// /// Change user password /// /// + /// /// - Task> Change(ChangePassword changePassword); + Task> Change(ChangePassword changePassword, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/IRegistrationApiService.cs b/src/DM.Web.API/Services/Users/IRegistrationApiService.cs index fbcf57e2..d517431e 100644 --- a/src/DM.Web.API/Services/Users/IRegistrationApiService.cs +++ b/src/DM.Web.API/Services/Users/IRegistrationApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Users; @@ -12,5 +13,6 @@ public interface IRegistrationApiService /// Register new user /// /// Registration information - Task Register(Registration registration); + /// + Task Register(Registration registration, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/IUserApiService.cs b/src/DM.Web.API/Services/Users/IUserApiService.cs index 3f7da0bb..2e85d577 100644 --- a/src/DM.Web.API/Services/Users/IUserApiService.cs +++ b/src/DM.Web.API/Services/Users/IUserApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Web.API.Dto.Contracts; using DM.Web.API.Dto.Users; @@ -14,36 +15,42 @@ public interface IUserApiService /// Get community users /// /// Paging query + /// /// - Task> GetUsers(UsersQuery query); + Task> GetUsers(UsersQuery query, CancellationToken cancellationToken); /// /// Get community user /// /// User login + /// /// - Task> GetUser(string login); + Task> GetUser(string login, CancellationToken cancellationToken); /// /// Get community user details /// /// + /// /// - Task> GetUserDetails(string login); + Task> GetUserDetails(string login, CancellationToken cancellationToken); /// /// Update user /// /// User login /// User information + /// /// - Task> UpdateUser(string login, UserDetails user); + Task> UpdateUser(string login, UserDetails user, CancellationToken cancellationToken); /// /// Upload user profile picture /// /// User login /// Profile picture files + /// /// - Task> UploadProfilePicture(string login, IFormFile files); + Task> UploadProfilePicture(string login, IFormFile files, + CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/LoginApiService.cs b/src/DM.Web.API/Services/Users/LoginApiService.cs index e5c93c12..c78bf55a 100644 --- a/src/DM.Web.API/Services/Users/LoginApiService.cs +++ b/src/DM.Web.API/Services/Users/LoginApiService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Authentication.Dto; @@ -17,26 +18,12 @@ namespace DM.Web.API.Services.Users; /// -internal class LoginApiService : ILoginApiService +internal class LoginApiService( + IWebAuthenticationService authenticationService, + IIdentityProvider identityProvider, + IUserReadingService userReadingService, + IMapper mapper) : ILoginApiService { - private readonly IWebAuthenticationService authenticationService; - private readonly IIdentityProvider identityProvider; - private readonly IUserReadingService userReadingService; - private readonly IMapper mapper; - - /// - public LoginApiService( - IWebAuthenticationService authenticationService, - IIdentityProvider identityProvider, - IUserReadingService userReadingService, - IMapper mapper) - { - this.authenticationService = authenticationService; - this.identityProvider = identityProvider; - this.userReadingService = userReadingService; - this.mapper = mapper; - } - /// public async Task> Login(LoginCredentials credentials, HttpContext httpContext) { @@ -44,7 +31,8 @@ public async Task> Login(LoginCredentials credentials, HttpContex switch (identity.Error) { case AuthenticationError.NoError: - var userDetails = await userReadingService.GetDetails(identityProvider.Current.User.Login); + var userDetails = await userReadingService.GetDetails( + identityProvider.Current.User.Login, httpContext.RequestAborted); return new Envelope(mapper.Map(userDetails)); case AuthenticationError.WrongLogin: throw new HttpBadRequestException(new Dictionary @@ -74,10 +62,11 @@ public async Task> Login(LoginCredentials credentials, HttpContex /// public Task LogoutAll(HttpContext httpContext) => authenticationService.LogoutElsewhere(httpContext); + /// /// - public async Task> GetCurrent() + public async Task> GetCurrent(CancellationToken cancellationToken) { - var userDetails = await userReadingService.GetDetails(identityProvider.Current.User.Login); + var userDetails = await userReadingService.GetDetails(identityProvider.Current.User.Login, cancellationToken); return new Envelope(mapper.Map(userDetails)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/PasswordResetApiService.cs b/src/DM.Web.API/Services/Users/PasswordResetApiService.cs index b71800e8..536cd029 100644 --- a/src/DM.Web.API/Services/Users/PasswordResetApiService.cs +++ b/src/DM.Web.API/Services/Users/PasswordResetApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Account.PasswordChange; @@ -9,36 +10,24 @@ namespace DM.Web.API.Services.Users; /// -internal class PasswordResetApiService : IPasswordResetApiService +internal class PasswordResetApiService( + IPasswordResetService passwordResetService, + IPasswordChangeService passwordChangeService, + IMapper mapper) : IPasswordResetApiService { - private readonly IPasswordResetService passwordResetService; - private readonly IPasswordChangeService passwordChangeService; - private readonly IMapper mapper; - - /// - public PasswordResetApiService( - IPasswordResetService passwordResetService, - IPasswordChangeService passwordChangeService, - IMapper mapper) - { - this.passwordResetService = passwordResetService; - this.passwordChangeService = passwordChangeService; - this.mapper = mapper; - } - /// - public async Task> Reset(ResetPassword resetPassword) + public async Task> Reset(ResetPassword resetPassword, CancellationToken cancellationToken) { var userPasswordReset = mapper.Map(resetPassword); - var user = await passwordResetService.Reset(userPasswordReset); + var user = await passwordResetService.Reset(userPasswordReset, cancellationToken); return new Envelope(mapper.Map(user), new {email = user.Email.Obfuscate()}); } /// - public async Task> Change(ChangePassword changePassword) + public async Task> Change(ChangePassword changePassword, CancellationToken cancellationToken) { var userPasswordChange = mapper.Map(changePassword); - var user = await passwordChangeService.Change(userPasswordChange); + var user = await passwordChangeService.Change(userPasswordChange, cancellationToken); return new Envelope(mapper.Map(user)); } } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/RegistrationApiService.cs b/src/DM.Web.API/Services/Users/RegistrationApiService.cs index 1222ceb0..80870e52 100644 --- a/src/DM.Web.API/Services/Users/RegistrationApiService.cs +++ b/src/DM.Web.API/Services/Users/RegistrationApiService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Account.Registration; @@ -6,21 +7,11 @@ namespace DM.Web.API.Services.Users; /// -internal class RegistrationApiService : IRegistrationApiService +internal class RegistrationApiService( + IRegistrationService registrationService, + IMapper mapper) : IRegistrationApiService { - private readonly IRegistrationService registrationService; - private readonly IMapper mapper; - - /// - public RegistrationApiService( - IRegistrationService registrationService, - IMapper mapper) - { - this.registrationService = registrationService; - this.mapper = mapper; - } - /// - public Task Register(Registration registration) => - registrationService.Register(mapper.Map(registration)); + public Task Register(Registration registration, CancellationToken cancellationToken) => + registrationService.Register(mapper.Map(registration), cancellationToken); } \ No newline at end of file diff --git a/src/DM.Web.API/Services/Users/UserApiService.cs b/src/DM.Web.API/Services/Users/UserApiService.cs index cac4ba87..6e5a8872 100644 --- a/src/DM.Web.API/Services/Users/UserApiService.cs +++ b/src/DM.Web.API/Services/Users/UserApiService.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using System.Threading.Tasks; using AutoMapper; using DM.Services.Community.BusinessProcesses.Users.Reading; @@ -11,58 +12,49 @@ namespace DM.Web.API.Services.Users; /// -internal class UserApiService : IUserApiService +internal class UserApiService( + IUserReadingService readingService, + IUserUpdatingService updatingService, + IMapper mapper) : IUserApiService { - private readonly IUserReadingService readingService; - private readonly IUserUpdatingService updatingService; - private readonly IMapper mapper; - - /// - public UserApiService( - IUserReadingService readingService, - IUserUpdatingService updatingService, - IMapper mapper) - { - this.readingService = readingService; - this.updatingService = updatingService; - this.mapper = mapper; - } - /// - public async Task> GetUsers(UsersQuery query) + public async Task> GetUsers(UsersQuery query, CancellationToken cancellationToken) { - var (users, paging) = await readingService.Get(query, query.Inactive); + var (users, paging) = await readingService.Get(query, query.Inactive, cancellationToken); return new ListEnvelope(users.Select(mapper.Map), new Paging(paging)); } /// - public async Task> GetUser(string login) + public async Task> GetUser(string login, CancellationToken cancellationToken) { - var user = await readingService.Get(login); + var user = await readingService.Get(login, cancellationToken); return new Envelope(mapper.Map(user)); } /// - public async Task> GetUserDetails(string login) + public async Task> GetUserDetails(string login, CancellationToken cancellationToken) { - var user = await readingService.GetDetails(login); + var user = await readingService.GetDetails(login, cancellationToken); return new Envelope(mapper.Map(user)); } /// - public async Task> UpdateUser(string login, UserDetails user) + public async Task> UpdateUser( + string login, UserDetails user, CancellationToken cancellationToken) { var updateUser = mapper.Map(user); updateUser.Login = login; - var updatedUser = await updatingService.Update(updateUser); + var updatedUser = await updatingService.Update(updateUser, cancellationToken); return new Envelope(mapper.Map(updatedUser)); } /// - public async Task> UploadProfilePicture(string login, IFormFile file) + public async Task> UploadProfilePicture( + string login, IFormFile file, CancellationToken cancellationToken) { await using var uploadStream = file.OpenReadStream(); - var updatedUser = await updatingService.UploadPicture(login, uploadStream, file.Name, file.ContentType); + var updatedUser = await updatingService.UploadPicture( + login, uploadStream, file.Name, file.ContentType, cancellationToken); return new Envelope(mapper.Map(updatedUser)); } } \ No newline at end of file diff --git a/src/DM.Web.Core/Authentication/WebAuthenticationService.cs b/src/DM.Web.Core/Authentication/WebAuthenticationService.cs index f6a6df61..ed4ef32b 100644 --- a/src/DM.Web.Core/Authentication/WebAuthenticationService.cs +++ b/src/DM.Web.Core/Authentication/WebAuthenticationService.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation; @@ -29,20 +30,23 @@ public WebAuthenticationService( this.logger = logger; } - private async Task GetAuthenticationResult(AuthCredentials credentials) => credentials switch + private async Task GetAuthenticationResult( + AuthCredentials credentials, CancellationToken cancellationToken) => credentials switch { - LoginCredentials loginCredentials => await authenticationService.Authenticate(loginCredentials.Login, - loginCredentials.Password, loginCredentials.RememberMe), - TokenCredentials tokenCredentials => await authenticationService.Authenticate(tokenCredentials.Token), - UnconditionalCredentials unconditionalCredentials => await authenticationService.Authenticate( - unconditionalCredentials.UserId), + LoginCredentials loginCredentials => + await authenticationService.Authenticate( + loginCredentials.Login, loginCredentials.Password, loginCredentials.RememberMe, cancellationToken), + TokenCredentials tokenCredentials => + await authenticationService.Authenticate(tokenCredentials.Token, cancellationToken), + UnconditionalCredentials unconditionalCredentials => + await authenticationService.Authenticate(unconditionalCredentials.UserId, cancellationToken), _ => Identity.Guest() }; /// public async Task Authenticate(AuthCredentials credentials, HttpContext httpContext) { - var identity = identitySetter.Current = await GetAuthenticationResult(credentials); + var identity = identitySetter.Current = await GetAuthenticationResult(credentials, httpContext.RequestAborted); await TryLoadAuthenticationResult(httpContext, identity); return identity; } @@ -50,14 +54,14 @@ public async Task Authenticate(AuthCredentials credentials, HttpConte /// public async Task Logout(HttpContext httpContext) { - var identity = identitySetter.Current = await authenticationService.Logout(); + var identity = identitySetter.Current = await authenticationService.Logout(httpContext.RequestAborted); await TryLoadAuthenticationResult(httpContext, identity); } /// public async Task LogoutElsewhere(HttpContext httpContext) { - var identity = identitySetter.Current = await authenticationService.LogoutElsewhere(); + var identity = identitySetter.Current = await authenticationService.LogoutElsewhere(httpContext.RequestAborted); await TryLoadAuthenticationResult(httpContext, identity); return identity; } diff --git a/src/DM.Web.Core/Hubs/IUserConnectionService.cs b/src/DM.Web.Core/Hubs/IUserConnectionService.cs index 1b750938..010bf69f 100644 --- a/src/DM.Web.Core/Hubs/IUserConnectionService.cs +++ b/src/DM.Web.Core/Hubs/IUserConnectionService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace DM.Web.Core.Hubs; @@ -14,16 +15,18 @@ public interface IUserConnectionService /// /// /// + /// /// - Task Add(string authToken, string connectionId); + Task Add(string authToken, string connectionId, CancellationToken cancellationToken); /// /// Authenticate user and remove its connection /// /// /// + /// /// - Task Remove(string authToken, string connectionId); + Task Remove(string authToken, string connectionId, CancellationToken cancellationToken); /// /// Get all connected users diff --git a/src/DM.Web.Core/Hubs/UserConnectionService.cs b/src/DM.Web.Core/Hubs/UserConnectionService.cs index 5e4c8bb7..817553e4 100644 --- a/src/DM.Web.Core/Hubs/UserConnectionService.cs +++ b/src/DM.Web.Core/Hubs/UserConnectionService.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation; @@ -11,9 +12,9 @@ internal class UserConnectionService(IAuthenticationService authenticationServic { private static readonly ConcurrentDictionary> Connections = new(); - public async Task Add(string authToken, string connectionId) + public async Task Add(string authToken, string connectionId, CancellationToken cancellationToken) { - var identity = await authenticationService.Authenticate(authToken); + var identity = await authenticationService.Authenticate(authToken, cancellationToken); if (!identity.User.IsAuthenticated) { return; @@ -21,7 +22,7 @@ public async Task Add(string authToken, string connectionId) Connections.AddOrUpdate( identity.User.UserId, - _ => new HashSet {connectionId}, + _ => [connectionId], (_, connectionIds) => { connectionIds.Add(connectionId); @@ -29,9 +30,9 @@ public async Task Add(string authToken, string connectionId) }); } - public async Task Remove(string authToken, string connectionId) + public async Task Remove(string authToken, string connectionId, CancellationToken cancellationToken) { - var identity = await authenticationService.Authenticate(authToken); + var identity = await authenticationService.Authenticate(authToken, cancellationToken); if (!identity.User.IsAuthenticated || !Connections.TryGetValue(identity.User.UserId, out var connectionIds)) { diff --git a/test/DM.Services.Authentication.Tests/AuthenticationServiceLoginShould.cs b/test/DM.Services.Authentication.Tests/AuthenticationServiceLoginShould.cs index 20c27a90..1dd6454f 100644 --- a/test/DM.Services.Authentication.Tests/AuthenticationServiceLoginShould.cs +++ b/test/DM.Services.Authentication.Tests/AuthenticationServiceLoginShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Factories; @@ -33,7 +34,7 @@ public AuthenticationServiceLoginShould() securityManager = Mock(); cryptoService = Mock(); authenticationRepository = Mock(); - userSearchSetup = authenticationRepository.Setup(r => r.TryFindUser(It.IsAny())); + userSearchSetup = authenticationRepository.Setup(r => r.TryFindUser(It.IsAny(), It.IsAny())); sessionFactory = Mock(); var identityProvider = Mock(); identityProvider.Setup(p => p.Current).Returns(Identity.Guest); @@ -45,7 +46,7 @@ public AuthenticationServiceLoginShould() public async Task FailIfNoUserFoundByLogin() { userSearchSetup.ReturnsAsync((false, null)); - var actual = await service.Authenticate(Username, "qwerty", false); + var actual = await service.Authenticate(Username, "qwerty", false, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.WrongLogin); } @@ -55,7 +56,7 @@ public async Task FailIfInactiveUserFound() { var user = new AuthenticatedUser {Activated = false}; userSearchSetup.ReturnsAsync((true, user)); - var actual = await service.Authenticate(Username, "qwerty", false); + var actual = await service.Authenticate(Username, "qwerty", false, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.Inactive); actual.User.Should().Be(AuthenticatedUser.Guest); @@ -69,7 +70,7 @@ public async Task FailIfRemovedUserFound() { var user = new AuthenticatedUser {Activated = true, IsRemoved = true}; userSearchSetup.ReturnsAsync((true, user)); - var actual = await service.Authenticate(Username, "qwerty", false); + var actual = await service.Authenticate(Username, "qwerty", false, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.Removed); actual.User.Should().Be(AuthenticatedUser.Guest); @@ -88,7 +89,7 @@ public async Task FailIfBannedUserFound() AccessPolicy = AccessPolicy.FullBan | AccessPolicy.RestrictContentEditing }; userSearchSetup.ReturnsAsync((true, user)); - var actual = await service.Authenticate(Username, "qwerty", false); + var actual = await service.Authenticate(Username, "qwerty", false, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.Banned); actual.User.Should().Be(AuthenticatedUser.Guest); @@ -113,7 +114,7 @@ public async Task FailIfPasswordIsIncorrect() .Setup(m => m.ComparePasswords(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(false); - var actual = await service.Authenticate(Username, "qwerty", false); + var actual = await service.Authenticate(Username, "qwerty", false, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.WrongPassword); actual.User.Should().Be(AuthenticatedUser.Guest); @@ -148,16 +149,16 @@ public async Task SucceedAndCreateNewUserSession() .Setup(f => f.Create(It.IsAny(), It.IsAny())) .Returns(session); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(userSettings); authenticationRepository - .Setup(r => r.AddSession(It.IsAny(), It.IsAny())) + .Setup(r => r.AddSession(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(externalSession); cryptoService - .Setup(s => s.Encrypt(It.IsAny())) + .Setup(s => s.Encrypt(It.IsAny(), It.IsAny())) .ReturnsAsync("token"); - var actual = await service.Authenticate(Username, "qwerty", true); + var actual = await service.Authenticate(Username, "qwerty", true, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.NoError); actual.User.Should().Be(user); @@ -166,8 +167,8 @@ public async Task SucceedAndCreateNewUserSession() actual.AuthenticationToken.Should().Be("token"); securityManager.Verify(m => m.ComparePasswords("qwerty", "salt", "hash")); sessionFactory.Verify(f => f.Create(true, false)); - authenticationRepository.Verify(r => r.FindUserSettings(userId), Times.Once); - authenticationRepository.Verify(r => r.AddSession(userId, session), Times.Once); + authenticationRepository.Verify(r => r.FindUserSettings(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.AddSession(userId, session, It.IsAny()), Times.Once); } [Fact] @@ -179,26 +180,26 @@ public async Task LoginUnconditionally() var userSettings = new UserSettings(); var externalSession = new DM.Services.Authentication.Dto.Session(); authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(user); sessionFactory .Setup(f => f.Create(It.IsAny(), It.IsAny())) .Returns(session); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(userSettings); cryptoService - .Setup(s => s.Encrypt(It.IsAny())) + .Setup(s => s.Encrypt(It.IsAny(), It.IsAny())) .ReturnsAsync("token"); authenticationRepository - .Setup(r => r.AddSession(It.IsAny(), It.IsAny())) + .Setup(r => r.AddSession(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(externalSession); - var actual = await service.Authenticate(userId); + var actual = await service.Authenticate(userId, CancellationToken.None); actual.Error.Should().Be(AuthenticationError.NoError); actual.AuthenticationToken.Should().Be("token"); - authenticationRepository.Verify(r => r.AddSession(userId, session), Times.Once); + authenticationRepository.Verify(r => r.AddSession(userId, session, It.IsAny()), Times.Once); } } \ No newline at end of file diff --git a/test/DM.Services.Authentication.Tests/AuthenticationServiceLogoutShould.cs b/test/DM.Services.Authentication.Tests/AuthenticationServiceLogoutShould.cs index 36a144fd..066eac04 100644 --- a/test/DM.Services.Authentication.Tests/AuthenticationServiceLogoutShould.cs +++ b/test/DM.Services.Authentication.Tests/AuthenticationServiceLogoutShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Factories; @@ -50,11 +51,11 @@ public async Task RemoveActiveUserSession() userSetup.Returns(new AuthenticatedUser {UserId = userId}); sessionSetup.Returns(session); authenticationRepository - .Setup(r => r.RemoveSession(It.IsAny(), It.IsAny())) + .Setup(r => r.RemoveSession(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); - await service.Logout(); + await service.Logout(CancellationToken.None); - authenticationRepository.Verify(r => r.RemoveSession(userId, sessionId), Times.Once); + authenticationRepository.Verify(r => r.RemoveSession(userId, sessionId, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); } @@ -70,10 +71,10 @@ public async Task RemoveAllActiveSessionsAndCreateNewSimilarToCurrent() sessionSetup.Returns(session); identity.Setup(i => i.Settings).Returns(userSettings); authenticationRepository - .Setup(r => r.RemoveSessionsExcept(It.IsAny(), It.IsAny())) + .Setup(r => r.RemoveSessionsExcept(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); cryptoService - .Setup(s => s.Encrypt(It.IsAny())) + .Setup(s => s.Encrypt(It.IsAny(), It.IsAny())) .ReturnsAsync("token"); var newSessionId = Guid.NewGuid(); @@ -81,12 +82,12 @@ public async Task RemoveAllActiveSessionsAndCreateNewSimilarToCurrent() var sessionToCreate = new DbSession{Id = sessionId}; sessionFactory.Setup(f => f.Create(false, false)).Returns(sessionToCreate); authenticationRepository - .Setup(r => r.AddSession(It.IsAny(), It.IsAny())) + .Setup(r => r.AddSession(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(newSession); - await service.Invoking(s => s.LogoutElsewhere()).Should().NotThrowAsync(); + await service.Invoking(s => s.LogoutElsewhere(CancellationToken.None)).Should().NotThrowAsync(); - authenticationRepository.Verify(r => r.RemoveSessionsExcept(userId, sessionId), Times.Once); + authenticationRepository.Verify(r => r.RemoveSessionsExcept(userId, sessionId, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); } } \ No newline at end of file diff --git a/test/DM.Services.Authentication.Tests/AuthenticationServiceTokenShould.cs b/test/DM.Services.Authentication.Tests/AuthenticationServiceTokenShould.cs index 20cdcbe0..b65cff8d 100644 --- a/test/DM.Services.Authentication.Tests/AuthenticationServiceTokenShould.cs +++ b/test/DM.Services.Authentication.Tests/AuthenticationServiceTokenShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Factories; @@ -31,7 +32,7 @@ public AuthenticationServiceTokenShould() { var securityManager = Mock(); cryptoService = Mock(); - tokenDecryptSetup = cryptoService.Setup(s => s.Decrypt(It.IsAny())); + tokenDecryptSetup = cryptoService.Setup(s => s.Decrypt(It.IsAny(), It.IsAny())); authenticationRepository = Mock(); @@ -56,27 +57,27 @@ public AuthenticationServiceTokenShould() public async Task FailIfErrorOnDecryptingToken() { tokenDecryptSetup.ThrowsAsync(new Exception()); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.ForgedToken); - cryptoService.Verify(s => s.Decrypt("token")); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); } [Fact] public async Task FailIfErrorOnDeserializingToken() { tokenDecryptSetup.ReturnsAsync("some invalid decrypted string"); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.ForgedToken); - cryptoService.Verify(s => s.Decrypt("token")); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); } [Fact] public async Task FailIfDeserializedTokenIsInvalid() { tokenDecryptSetup.ReturnsAsync("{\"something\": \"invalid\"}"); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.ForgedToken); - cryptoService.Verify(s => s.Decrypt("token")); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); } [Fact] @@ -89,32 +90,32 @@ public async Task FailWhenNonPersistentSessionExpiredAndRemoveExpiredSession() " \"sessionId\": \"6f9e570c-1dca-4cca-be93-d7418b85959e\"}"); authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(new AuthenticatedUser()); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(new UserSettings()); authenticationRepository - .Setup(r => r.FindUserSession(It.IsAny())) + .Setup(r => r.FindUserSession(It.IsAny(), It.IsAny())) .ReturnsAsync(new Session { Persistent = false, ExpirationDate = new DateTime(2018, 06, 11, 9, 59, 59) }); authenticationRepository - .Setup(r => r.RemoveSession(It.IsAny(), It.IsAny())) + .Setup(r => r.RemoveSession(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); dateTimeProvider .Setup(p => p.Now) .Returns(new DateTime(2018, 06, 11, 10, 0, 0)); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.SessionExpired); - cryptoService.Verify(s => s.Decrypt("token")); - authenticationRepository.Verify(r => r.FindUser(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSettings(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSession(sessionId), Times.Once); - authenticationRepository.Verify(r => r.RemoveSession(userId, sessionId), Times.Once); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); + authenticationRepository.Verify(r => r.FindUser(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSettings(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSession(sessionId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.RemoveSession(userId, sessionId, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); } @@ -126,16 +127,16 @@ public async Task FailWhenInvalidSessionFound() " \"sessionId\": \"6f9e570c-1dca-4cca-be93-d7418b85959e\"}"); authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(new AuthenticatedUser()); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(new UserSettings()); authenticationRepository - .Setup(r => r.FindUserSession(It.IsAny())) + .Setup(r => r.FindUserSession(It.IsAny(), It.IsAny())) .ReturnsAsync((Session) null); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.SessionExpired); } @@ -157,16 +158,16 @@ public async Task SucceedAndRefreshSessionWhenNonPersistentSessionAboutToExpire( ExpirationDate = new DateTime(2018, 06, 11, 10, 0, 0) }; authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(user); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(settings); authenticationRepository - .Setup(r => r.FindUserSession(It.IsAny())) + .Setup(r => r.FindUserSession(It.IsAny(), It.IsAny())) .ReturnsAsync(session); authenticationRepository - .Setup(r => r.RefreshSession(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(r => r.RefreshSession(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); dateTimeProvider .Setup(p => p.Now) @@ -175,19 +176,19 @@ public async Task SucceedAndRefreshSessionWhenNonPersistentSessionAboutToExpire( .Setup(b => b.Field(u => u.LastVisitDate, It.IsAny())) .Returns(updateBuilder.Object); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.NoError); actual.User.Should().Be(user); actual.Session.Should().Be(session); actual.Settings.Should().Be(settings); actual.AuthenticationToken.Should().Be("token"); - cryptoService.Verify(s => s.Decrypt("token")); - authenticationRepository.Verify(r => r.FindUser(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSettings(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSession(sessionId), Times.Once); - authenticationRepository.Verify(r => r.RefreshSession(userId, sessionId, new DateTimeOffset(new DateTime(2018, 06, 11, 10, 20, 0)))); - authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object), Times.Once); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); + authenticationRepository.Verify(r => r.FindUser(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSettings(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSession(sessionId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.RefreshSession(userId, sessionId, new DateTimeOffset(new DateTime(2018, 06, 11, 10, 20, 0)), It.IsAny())); + authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); updateBuilder.VerifyNoOtherCalls(); @@ -211,13 +212,13 @@ public async Task SucceedWhenSessionNotYetExpired() ExpirationDate = new DateTimeOffset(new DateTime(2019, 06, 11, 10, 0, 0)) }; authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(user); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(settings); authenticationRepository - .Setup(r => r.FindUserSession(It.IsAny())) + .Setup(r => r.FindUserSession(It.IsAny(), It.IsAny())) .ReturnsAsync(session); dateTimeProvider .Setup(p => p.Now) @@ -226,18 +227,18 @@ public async Task SucceedWhenSessionNotYetExpired() .Setup(b => b.Field(u => u.LastVisitDate, It.IsAny())) .Returns(updateBuilder.Object); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.NoError); actual.User.Should().Be(user); actual.Session.Should().Be(session); actual.Settings.Should().Be(settings); actual.AuthenticationToken.Should().Be("token"); - cryptoService.Verify(s => s.Decrypt("token")); - authenticationRepository.Verify(r => r.FindUser(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSettings(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSession(sessionId), Times.Once); - authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object), Times.Once); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); + authenticationRepository.Verify(r => r.FindUser(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSettings(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSession(sessionId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); } @@ -258,30 +259,30 @@ public async Task SucceedWithoutExpirationCheckingWhenSessionIsPersistent() Persistent = true }; authenticationRepository - .Setup(r => r.FindUser(It.IsAny())) + .Setup(r => r.FindUser(It.IsAny(), It.IsAny())) .ReturnsAsync(user); authenticationRepository - .Setup(r => r.FindUserSettings(It.IsAny())) + .Setup(r => r.FindUserSettings(It.IsAny(), It.IsAny())) .ReturnsAsync(settings); authenticationRepository - .Setup(r => r.FindUserSession(It.IsAny())) + .Setup(r => r.FindUserSession(It.IsAny(), It.IsAny())) .ReturnsAsync(session); updateBuilder .Setup(b => b.Field(u => u.LastVisitDate, It.IsAny())) .Returns(updateBuilder.Object); - var actual = await service.Authenticate("token"); + var actual = await service.Authenticate("token", CancellationToken.None); actual.Error.Should().Be(AuthenticationError.NoError); actual.User.Should().Be(user); actual.Session.Should().Be(session); actual.Settings.Should().Be(settings); actual.AuthenticationToken.Should().Be("token"); - cryptoService.Verify(s => s.Decrypt("token")); - authenticationRepository.Verify(r => r.FindUser(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSettings(userId), Times.Once); - authenticationRepository.Verify(r => r.FindUserSession(sessionId), Times.Once); - authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object), Times.Once); + cryptoService.Verify(s => s.Decrypt("token", It.IsAny())); + authenticationRepository.Verify(r => r.FindUser(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSettings(userId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.FindUserSession(sessionId, It.IsAny()), Times.Once); + authenticationRepository.Verify(r => r.UpdateActivity(updateBuilder.Object, It.IsAny()), Times.Once); authenticationRepository.VerifyNoOtherCalls(); } } \ No newline at end of file diff --git a/test/DM.Services.Authentication.Tests/SymmetricCryptoServiceShould.cs b/test/DM.Services.Authentication.Tests/SymmetricCryptoServiceShould.cs index 98c9ed5c..24572ddb 100644 --- a/test/DM.Services.Authentication.Tests/SymmetricCryptoServiceShould.cs +++ b/test/DM.Services.Authentication.Tests/SymmetricCryptoServiceShould.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Implementation.Security; using DM.Tests.Core; @@ -14,8 +15,8 @@ public class SymmetricCryptoServiceShould : UnitTestBase public async Task CryptSymmetrically() { var input = "some value to encrypt"; - var encrypted = await service.Encrypt(input); - var decrypted = await service.Decrypt(encrypted); + var encrypted = await service.Encrypt(input, CancellationToken.None); + var decrypted = await service.Decrypt(encrypted, CancellationToken.None); decrypted.Should().Be(input); encrypted.Should().NotBe(input); diff --git a/test/DM.Services.Community.Tests/ActivationServiceShould.cs b/test/DM.Services.Community.Tests/ActivationServiceShould.cs index c850e5f5..308f1f76 100644 --- a/test/DM.Services.Community.Tests/ActivationServiceShould.cs +++ b/test/DM.Services.Community.Tests/ActivationServiceShould.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Account.Activation; using DM.Services.Core.Dto.Enums; @@ -29,9 +30,9 @@ public ActivationServiceShould() { activationRepository = Mock(); findUserSetup = activationRepository - .Setup(r => r.FindUserToActivate(It.IsAny(), It.IsAny())); + .Setup(r => r.FindUserToActivate(It.IsAny(), It.IsAny(), It.IsAny())); activationRepository - .Setup(r => r.ActivateUser(It.IsAny>(), It.IsAny>())) + .Setup(r => r.ActivateUser(It.IsAny>(), It.IsAny>(), It.IsAny())) .Returns(Task.CompletedTask); var dateTimeProvider = Mock(); @@ -68,17 +69,17 @@ public async Task SearchLastTwoDaysTokens() { var tokenId = Guid.NewGuid(); findUserSetup.ReturnsAsync(Guid.NewGuid()); - await activationService.Activate(tokenId); - activationRepository.Verify(r => r.FindUserToActivate(tokenId, new DateTime(2018, 12, 31)), Times.Once); + await activationService.Activate(tokenId, CancellationToken.None); + activationRepository.Verify(r => r.FindUserToActivate(tokenId, new DateTime(2018, 12, 31), It.IsAny()), Times.Once); } [Fact] - public void ThrowGoneException_WhenTokenInvalid() + public async Task ThrowGoneException_WhenTokenInvalid() { findUserSetup.ReturnsAsync((Guid?) null); - activationService - .Invoking(s => s.Activate(Guid.NewGuid()).Wait()) - .Should().Throw() + (await activationService + .Invoking(s => s.Activate(Guid.NewGuid(), CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Gone); } @@ -89,7 +90,7 @@ public async Task ReturnActivatedUserId_WhenTokenValid() var userId = Guid.NewGuid(); findUserSetup.ReturnsAsync(userId); - var actual = await activationService.Activate(tokenId); + var actual = await activationService.Activate(tokenId, CancellationToken.None); actual.Should().Be(userId); } @@ -100,9 +101,9 @@ public async Task ActivateFoundUser_WhenTokenValid() var userId = Guid.NewGuid(); findUserSetup.ReturnsAsync(userId); - await activationService.Activate(tokenId); + await activationService.Activate(tokenId, CancellationToken.None); - activationRepository.Verify(r => r.ActivateUser(userUpdateBuilder.Object, tokenUpdateBuilder.Object)); + activationRepository.Verify(r => r.ActivateUser(userUpdateBuilder.Object, tokenUpdateBuilder.Object, It.IsAny())); userUpdateBuilder.Verify(b => b.Field(u => u.Activated, true)); tokenUpdateBuilder.Verify(b => b.Field(t => t.IsRemoved, true)); } @@ -114,7 +115,7 @@ public async Task PublishActivationMessage_WhenTokenValid() var userId = Guid.NewGuid(); findUserSetup.ReturnsAsync(userId); - await activationService.Activate(tokenId); + await activationService.Activate(tokenId, CancellationToken.None); publisher.Verify(p => p.Send(EventType.ActivatedUser, userId), Times.Once); } diff --git a/test/DM.Services.Community.Tests/BusinessProcesses/RegistrationServiceShould.cs b/test/DM.Services.Community.Tests/BusinessProcesses/RegistrationServiceShould.cs index fc6945c0..7116c517 100644 --- a/test/DM.Services.Community.Tests/BusinessProcesses/RegistrationServiceShould.cs +++ b/test/DM.Services.Community.Tests/BusinessProcesses/RegistrationServiceShould.cs @@ -50,12 +50,12 @@ public RegistrationServiceShould() registrationRepository = Mock(); registrationRepository - .Setup(r => r.AddUser(It.IsAny(), It.IsAny())) + .Setup(r => r.AddUser(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); mailSender = Mock(); mailSender - .Setup(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); eventPublisher = Mock(); @@ -80,7 +80,7 @@ public async Task CreateUserWithGeneratedSaltAndHash() createUserSetup.Returns(new User()); var userRegistration = new UserRegistration {Password = "my password"}; - await service.Register(userRegistration); + await service.Register(userRegistration, CancellationToken.None); securityManager.Verify(m => m.GeneratePassword("my password")); userFactory.Verify(f => f.Create(userRegistration, "salt", "hash")); @@ -94,7 +94,7 @@ public async Task CreateTokenWithGeneratedUserId() var userId = Guid.NewGuid(); createUserSetup.Returns(new User {UserId = userId}); - await service.Register(new UserRegistration()); + await service.Register(new UserRegistration(), CancellationToken.None); tokenFactory.Verify(f => f.Create(userId)); } @@ -108,9 +108,9 @@ public async Task SaveCreatedUserAndToken() var user = new User(); createUserSetup.Returns(user); - await service.Register(new UserRegistration()); + await service.Register(new UserRegistration(), CancellationToken.None); - registrationRepository.Verify(r => r.AddUser(user, token), Times.Once); + registrationRepository.Verify(r => r.AddUser(user, token, It.IsAny()), Times.Once); registrationRepository.VerifyNoOtherCalls(); } @@ -122,9 +122,9 @@ public async Task SendConfirmationLetter() createTokenSetup.Returns(new Token {TokenId = tokenId}); createUserSetup.Returns(new User {Email = "email", Login = "login"}); - await service.Register(new UserRegistration()); + await service.Register(new UserRegistration(), CancellationToken.None); - mailSender.Verify(s => s.Send("email", "login", tokenId), Times.Once); + mailSender.Verify(s => s.Send("email", "login", tokenId, It.IsAny()), Times.Once); mailSender.VerifyNoOtherCalls(); } @@ -136,7 +136,7 @@ public async Task PublishEvent() var userId = Guid.NewGuid(); createUserSetup.Returns(new User {UserId = userId}); - await service.Register(new UserRegistration {Email = "email", Login = "login"}); + await service.Register(new UserRegistration {Email = "email", Login = "login"}, CancellationToken.None); eventPublisher.Verify(p => p.Send(EventType.NewUser, userId)); } diff --git a/test/DM.Services.Community.Tests/BusinessProcesses/UserReadingServiceShould.cs b/test/DM.Services.Community.Tests/BusinessProcesses/UserReadingServiceShould.cs index 671da048..03f842eb 100644 --- a/test/DM.Services.Community.Tests/BusinessProcesses/UserReadingServiceShould.cs +++ b/test/DM.Services.Community.Tests/BusinessProcesses/UserReadingServiceShould.cs @@ -1,4 +1,6 @@ +using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation.UserIdentity; @@ -34,16 +36,16 @@ public UserReadingServiceShould() } [Fact] - public void ThrowGoneWhenUserDetailsNotFound() + public async Task ThrowGoneWhenUserDetailsNotFound() { readingRepository - .Setup(r => r.GetUserDetails(It.IsAny())) + .Setup(r => r.GetUserDetails(It.IsAny(), It.IsAny())) .ReturnsAsync((UserDetails) null); - service.Invoking(s => s.GetDetails("User").Wait()) - .Should().Throw() + (await service.Invoking(s => s.GetDetails("User", CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Gone); - readingRepository.Verify(r => r.GetUserDetails("User"), Times.Once); + readingRepository.Verify(r => r.GetUserDetails("User", It.IsAny()), Times.Once); } [Fact] @@ -51,26 +53,26 @@ public async Task ReturnFoundUserDetails() { var expected = new UserDetails(); readingRepository - .Setup(r => r.GetUserDetails(It.IsAny())) + .Setup(r => r.GetUserDetails(It.IsAny(), It.IsAny())) .ReturnsAsync(expected); - var actual = await service.GetDetails("User"); + var actual = await service.GetDetails("User", CancellationToken.None); actual.Should().Be(expected); - readingRepository.Verify(r => r.GetUserDetails("User"), Times.Once); + readingRepository.Verify(r => r.GetUserDetails("User", It.IsAny()), Times.Once); } [Fact] - public void ThrowGoneWhenUserNotFound() + public async Task ThrowGoneWhenUserNotFound() { readingRepository - .Setup(r => r.GetUser(It.IsAny())) + .Setup(r => r.GetUser(It.IsAny(), It.IsAny())) .ReturnsAsync((GeneralUser) null); - service.Invoking(s => s.Get("User").Wait()) - .Should().Throw() + (await service.Invoking(s => s.Get("User", CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Gone); - readingRepository.Verify(r => r.GetUser("User"), Times.Once); + readingRepository.Verify(r => r.GetUser("User", It.IsAny()), Times.Once); } [Fact] @@ -78,30 +80,30 @@ public async Task ReturnFoundUser() { var expected = new GeneralUser(); readingRepository - .Setup(r => r.GetUser(It.IsAny())) + .Setup(r => r.GetUser(It.IsAny(), It.IsAny())) .ReturnsAsync(expected); - var actual = await service.Get("User"); + var actual = await service.Get("User", CancellationToken.None); actual.Should().Be(expected); - readingRepository.Verify(r => r.GetUser("User"), Times.Once); + readingRepository.Verify(r => r.GetUser("User", It.IsAny()), Times.Once); } [Fact] public async Task ReturnFetchedUsers() { - var expected = new GeneralUser[0]; + var expected = Array.Empty(); readingRepository - .Setup(r => r.CountUsers(It.IsAny())) + .Setup(r => r.CountUsers(It.IsAny(), It.IsAny())) .ReturnsAsync(10); readingRepository - .Setup(r => r.GetUsers(It.IsAny(), It.IsAny())) + .Setup(r => r.GetUsers(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(expected); currentUserSettingsSetup.Returns(new UserSettings{Paging = new PagingSettings{EntitiesPerPage = 10}}); - var (actual, _) = await service.Get(new PagingQuery(), true); + var (actual, _) = await service.Get(new PagingQuery(), true, CancellationToken.None); actual.Should().BeSameAs(expected); - readingRepository.Verify(r => r.CountUsers(true), Times.Once); - readingRepository.Verify(r => r.GetUsers(It.IsAny(), true)); + readingRepository.Verify(r => r.CountUsers(true, It.IsAny()), Times.Once); + readingRepository.Verify(r => r.GetUsers(It.IsAny(), true, It.IsAny())); } } \ No newline at end of file diff --git a/test/DM.Services.Community.Tests/RegistrationMailSenderShould.cs b/test/DM.Services.Community.Tests/RegistrationMailSenderShould.cs index 9249382b..9f7964de 100644 --- a/test/DM.Services.Community.Tests/RegistrationMailSenderShould.cs +++ b/test/DM.Services.Community.Tests/RegistrationMailSenderShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Account.Registration.Confirmation; using DM.Services.Core.Configuration; @@ -40,7 +41,7 @@ public RegistrationMailSenderShould() public async Task RenderConfirmationTemplate() { renderSetup.ReturnsAsync("renderResult"); - await registrationMailSender.Send("email", "login", Guid.Parse("3cac234a-9c07-4103-9179-d00562a487ba")); + await registrationMailSender.Send("email", "login", Guid.Parse("3cac234a-9c07-4103-9179-d00562a487ba"), CancellationToken.None); renderer.Verify(r => r.Render( "RegistrationLetter", It.Is(vm => @@ -52,7 +53,7 @@ public async Task RenderConfirmationTemplate() public async Task SendLetterWithRenderedTemplate() { renderSetup.ReturnsAsync("rendered letter"); - await registrationMailSender.Send("email", "login", Guid.NewGuid()); + await registrationMailSender.Send("email", "login", Guid.NewGuid(), CancellationToken.None); sender.Verify(s => s.Send(It.Is(l => l.Address == "email" && l.Subject.Contains("login") && diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryCreatingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryCreatingServiceShould.cs index 585d35d6..3e3f9d06 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryCreatingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryCreatingServiceShould.cs @@ -49,7 +49,7 @@ public CommentaryCreatingServiceShould() .ReturnsAsync(new ValidationResult()); var topicReadingService = Mock(); - topicReadingSetup = topicReadingService.Setup(s => s.GetTopic(It.IsAny())); + topicReadingSetup = topicReadingService.Setup(s => s.GetTopic(It.IsAny(), It.IsAny())); intentionManager = Mock(); intentionManager @@ -66,7 +66,7 @@ public CommentaryCreatingServiceShould() commentRepository = Mock(); commentaryCreateSetup = commentRepository.Setup(r => - r.Create(It.IsAny(), It.IsAny>())); + r.Create(It.IsAny(), It.IsAny>(), It.IsAny())); invokedEventPublisher = Mock(); invokedEventPublisher @@ -75,7 +75,7 @@ public CommentaryCreatingServiceShould() countersRepository = Mock(); countersRepository - .Setup(r => r.Increment(It.IsAny(), It.IsAny())) + .Setup(r => r.Increment(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var updateBuilderFactory = Mock(); @@ -102,7 +102,7 @@ public async Task AuthorizeCreateCommentaryAction() commentaryDalCreateSetup.Returns(new Comment()); commentaryCreateSetup.ReturnsAsync(new Common.Dto.Comment()); - await service.Create(new CreateComment()); + await service.Create(new CreateComment(), CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(TopicIntention.CreateComment, topic)); } @@ -119,10 +119,10 @@ public async Task SaveNewCommentAndUpdateDenormalizedColumn() var expected = new Common.Dto.Comment(); commentaryCreateSetup.ReturnsAsync(expected); - var actual = await service.Create(new CreateComment()); + var actual = await service.Create(new CreateComment(), CancellationToken.None); actual.Should().Be(expected); - commentRepository.Verify(r => r.Create(forumComment, updateBuilder.Object), Times.Once); + commentRepository.Verify(r => r.Create(forumComment, updateBuilder.Object, It.IsAny()), Times.Once); updateBuilder.Verify(b => b.Field(t => t.LastCommentId, commentId)); } @@ -136,9 +136,9 @@ public async Task IncrementUnreadCounter() commentaryDalCreateSetup.Returns(new Comment()); commentaryCreateSetup.ReturnsAsync(new Common.Dto.Comment()); - await service.Create(new CreateComment()); + await service.Create(new CreateComment(), CancellationToken.None); - countersRepository.Verify(r => r.Increment(topicId, UnreadEntryType.Message), Times.Once); + countersRepository.Verify(r => r.Increment(topicId, UnreadEntryType.Message, It.IsAny()), Times.Once); countersRepository.VerifyNoOtherCalls(); } @@ -153,7 +153,7 @@ public async Task PublishEvent() commentaryDalCreateSetup.Returns(new Comment {CommentId = commentId}); commentaryCreateSetup.ReturnsAsync(new Common.Dto.Comment()); - await service.Create(new CreateComment()); + await service.Create(new CreateComment(), CancellationToken.None); invokedEventPublisher.Verify(p => p.Send(EventType.NewForumComment, commentId)); invokedEventPublisher.VerifyNoOtherCalls(); diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryDeletingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryDeletingServiceShould.cs index 16dcb98f..24982ce3 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryDeletingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryDeletingServiceShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -52,7 +53,7 @@ public CommentaryDeletingServiceShould() .Returns(commentUpdateBuilder.Object); commentaryRepository = Mock(); - getCommentSetup = commentaryRepository.Setup(r => r.GetForDelete(It.IsAny())); + getCommentSetup = commentaryRepository.Setup(r => r.GetForDelete(It.IsAny(), It.IsAny())); unreadCountersRepository = Mock(); eventPublisher = Mock(); @@ -69,7 +70,7 @@ public async Task AuthorizeDeleteAction() var comment = new CommentToDelete(); getCommentSetup.ReturnsAsync(comment); - await service.Delete(commentId); + await service.Delete(commentId, CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(CommentIntention.Delete, (Common.Dto.Comment) comment)); } @@ -81,10 +82,10 @@ public async Task SaveWithRemovedFlag() var comment = new CommentToDelete(); getCommentSetup.ReturnsAsync(comment); - await service.Delete(commentId); + await service.Delete(commentId, CancellationToken.None); commentaryRepository.Verify(r => - r.Delete(commentUpdateBuilder.Object, topicUpdateBuilder.Object), Times.Once); + r.Delete(commentUpdateBuilder.Object, topicUpdateBuilder.Object, It.IsAny()), Times.Once); commentUpdateBuilder.Verify(b => b.Field(c => c.IsRemoved, true)); } @@ -98,14 +99,14 @@ public async Task SaveWithUpdateTopicLastComment_WhenIsLastCommentOfTopic() var secondLastCommentId = Guid.NewGuid(); commentaryRepository - .Setup(r => r.GetSecondLastCommentId(topicId)) + .Setup(r => r.GetSecondLastCommentId(topicId, It.IsAny())) .ReturnsAsync(secondLastCommentId); - await service.Delete(commentId); + await service.Delete(commentId, CancellationToken.None); - commentaryRepository.Verify(r => r.GetSecondLastCommentId(topicId), Times.Once); + commentaryRepository.Verify(r => r.GetSecondLastCommentId(topicId, It.IsAny()), Times.Once); commentaryRepository.Verify(r => - r.Delete(commentUpdateBuilder.Object, topicUpdateBuilder.Object), Times.Once); + r.Delete(commentUpdateBuilder.Object, topicUpdateBuilder.Object, It.IsAny()), Times.Once); topicUpdateBuilder.Verify(b => b.Field(t => t.LastCommentId, secondLastCommentId)); } @@ -121,11 +122,12 @@ public async Task DecrementUnreadCounter() }; getCommentSetup.ReturnsAsync(comment); - await service.Delete(commentId); + await service.Delete(commentId, CancellationToken.None); unreadCountersRepository.Verify( r => r.Decrement(topicId, UnreadEntryType.Message, - new DateTimeOffset(2019, 01, 14, 10, 13, 11, TimeSpan.Zero)), Times.Once); + new DateTimeOffset(2019, 01, 14, 10, 13, 11, TimeSpan.Zero), + It.IsAny()), Times.Once); unreadCountersRepository.VerifyNoOtherCalls(); } @@ -136,7 +138,7 @@ public async Task SendEvent() var comment = new CommentToDelete(); getCommentSetup.ReturnsAsync(comment); - await service.Delete(commentId); + await service.Delete(commentId, CancellationToken.None); eventPublisher.Verify(p => p.Send(EventType.DeletedForumComment, commentId)); } diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryReadingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryReadingServiceShould.cs index 749cec99..0819f4ab 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryReadingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryReadingServiceShould.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation.UserIdentity; @@ -37,7 +38,7 @@ public class CommentaryReadingServiceShould : UnitTestBase public CommentaryReadingServiceShould() { var topicReadingService = Mock(); - readingTopicSetup = topicReadingService.Setup(r => r.GetTopic(It.IsAny())); + readingTopicSetup = topicReadingService.Setup(r => r.GetTopic(It.IsAny(), It.IsAny())); var identity = Mock(); identity.Setup(i => i.Settings).Returns(new UserSettings @@ -47,19 +48,19 @@ public CommentaryReadingServiceShould() identityProvider.Setup(p => p.Current).Returns(identity.Object); var commentaryRepository = Mock(); - getCommentsListSetup = commentaryRepository.Setup(r => r.Get(It.IsAny(), It.IsAny())); - getCommentSetup = commentaryRepository.Setup(r => r.Get(It.IsAny())); - countCommentsSetup = commentaryRepository.Setup(r => r.Count(It.IsAny())); + getCommentsListSetup = commentaryRepository.Setup(r => r.Get(It.IsAny(), It.IsAny(), It.IsAny())); + getCommentSetup = commentaryRepository.Setup(r => r.Get(It.IsAny(), It.IsAny())); + countCommentsSetup = commentaryRepository.Setup(r => r.Count(It.IsAny(), It.IsAny())); var forumReadingService = Mock(); - getForumSetup = forumReadingService.Setup(s => s.GetForum(It.IsAny(), It.IsAny())); + getForumSetup = forumReadingService.Setup(s => s.GetForum(It.IsAny(), It.IsAny(), It.IsAny())); unreadCountersRepository = Mock(); unreadCountersRepository - .Setup(r => r.Flush(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(r => r.Flush(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); unreadCountersRepository - .Setup(r => r.FlushAll(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(r => r.FlushAll(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); readingService = new CommentaryReadingService(topicReadingService.Object, @@ -72,7 +73,7 @@ public void ThrowException_WhenNothingFound() { var commentId = Guid.NewGuid(); getCommentSetup.ReturnsAsync((Comment) null); - readingService.Invoking(s => s.Get(commentId).Wait()) + readingService.Invoking(s => s.Get(commentId, CancellationToken.None).Wait()) .Should().Throw().And .StatusCode.Should().Be(HttpStatusCode.Gone); } @@ -82,7 +83,7 @@ public async Task ReturnFoundCommentary() { var expected = new Comment(); getCommentSetup.ReturnsAsync(expected); - var actual = await readingService.Get(Guid.NewGuid()); + var actual = await readingService.Get(Guid.NewGuid(), CancellationToken.None); actual.Should().Be(expected); } @@ -96,7 +97,7 @@ public async Task ReturnFoundList() getCommentsListSetup.ReturnsAsync(expected); currentUserSetup.Returns(Create.User().WithRole(UserRole.Guest).Please); - var (actualList, actualPaging) = await readingService.Get(topicId, new PagingQuery()); + var (actualList, actualPaging) = await readingService.Get(topicId, new PagingQuery(), CancellationToken.None); actualList.Should().BeSameAs(expected); actualPaging.Should().NotBeNull(); @@ -110,9 +111,9 @@ public async Task FlushTopicCounter() readingTopicSetup.ReturnsAsync(new Topic()); currentUserSetup.Returns(Create.User(userId).Please); - await readingService.MarkAsRead(topicId); + await readingService.MarkAsRead(topicId, CancellationToken.None); - unreadCountersRepository.Verify(r => r.Flush(userId, UnreadEntryType.Message, topicId), Times.Once); + unreadCountersRepository.Verify(r => r.Flush(userId, UnreadEntryType.Message, topicId, It.IsAny()), Times.Once); unreadCountersRepository.VerifyNoOtherCalls(); } @@ -125,9 +126,9 @@ public async Task FlushForumCounters() currentUserSetup.Returns(Create.User(userId).Please); getForumSetup.ReturnsAsync(new Dto.Output.Forum {Id = forumInternalId}); - await readingService.MarkAsRead(forumId); + await readingService.MarkAsRead(forumId, CancellationToken.None); - unreadCountersRepository.Verify(r => r.FlushAll(userId, UnreadEntryType.Message, forumInternalId), + unreadCountersRepository.Verify(r => r.FlushAll(userId, UnreadEntryType.Message, forumInternalId, CancellationToken.None), Times.Once); unreadCountersRepository.VerifyNoOtherCalls(); } diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryUpdatingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryUpdatingServiceShould.cs index 477146df..883de3ea 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryUpdatingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Commentaries/CommentaryUpdatingServiceShould.cs @@ -41,7 +41,7 @@ public CommentaryUpdatingServiceShould() .ReturnsAsync(new ValidationResult()); var readingService = Mock(); - getCommentSetup = readingService.Setup(s => s.Get(It.IsAny())); + getCommentSetup = readingService.Setup(s => s.Get(It.IsAny(), It.IsAny())); intentionManager = Mock(); intentionManager @@ -63,7 +63,7 @@ public CommentaryUpdatingServiceShould() .Returns(commentUpdateBuilder.Object); commentRepository = Mock(); - updateCommentSetup = commentRepository.Setup(r => r.Update(It.IsAny>())); + updateCommentSetup = commentRepository.Setup(r => r.Update(It.IsAny>(), It.IsAny())); eventPublisher = Mock(); eventPublisher @@ -89,7 +89,7 @@ public async Task AuthorizeUpdateAction() var updatedComment = new Common.Dto.Comment(); updateCommentSetup.ReturnsAsync(updatedComment); - await service.Update(new UpdateComment {CommentId = commentId, Text = string.Empty}); + await service.Update(new UpdateComment {CommentId = commentId, Text = string.Empty}, CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(CommentIntention.Edit, comment), Times.Once); } @@ -106,10 +106,10 @@ public async Task SaveWithUpdatedTextAndModifiedDate() currentMomentSetup.Returns(rightNow); commentUpdateBuilder.Setup(b => b.HasChanges()).Returns(true); - var actual = await service.Update(new UpdateComment {CommentId = commentId, Text = "some text boi"}); + var actual = await service.Update(new UpdateComment {CommentId = commentId, Text = "some text boi"}, CancellationToken.None); actual.Should().Be(expected); - commentRepository.Verify(r => r.Update(commentUpdateBuilder.Object), Times.Once); + commentRepository.Verify(r => r.Update(commentUpdateBuilder.Object, It.IsAny()), Times.Once); commentUpdateBuilder.Verify(b => b.Field(c => c.Text, "some text boi")); commentUpdateBuilder.Verify(b => b.Field(c => c.LastUpdateDate, rightNow)); } @@ -123,7 +123,7 @@ public async Task PublishEvent() var updatedComment = new Common.Dto.Comment(); updateCommentSetup.ReturnsAsync(updatedComment); - await service.Update(new UpdateComment {CommentId = commentId, Text = string.Empty}); + await service.Update(new UpdateComment {CommentId = commentId, Text = string.Empty}, CancellationToken.None); eventPublisher.Verify(p => p.Send(EventType.ChangedForumComment, commentId), Times.Once); } diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForCommentsShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForCommentsShould.cs index d877c119..7093ff5d 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForCommentsShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForCommentsShould.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation.UserIdentity; @@ -38,7 +39,7 @@ public class LikeServiceForCommentsShould : UnitTestBase public LikeServiceForCommentsShould() { var commentReadingService = Mock(); - commentReading = commentReadingService.Setup(s => s.Get(It.IsAny())); + commentReading = commentReadingService.Setup(s => s.Get(It.IsAny(), It.IsAny())); var intentionManager = Mock(); intentionManager @@ -57,7 +58,7 @@ public LikeServiceForCommentsShould() } [Fact] - public void ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() + public async Task ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() { var commentId = Guid.NewGuid(); var userId = Guid.NewGuid(); @@ -71,8 +72,8 @@ public void ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() }); currentUser.Returns(Create.User(userId).Please); - service.Invoking(s => s.LikeComment(commentId).Wait()) - .Should().Throw() + (await service.Invoking(s => s.LikeComment(commentId, CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Conflict); } @@ -98,16 +99,16 @@ public async Task SaveInRepositoryAndPublishMessageAndReturnUserWhenLikes() .Setup(f => f.Create(It.IsAny(), It.IsAny())) .Returns(like); likeRepository - .Setup(r => r.Add(It.IsAny())) + .Setup(r => r.Add(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); publisher .Setup(p => p.Send(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); - var actual = await service.LikeComment(commentId); + var actual = await service.LikeComment(commentId, CancellationToken.None); actual.Should().Be(user); - likeRepository.Verify(r => r.Add(like), Times.Once); + likeRepository.Verify(r => r.Add(like, It.IsAny()), Times.Once); likeRepository.VerifyNoOtherCalls(); publisher.Verify(p => p.Send(EventType.LikedForumComment, likeId), Times.Once); @@ -115,7 +116,7 @@ public async Task SaveInRepositoryAndPublishMessageAndReturnUserWhenLikes() } [Fact] - public void ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() + public async Task ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() { var commentId = Guid.NewGuid(); commentReading.ReturnsAsync(new Comment @@ -127,8 +128,8 @@ public void ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() }); currentUser.Returns(Create.User().Please); - service.Invoking(s => s.DislikeComment(commentId).Wait()) - .Should().Throw() + (await service.Invoking(s => s.DislikeComment(commentId, CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Conflict); } @@ -150,12 +151,12 @@ public async Task SaveInRepositoryWhenDislikes() currentUser.Returns(user); likeRepository - .Setup(r => r.Delete(It.IsAny(), It.IsAny())) + .Setup(r => r.Delete(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); - await service.DislikeComment(commentId); + await service.DislikeComment(commentId, CancellationToken.None); - likeRepository.Verify(r => r.Delete(commentId, userId), Times.Once); + likeRepository.Verify(r => r.Delete(commentId, userId, It.IsAny()), Times.Once); likeRepository.VerifyNoOtherCalls(); } } \ No newline at end of file diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForTopicsShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForTopicsShould.cs index a24a0ccc..7c27b95f 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForTopicsShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Likes/LikeServiceForTopicsShould.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation.UserIdentity; @@ -37,7 +38,7 @@ public class LikeServiceForTopicsShould : UnitTestBase public LikeServiceForTopicsShould() { var topicReadingService = Mock(); - topicReading = topicReadingService.Setup(s => s.GetTopic(It.IsAny())); + topicReading = topicReadingService.Setup(s => s.GetTopic(It.IsAny(), It.IsAny())); var intentionManager = Mock(); intentionManager @@ -56,7 +57,7 @@ public LikeServiceForTopicsShould() } [Fact] - public void ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() + public async Task ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() { var topicId = Guid.NewGuid(); var userId = Guid.NewGuid(); @@ -70,8 +71,8 @@ public void ThrowConflictExceptionWhenUserTriesToLikeTopicTwice() }); currentUser.Returns(Create.User(userId).Please); - service.Invoking(s => s.LikeTopic(topicId).Wait()) - .Should().Throw() + (await service.Invoking(s => s.LikeTopic(topicId, CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Conflict); } @@ -97,16 +98,16 @@ public async Task SaveInRepositoryAndPublishMessageAndReturnUserWhenLikes() .Setup(f => f.Create(It.IsAny(), It.IsAny())) .Returns(like); likeRepository - .Setup(r => r.Add(It.IsAny())) + .Setup(r => r.Add(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); publisher .Setup(p => p.Send(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); - var actual = await service.LikeTopic(topicId); + var actual = await service.LikeTopic(topicId, CancellationToken.None); actual.Should().Be(user); - likeRepository.Verify(r => r.Add(like), Times.Once); + likeRepository.Verify(r => r.Add(like, It.IsAny()), Times.Once); likeRepository.VerifyNoOtherCalls(); publisher.Verify(p => p.Send(EventType.LikedTopic, likeId), Times.Once); @@ -114,7 +115,7 @@ public async Task SaveInRepositoryAndPublishMessageAndReturnUserWhenLikes() } [Fact] - public void ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() + public async Task ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() { var topicId = Guid.NewGuid(); topicReading.ReturnsAsync(new Topic @@ -126,8 +127,8 @@ public void ThrowConflictExceptionWhenUserTriesToDislikeHeNeverLiked() }); currentUser.Returns(Create.User().Please); - service.Invoking(s => s.DislikeTopic(topicId).Wait()) - .Should().Throw() + (await service.Invoking(s => s.DislikeTopic(topicId, CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Conflict); } @@ -149,12 +150,12 @@ public async Task SaveInRepositoryWhenDislikes() currentUser.Returns(user); likeRepository - .Setup(r => r.Delete(It.IsAny(), It.IsAny())) + .Setup(r => r.Delete(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); - await service.DislikeTopic(topicId); + await service.DislikeTopic(topicId, CancellationToken.None); - likeRepository.Verify(r => r.Delete(topicId, userId), Times.Once); + likeRepository.Verify(r => r.Delete(topicId, userId, It.IsAny()), Times.Once); likeRepository.VerifyNoOtherCalls(); } } \ No newline at end of file diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicCreatingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicCreatingServiceShould.cs index b67048b3..679468d6 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicCreatingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicCreatingServiceShould.cs @@ -44,7 +44,7 @@ public TopicCreatingServiceShould() .ReturnsAsync(new ValidationResult()); var forumReadingService = Mock(); - getForumSetup = forumReadingService.Setup(s => s.GetForum(It.IsAny(), true)); + getForumSetup = forumReadingService.Setup(s => s.GetForum(It.IsAny(), true, It.IsAny())); intentionManager = Mock(); intentionManager @@ -60,11 +60,11 @@ public TopicCreatingServiceShould() It.IsAny(), It.IsAny(), It.IsAny())); creatingRepository = Mock(); - saveTopicSetup = creatingRepository.Setup(r => r.Create(It.IsAny())); + saveTopicSetup = creatingRepository.Setup(r => r.Create(It.IsAny(), It.IsAny())); unreadCountersRepository = Mock(); unreadCountersRepository - .Setup(r => r.Create(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(r => r.Create(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); publisher = Mock(); @@ -92,7 +92,7 @@ public async Task AuthorizeCreateTopicAction() createTopicSetup.Returns(forumTopic); saveTopicSetup.ReturnsAsync(new Topic()); - await service.CreateTopic(createTopic); + await service.CreateTopic(createTopic, CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(ForumIntention.CreateTopic, forum)); } @@ -108,10 +108,10 @@ public async Task SaveTopic() var expected = new Topic(); saveTopicSetup.ReturnsAsync(expected); - var actual = await service.CreateTopic(createTopic); + var actual = await service.CreateTopic(createTopic, CancellationToken.None); actual.Should().Be(expected); - creatingRepository.Verify(r => r.Create(forumTopic), Times.Once); + creatingRepository.Verify(r => r.Create(forumTopic, It.IsAny()), Times.Once); creatingRepository.VerifyNoOtherCalls(); } @@ -127,9 +127,9 @@ public async Task CreateUnreadCommentsCounterForTopic() createTopicSetup.Returns(forumTopic); saveTopicSetup.ReturnsAsync(new Topic {Id = forumTopicId}); - await service.CreateTopic(createTopic); + await service.CreateTopic(createTopic, CancellationToken.None); - unreadCountersRepository.Verify(r => r.Create(forumTopicId, forumId, UnreadEntryType.Message), Times.Once); + unreadCountersRepository.Verify(r => r.Create(forumTopicId, forumId, UnreadEntryType.Message, It.IsAny()), Times.Once); unreadCountersRepository.VerifyNoOtherCalls(); } @@ -144,7 +144,7 @@ public async Task PublishMessage() createTopicSetup.Returns(forumTopic); saveTopicSetup.ReturnsAsync(new Topic {Id = forumTopicId}); - await service.CreateTopic(createTopic); + await service.CreateTopic(createTopic, CancellationToken.None); publisher.Verify(p => p.Send(EventType.NewForumTopic, forumTopicId), Times.Once); publisher.VerifyNoOtherCalls(); diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicDeletingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicDeletingServiceShould.cs index 92f51755..6d7576a0 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicDeletingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicDeletingServiceShould.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using DM.Services.Common.Authorization; using DM.Services.Common.BusinessProcesses.UnreadCounters; @@ -33,7 +34,7 @@ public class TopicDeletingServiceShould : UnitTestBase public TopicDeletingServiceShould() { var readingService = Mock(); - getTopicSetup = readingService.Setup(s => s.GetTopic(It.IsAny())); + getTopicSetup = readingService.Setup(s => s.GetTopic(It.IsAny(), It.IsAny())); intentionManager = Mock(); intentionManager @@ -49,7 +50,7 @@ public TopicDeletingServiceShould() .Returns(updateBuilder.Object); updatingRepository = Mock(); - updateSetup = updatingRepository.Setup(r => r.Update(It.IsAny>())); + updateSetup = updatingRepository.Setup(r => r.Update(It.IsAny>(), It.IsAny())); publisher = Mock(); publisher @@ -58,7 +59,7 @@ public TopicDeletingServiceShould() unreadCountersRepository = Mock(); unreadCountersRepository - .Setup(r => r.Delete(It.IsAny(), It.IsAny())) + .Setup(r => r.Delete(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); service = new TopicDeletingService(readingService.Object, @@ -76,7 +77,7 @@ public async Task AuthorizeDeletingAction() getTopicSetup.ReturnsAsync(topic); updateSetup.ReturnsAsync(new Topic()); - await service.DeleteTopic(topicId); + await service.DeleteTopic(topicId, CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(ForumIntention.AdministrateTopics, forum), Times.Once); } @@ -89,11 +90,11 @@ public async Task OnlyUpdateRemovedField() getTopicSetup.ReturnsAsync(topic); updateSetup.ReturnsAsync(new Topic()); - await service.DeleteTopic(topicId); + await service.DeleteTopic(topicId, CancellationToken.None); updateBuilder.Verify(b => b.Field(t => t.IsRemoved, true), Times.Once); updateBuilder.VerifyNoOtherCalls(); - updatingRepository.Verify(r => r.Update(updateBuilder.Object), Times.Once); + updatingRepository.Verify(r => r.Update(updateBuilder.Object, It.IsAny()), Times.Once); updatingRepository.VerifyNoOtherCalls(); } @@ -105,9 +106,9 @@ public async Task DeleteUnreadCounters() getTopicSetup.ReturnsAsync(topic); updateSetup.ReturnsAsync(new Topic()); - await service.DeleteTopic(topicId); + await service.DeleteTopic(topicId, CancellationToken.None); - unreadCountersRepository.Verify(r => r.Delete(topicId, UnreadEntryType.Message), Times.Once); + unreadCountersRepository.Verify(r => r.Delete(topicId, UnreadEntryType.Message, It.IsAny()), Times.Once); unreadCountersRepository.VerifyNoOtherCalls(); } @@ -119,7 +120,7 @@ public async Task PublishEvent() getTopicSetup.ReturnsAsync(topic); updateSetup.ReturnsAsync(new Topic()); - await service.DeleteTopic(topicId); + await service.DeleteTopic(topicId, CancellationToken.None); publisher.Verify(p => p.Send(EventType.DeletedForumTopic, topicId), Times.Once); publisher.VerifyNoOtherCalls(); diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs index 32087aea..e6011415 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using DM.Services.Authentication.Dto; using DM.Services.Authentication.Implementation.UserIdentity; @@ -44,7 +45,7 @@ public TopicReadingServiceShould() } [Fact] - public void ThrowHttpExceptionWhenAvailableTopicNotFound() + public async Task ThrowHttpExceptionWhenAvailableTopicNotFound() { var topicId = Guid.NewGuid(); currentUserSetup.Returns(Create.User().Please); @@ -56,8 +57,8 @@ public void ThrowHttpExceptionWhenAvailableTopicNotFound() .Setup(r => r.Get(It.IsAny(), It.IsAny())) .ReturnsAsync((Topic) null); - service.Invoking(s => s.GetTopic(topicId).Wait()) - .Should().Throw() + (await service.Invoking(s => s.GetTopic(topicId, CancellationToken.None)) + .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Gone); topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.SeniorModerator), Times.Once); @@ -77,7 +78,7 @@ public async Task ReturnFoundTopic() .Returns(ForumAccessPolicy.Player); currentUserSetup.Returns(Create.User().Please); - var actual = await service.GetTopic(topicId); + var actual = await service.GetTopic(topicId, CancellationToken.None); actual.Should().Be(expected); topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.Player), Times.Once); @@ -97,13 +98,13 @@ public async Task FillUnreadCountersWhenUserAuthenticated() .Returns(ForumAccessPolicy.Player); currentUserSetup.Returns(Create.User(userId).WithRole(UserRole.Player).Please); unreadCountersRepository - .Setup(r => r.SelectByEntities(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(r => r.SelectByEntities(It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) .ReturnsAsync(new Dictionary{[topicId] = 22}); - var actual = await service.GetTopic(topicId); + var actual = await service.GetTopic(topicId, CancellationToken.None); actual.Should().Be(expected); actual.UnreadCommentsCount.Should().Be(22); - unreadCountersRepository.Verify(r => r.SelectByEntities(userId, UnreadEntryType.Message, topicId), Times.Once); + unreadCountersRepository.Verify(r => r.SelectByEntities(userId, UnreadEntryType.Message, new[] {topicId}, It.IsAny()), Times.Once); } } \ No newline at end of file diff --git a/test/DM.Services.Gaming.Tests/GameCreatingServiceShould.cs b/test/DM.Services.Gaming.Tests/GameCreatingServiceShould.cs index ccbd3eed..d0351462 100644 --- a/test/DM.Services.Gaming.Tests/GameCreatingServiceShould.cs +++ b/test/DM.Services.Gaming.Tests/GameCreatingServiceShould.cs @@ -52,11 +52,11 @@ public GameCreatingServiceShould() .ReturnsAsync(new ValidationResult()); var readingService = Mock(); - readingService.Setup(s => s.GetTags()); + readingService.Setup(s => s.GetTags(It.IsAny())); assignmentService = Mock(); assignmentService - .Setup(s => s.CreateAssignment(It.IsAny(), It.IsAny())) + .Setup(s => s.CreateAssignment(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); intentionManager = Mock(); @@ -82,11 +82,11 @@ public GameCreatingServiceShould() gameRepository = Mock(); saveGameSetup = gameRepository .Setup(r => r.Create(It.IsAny(), It.IsAny(), - It.IsAny>())); + It.IsAny>(), It.IsAny())); countersRepository = Mock(); countersRepository - .Setup(r => r.Create(It.IsAny(), It.IsAny())) + .Setup(r => r.Create(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var schemaRepository = Mock(); @@ -119,7 +119,7 @@ public async Task CheckAuthorization() createRoomSetup.Returns(new Room()); saveGameSetup.ReturnsAsync(new GameExtended()); - await service.Create(new CreateGame()); + await service.Create(new CreateGame(), CancellationToken.None); intentionManager.Verify(m => m.ThrowIfForbidden(GameIntention.Create), Times.Once); } @@ -138,7 +138,7 @@ public async Task CreateModerationRequiredGameWhenUserHasLowRating() saveGameSetup.ReturnsAsync(new GameExtended()); var createGame = new CreateGame(); - await service.Create(createGame); + await service.Create(createGame, CancellationToken.None); gameFactory.Verify(f => f.Create(createGame, userId, GameStatus.RequiresModeration)); } @@ -161,7 +161,7 @@ public async Task CreateInDesiredStatusWhenUserHasHighRating(bool draft, GameSta { Draft = draft }; - await service.Create(createGame); + await service.Create(createGame, CancellationToken.None); gameFactory.Verify(f => f.Create(createGame, userId, status)); } @@ -175,13 +175,13 @@ public async Task SearchForAssistantWhenLoginGiven() createRoomSetup.Returns(room); saveGameSetup.ReturnsAsync(new GameExtended()); userRepository - .Setup(r => r.FindUserId(It.IsAny())) + .Setup(r => r.FindUserId(It.IsAny(), It.IsAny())) .ReturnsAsync((false, Guid.Empty)); var createGame = new CreateGame {AssistantLogin = "assistant boi"}; - await service.Create(createGame); + await service.Create(createGame, CancellationToken.None); - userRepository.Verify(r => r.FindUserId("assistant boi")); + userRepository.Verify(r => r.FindUserId("assistant boi", It.IsAny())); } [Fact] @@ -196,12 +196,12 @@ public async Task CreateGameWithAssistantTokenWhenFound() saveGameSetup.ReturnsAsync(new GameExtended()); var assistantId = Guid.NewGuid(); userRepository - .Setup(r => r.FindUserId(It.IsAny())) + .Setup(r => r.FindUserId(It.IsAny(), It.IsAny())) .ReturnsAsync((true, assistantId)); - await service.Create(new CreateGame {AssistantLogin = "assistant boi"}); + await service.Create(new CreateGame {AssistantLogin = "assistant boi"}, CancellationToken.None); - assignmentService.Verify(s => s.CreateAssignment(gameId, assistantId), Times.Once); + assignmentService.Verify(s => s.CreateAssignment(gameId, assistantId, It.IsAny()), Times.Once); } [Fact] @@ -214,9 +214,9 @@ public async Task SaveCreatedGameAndRoomInStorage() createRoomSetup.Returns(room); saveGameSetup.ReturnsAsync(new GameExtended()); - await service.Create(new CreateGame()); + await service.Create(new CreateGame(), CancellationToken.None); - gameRepository.Verify(r => r.Create(game, room, It.IsAny>()), Times.Once); + gameRepository.Verify(r => r.Create(game, room, It.IsAny>(), It.IsAny()), Times.Once); gameRepository.VerifyNoOtherCalls(); } @@ -231,9 +231,9 @@ public async Task CreateCountersForGameEntries(UnreadEntryType entryType) createRoomSetup.Returns(new Room()); saveGameSetup.ReturnsAsync(new GameExtended()); - await service.Create(new CreateGame()); + await service.Create(new CreateGame(), CancellationToken.None); - countersRepository.Verify(r => r.Create(gameId, entryType), Times.Once); + countersRepository.Verify(r => r.Create(gameId, entryType, It.IsAny()), Times.Once); } [Fact] @@ -245,9 +245,9 @@ public async Task CreateCountersForRoomEntries() createRoomSetup.Returns(new Room {RoomId = roomId}); saveGameSetup.ReturnsAsync(new GameExtended()); - await service.Create(new CreateGame()); + await service.Create(new CreateGame(), CancellationToken.None); - countersRepository.Verify(r => r.Create(roomId, UnreadEntryType.Message), Times.Once); + countersRepository.Verify(r => r.Create(roomId, UnreadEntryType.Message, It.IsAny()), Times.Once); } [Fact] @@ -259,7 +259,7 @@ public async Task PublishMessage() createRoomSetup.Returns(new Room()); saveGameSetup.ReturnsAsync(new GameExtended()); - await service.Create(new CreateGame()); + await service.Create(new CreateGame(), CancellationToken.None); publisher.Verify(p => p.Send(EventType.NewGame, gameId), Times.Once); publisher.VerifyNoOtherCalls(); From b7681ef42f5570a0f6ee38c8f7c0b54a6ecb25f4 Mon Sep 17 00:00:00 2001 From: Vladislav Quilin Date: Tue, 20 Aug 2024 00:28:55 +0200 Subject: [PATCH 3/4] [DM.CA] Forum storage abstractions extracted to dedicated assembly --- DM.sln | 14 ++++++ Directory.Build.props | 2 +- ...Services.Forum.Storage.Dependencies.csproj | 18 +++++++ .../ServiceCollectionExtensions.cs | 49 +++++++++++++++++++ .../DM.Services.Forum.Storage.csproj | 18 +++++++ .../Profiles}/ForumProfile.cs | 7 +-- .../Profiles}/TopicProfile.cs | 3 +- .../CommentaryCreatingRepository.cs | 14 +++--- .../CommentaryDeletingRepository.cs | 13 ++--- .../CommentaryReadingRepository.cs | 27 ++++------ .../CommentaryUpdatingRepository.cs | 6 +-- .../Storages}/Fora/ForumRepository.cs | 7 +-- .../Storages/Fora}/ModeratorRepository.cs | 14 ++---- .../Topics}/TopicCreatingRepository.cs | 6 +-- .../Topics}/TopicReadingRepository.cs | 24 ++++----- .../Topics}/TopicUpdatingRepository.cs | 6 +-- .../Deleting/ICommentaryDeletingRepository.cs | 2 +- .../Reading/ICommentaryReadingRepository.cs | 2 +- .../Fora/IForumRepository.cs | 2 +- .../Moderation/IModeratorRepository.cs | 2 +- .../Creating/ITopicCreatingRepository.cs | 2 +- .../Topics/Reading/ITopicReadingRepository.cs | 5 +- .../Topics/Reading/TopicReadingService.cs | 2 +- .../Updating/ITopicUpdatingRepository.cs | 2 +- .../Dto/Internal/CommentToDelete.cs | 2 +- src/DM.Web.API/DM.Web.API.csproj | 1 + src/DM.Web.API/Startup.cs | 3 ++ .../Topics/TopicReadingServiceShould.cs | 10 ++-- 28 files changed, 164 insertions(+), 99 deletions(-) create mode 100644 src/DM.Services.Forum.Storage.Dependencies/DM.Services.Forum.Storage.Dependencies.csproj create mode 100644 src/DM.Services.Forum.Storage.Dependencies/ServiceCollectionExtensions.cs create mode 100644 src/DM.Services.Forum.Storage/DM.Services.Forum.Storage.csproj rename src/{DM.Services.Forum/Dto => DM.Services.Forum.Storage/Profiles}/ForumProfile.cs (68%) rename src/{DM.Services.Forum/Dto => DM.Services.Forum.Storage/Profiles}/TopicProfile.cs (94%) rename src/{DM.Services.Forum/BusinessProcesses/Commentaries/Creating => DM.Services.Forum.Storage/Storages/Commentaries}/CommentaryCreatingRepository.cs (66%) rename src/{DM.Services.Forum/BusinessProcesses/Commentaries/Deleting => DM.Services.Forum.Storage/Storages/Commentaries}/CommentaryDeletingRepository.cs (83%) rename src/{DM.Services.Forum/BusinessProcesses/Commentaries/Reading => DM.Services.Forum.Storage/Storages/Commentaries}/CommentaryReadingRepository.cs (67%) rename src/{DM.Services.Forum/BusinessProcesses/Commentaries/Updating => DM.Services.Forum.Storage/Storages/Commentaries}/CommentaryUpdatingRepository.cs (86%) rename src/{DM.Services.Forum/BusinessProcesses => DM.Services.Forum.Storage/Storages}/Fora/ForumRepository.cs (86%) rename src/{DM.Services.Forum/BusinessProcesses/Moderation => DM.Services.Forum.Storage/Storages/Fora}/ModeratorRepository.cs (68%) rename src/{DM.Services.Forum/BusinessProcesses/Topics/Creating => DM.Services.Forum.Storage/Storages/Topics}/TopicCreatingRepository.cs (86%) rename src/{DM.Services.Forum/BusinessProcesses/Topics/Reading => DM.Services.Forum.Storage/Storages/Topics}/TopicReadingRepository.cs (78%) rename src/{DM.Services.Forum/BusinessProcesses/Topics/Updating => DM.Services.Forum.Storage/Storages/Topics}/TopicUpdatingRepository.cs (86%) diff --git a/DM.sln b/DM.sln index 98081eef..e9f72f24 100644 --- a/DM.sln +++ b/DM.sln @@ -96,6 +96,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github-actions", "github-ac .github\workflows\dotnet.yml = .github\workflows\dotnet.yml EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Forum.Storage", "src\DM.Services.Forum.Storage\DM.Services.Forum.Storage.csproj", "{101BB826-5855-45C6-BA33-D73E530D4D84}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Forum.Storage.Dependencies", "src\DM.Services.Forum.Storage.Dependencies\DM.Services.Forum.Storage.Dependencies.csproj", "{90B89BED-DBBA-41C7-B91D-12D2CE905FD5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -206,6 +210,14 @@ Global {550DC966-8960-4F98-BA6B-BEDBA73BB431}.Debug|Any CPU.Build.0 = Debug|Any CPU {550DC966-8960-4F98-BA6B-BEDBA73BB431}.Release|Any CPU.ActiveCfg = Release|Any CPU {550DC966-8960-4F98-BA6B-BEDBA73BB431}.Release|Any CPU.Build.0 = Release|Any CPU + {101BB826-5855-45C6-BA33-D73E530D4D84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {101BB826-5855-45C6-BA33-D73E530D4D84}.Debug|Any CPU.Build.0 = Debug|Any CPU + {101BB826-5855-45C6-BA33-D73E530D4D84}.Release|Any CPU.ActiveCfg = Release|Any CPU + {101BB826-5855-45C6-BA33-D73E530D4D84}.Release|Any CPU.Build.0 = Release|Any CPU + {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {37EE71A5-6F98-42E7-B92F-3E2B65C67850} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} @@ -246,5 +258,7 @@ Global {EAA9F9E3-2684-4C5C-BC70-403F8CE1C4A1} = {60E4E464-934E-42F0-8137-3F2BA8E3063B} {6DD9DA97-AAFF-46D4-9313-367998B98CF9} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} {28709B36-C22C-4EB9-906F-19CDCC769338} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} + {101BB826-5855-45C6-BA33-D73E530D4D84} = {74044CFF-FF4E-4604-AB39-018D19914357} + {90B89BED-DBBA-41C7-B91D-12D2CE905FD5} = {74044CFF-FF4E-4604-AB39-018D19914357} EndGlobalSection EndGlobal diff --git a/Directory.Build.props b/Directory.Build.props index 8d0162f1..473fc20e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,7 @@ - <_Parameter1>$(AssemblyName).DependencyInjection + <_Parameter1>$(AssemblyName).Dependencies <_Parameter1>$(AssemblyName).Tests diff --git a/src/DM.Services.Forum.Storage.Dependencies/DM.Services.Forum.Storage.Dependencies.csproj b/src/DM.Services.Forum.Storage.Dependencies/DM.Services.Forum.Storage.Dependencies.csproj new file mode 100644 index 00000000..546c80a2 --- /dev/null +++ b/src/DM.Services.Forum.Storage.Dependencies/DM.Services.Forum.Storage.Dependencies.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/src/DM.Services.Forum.Storage.Dependencies/ServiceCollectionExtensions.cs b/src/DM.Services.Forum.Storage.Dependencies/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..b604ae04 --- /dev/null +++ b/src/DM.Services.Forum.Storage.Dependencies/ServiceCollectionExtensions.cs @@ -0,0 +1,49 @@ +using AutoMapper; +using DM.Services.Forum.BusinessProcesses.Commentaries.Creating; +using DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; +using DM.Services.Forum.BusinessProcesses.Commentaries.Reading; +using DM.Services.Forum.BusinessProcesses.Commentaries.Updating; +using DM.Services.Forum.BusinessProcesses.Fora; +using DM.Services.Forum.BusinessProcesses.Moderation; +using DM.Services.Forum.BusinessProcesses.Topics.Creating; +using DM.Services.Forum.BusinessProcesses.Topics.Reading; +using DM.Services.Forum.BusinessProcesses.Topics.Updating; +using DM.Services.Forum.Storage.Profiles; +using DM.Services.Forum.Storage.Storages.Commentaries; +using DM.Services.Forum.Storage.Storages.Fora; +using DM.Services.Forum.Storage.Storages.Topics; +using Microsoft.Extensions.DependencyInjection; + +namespace DM.Services.Forum.Storage.Dependencies; + +/// +/// Registrar +/// +public static class ServiceCollectionExtensions +{ + /// + /// Register forum storage dependencies + /// + /// + /// + public static IServiceCollection AddForumStorage(this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + // TODO: Switch to .AddAutoMapper + services.AddScoped(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/DM.Services.Forum.Storage/DM.Services.Forum.Storage.csproj b/src/DM.Services.Forum.Storage/DM.Services.Forum.Storage.csproj new file mode 100644 index 00000000..0a0a63a9 --- /dev/null +++ b/src/DM.Services.Forum.Storage/DM.Services.Forum.Storage.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/src/DM.Services.Forum/Dto/ForumProfile.cs b/src/DM.Services.Forum.Storage/Profiles/ForumProfile.cs similarity index 68% rename from src/DM.Services.Forum/Dto/ForumProfile.cs rename to src/DM.Services.Forum.Storage/Profiles/ForumProfile.cs index 15503f56..5c4793a7 100644 --- a/src/DM.Services.Forum/Dto/ForumProfile.cs +++ b/src/DM.Services.Forum.Storage/Profiles/ForumProfile.cs @@ -1,7 +1,6 @@ -using System.Linq; using AutoMapper; -namespace DM.Services.Forum.Dto; +namespace DM.Services.Forum.Storage.Profiles; /// /// Profile for forum DTO and DAL mapping @@ -11,9 +10,7 @@ internal class ForumProfile : Profile /// public ForumProfile() { - CreateMap(); - - CreateMap() + CreateMap() .ForMember(d => d.Id, s => s.MapFrom(f => f.ForumId)) .ForMember(d => d.ModeratorIds, s => s.MapFrom(f => f.Moderators.Select(m => m.UserId))); diff --git a/src/DM.Services.Forum/Dto/TopicProfile.cs b/src/DM.Services.Forum.Storage/Profiles/TopicProfile.cs similarity index 94% rename from src/DM.Services.Forum/Dto/TopicProfile.cs rename to src/DM.Services.Forum.Storage/Profiles/TopicProfile.cs index e5e43f54..3e16ba68 100644 --- a/src/DM.Services.Forum/Dto/TopicProfile.cs +++ b/src/DM.Services.Forum.Storage/Profiles/TopicProfile.cs @@ -1,10 +1,9 @@ -using System.Linq; using AutoMapper; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.Forum.Dto.Output; using Comment = DM.Services.DataAccess.BusinessObjects.Common.Comment; -namespace DM.Services.Forum.Dto; +namespace DM.Services.Forum.Storage.Profiles; /// /// Profile for topic DTO and DAL mapping diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryCreatingRepository.cs similarity index 66% rename from src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryCreatingRepository.cs index 136b66b4..baba270a 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Creating/CommentaryCreatingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryCreatingRepository.cs @@ -1,15 +1,13 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.DataAccess.RelationalStorage; +using DM.Services.Forum.BusinessProcesses.Commentaries.Creating; using Microsoft.EntityFrameworkCore; using Comment = DM.Services.DataAccess.BusinessObjects.Common.Comment; -namespace DM.Services.Forum.BusinessProcesses.Commentaries.Creating; +namespace DM.Services.Forum.Storage.Storages.Commentaries; /// internal class CommentaryCreatingRepository( @@ -17,16 +15,16 @@ internal class CommentaryCreatingRepository( IMapper mapper) : ICommentaryCreatingRepository { /// - public async Task Create(Comment comment, IUpdateBuilder topicUpdate, - CancellationToken cancellationToken) + public async Task Create( + Comment comment, IUpdateBuilder topicUpdate, CancellationToken cancellationToken) { dbContext.Comments.Add(comment); topicUpdate.AttachTo(dbContext); - await dbContext.SaveChangesAsync(); + await dbContext.SaveChangesAsync(cancellationToken); return await dbContext.Comments .TagWith("DM.Forum.CreatedComment") .Where(c => c.CommentId == comment.CommentId) .ProjectTo(mapper.ConfigurationProvider) - .FirstAsync(); + .FirstAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryDeletingRepository.cs similarity index 83% rename from src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryDeletingRepository.cs index 42b82b0b..4ef1776b 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/CommentaryDeletingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryDeletingRepository.cs @@ -1,17 +1,14 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Common; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.DataAccess.RelationalStorage; +using DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; using DM.Services.Forum.Dto.Internal; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; +namespace DM.Services.Forum.Storage.Storages.Commentaries; /// internal class CommentaryDeletingRepository( @@ -19,14 +16,12 @@ internal class CommentaryDeletingRepository( IMapper mapper) : ICommentaryDeletingRepository { /// - public Task GetForDelete(Guid commentId, CancellationToken cancellationToken) - { - return dbContext.Comments + public Task GetForDelete(Guid commentId, CancellationToken cancellationToken) => + dbContext.Comments .TagWith("DM.Forum.CommentToDelete") .Where(c => !c.IsRemoved && c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) .FirstOrDefaultAsync(cancellationToken); - } /// public Task Delete(IUpdateBuilder update, IUpdateBuilder topicUpdate, diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryReadingRepository.cs similarity index 67% rename from src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryReadingRepository.cs index 97841373..8a097b36 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/CommentaryReadingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryReadingRepository.cs @@ -1,17 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Common.Dto; using DM.Services.Core.Dto; using DM.Services.Core.Extensions; using DM.Services.DataAccess; +using DM.Services.Forum.BusinessProcesses.Commentaries.Reading; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Commentaries.Reading; +namespace DM.Services.Forum.Storage.Storages.Commentaries; /// internal class CommentaryReadingRepository( @@ -19,30 +15,27 @@ internal class CommentaryReadingRepository( IMapper mapper) : ICommentaryReadingRepository { /// - public Task Count(Guid topicId, CancellationToken cancellationToken) => dbContext.Comments - .TagWith("DM.Forum.CommentsCount") - .CountAsync(c => !c.IsRemoved && c.EntityId == topicId, cancellationToken); + public Task Count(Guid topicId, CancellationToken cancellationToken) => + dbContext.Comments + .TagWith("DM.Forum.CommentsCount") + .CountAsync(c => !c.IsRemoved && c.EntityId == topicId, cancellationToken); /// public async Task> Get( - Guid topicId, PagingData paging, CancellationToken cancellationToken) - { - return await dbContext.Comments + Guid topicId, PagingData paging, CancellationToken cancellationToken) => + await dbContext.Comments .TagWith("DM.Forum.CommentsList") .Where(c => !c.IsRemoved && c.EntityId == topicId) .OrderBy(c => c.CreateDate) .Page(paging) .ProjectTo(mapper.ConfigurationProvider) .ToArrayAsync(cancellationToken); - } /// - public Task Get(Guid commentId, CancellationToken cancellationToken) - { - return dbContext.Comments + public Task Get(Guid commentId, CancellationToken cancellationToken) => + dbContext.Comments .TagWith("DM.Forum.Comment") .Where(c => !c.IsRemoved && c.CommentId == commentId) .ProjectTo(mapper.ConfigurationProvider) .FirstOrDefaultAsync(cancellationToken); - } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryUpdatingRepository.cs similarity index 86% rename from src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryUpdatingRepository.cs index 57c33eae..3e19822f 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Updating/CommentaryUpdatingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Commentaries/CommentaryUpdatingRepository.cs @@ -1,14 +1,12 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.RelationalStorage; +using DM.Services.Forum.BusinessProcesses.Commentaries.Updating; using Microsoft.EntityFrameworkCore; using Comment = DM.Services.DataAccess.BusinessObjects.Common.Comment; -namespace DM.Services.Forum.BusinessProcesses.Commentaries.Updating; +namespace DM.Services.Forum.Storage.Storages.Commentaries; /// internal class CommentaryUpdatingRepository( diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs b/src/DM.Services.Forum.Storage/Storages/Fora/ForumRepository.cs similarity index 86% rename from src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Fora/ForumRepository.cs index c05cf084..446a198b 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/ForumRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Fora/ForumRepository.cs @@ -1,15 +1,12 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Core.Caching; using DM.Services.Core.Dto.Enums; using DM.Services.DataAccess; +using DM.Services.Forum.BusinessProcesses.Fora; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Fora; +namespace DM.Services.Forum.Storage.Storages.Fora; /// internal class ForumRepository( diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs b/src/DM.Services.Forum.Storage/Storages/Fora/ModeratorRepository.cs similarity index 68% rename from src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Fora/ModeratorRepository.cs index f80e5e11..20e35d5a 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/ModeratorRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Fora/ModeratorRepository.cs @@ -1,15 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Core.Dto; using DM.Services.DataAccess; +using DM.Services.Forum.BusinessProcesses.Moderation; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Moderation; +namespace DM.Services.Forum.Storage.Storages.Fora; /// internal class ModeratorRepository( @@ -17,13 +13,11 @@ internal class ModeratorRepository( IMapper mapper) : IModeratorRepository { /// - public async Task> Get(Guid forumId, CancellationToken cancellationToken) - { - return await dmDbContext.ForumModerators + public async Task> Get(Guid forumId, CancellationToken cancellationToken) => + await dmDbContext.ForumModerators .TagWith("DM.Forum.ModeratorsList") .Where(m => m.ForumId == forumId) .Select(m => m.User) .ProjectTo(mapper.ConfigurationProvider) .ToArrayAsync(cancellationToken); - } } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Topics/TopicCreatingRepository.cs similarity index 86% rename from src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Topics/TopicCreatingRepository.cs index 259b73c4..d37fa984 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/TopicCreatingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Topics/TopicCreatingRepository.cs @@ -1,14 +1,12 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Fora; +using DM.Services.Forum.BusinessProcesses.Topics.Creating; using DM.Services.Forum.Dto.Output; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Topics.Creating; +namespace DM.Services.Forum.Storage.Storages.Topics; /// internal class TopicCreatingRepository( diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Topics/TopicReadingRepository.cs similarity index 78% rename from src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Topics/TopicReadingRepository.cs index 4deceacc..7c1ab359 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Topics/TopicReadingRepository.cs @@ -1,18 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Core.Dto; using DM.Services.Core.Dto.Enums; using DM.Services.Core.Extensions; using DM.Services.DataAccess; +using DM.Services.Forum.BusinessProcesses.Topics.Reading; using DM.Services.Forum.Dto.Output; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Topics.Reading; +namespace DM.Services.Forum.Storage.Storages.Topics; /// internal class TopicReadingRepository( @@ -25,11 +21,11 @@ internal class TopicReadingRepository( /// public Task Count(Guid forumId, CancellationToken cancellationToken) => dbContext.ForumTopics .TagWith("DM.Forum.TopicsCount") - .CountAsync(t => !t.IsRemoved && t.ForumId == forumId && !t.Attached); + .CountAsync(t => !t.IsRemoved && t.ForumId == forumId && !t.Attached, cancellationToken); /// - public async Task> Get(Guid forumId, PagingData pagingData, bool attached, - CancellationToken cancellationToken) + public async Task> Get( + Guid forumId, PagingData pagingData, bool attached, CancellationToken cancellationToken) { var query = dbContext.ForumTopics .TagWith("DM.Forum.TopicsList") @@ -50,17 +46,15 @@ public async Task> Get(Guid forumId, PagingData pagingData, b orderedQuery = query.OrderByDescending(q => q.LastActivityDate); } - return await orderedQuery.Page(pagingData).ToArrayAsync(); + return await orderedQuery.Page(pagingData).ToArrayAsync(cancellationToken); } /// - public async Task Get(Guid topicId, ForumAccessPolicy accessPolicy) - { - return await dbContext.ForumTopics + public async Task Get(Guid topicId, ForumAccessPolicy accessPolicy, CancellationToken cancellationToken) => + await dbContext.ForumTopics .TagWith("DM.Forum.Topic") .Where(t => !t.IsRemoved && t.ForumTopicId == topicId && (t.Forum.ViewPolicy & accessPolicy) != ForumAccessPolicy.NoOne) .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(); - } + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs b/src/DM.Services.Forum.Storage/Storages/Topics/TopicUpdatingRepository.cs similarity index 86% rename from src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs rename to src/DM.Services.Forum.Storage/Storages/Topics/TopicUpdatingRepository.cs index 685d4f67..29c6545d 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/TopicUpdatingRepository.cs +++ b/src/DM.Services.Forum.Storage/Storages/Topics/TopicUpdatingRepository.cs @@ -1,15 +1,13 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Fora; using DM.Services.DataAccess.RelationalStorage; +using DM.Services.Forum.BusinessProcesses.Topics.Updating; using DM.Services.Forum.Dto.Output; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Forum.BusinessProcesses.Topics.Updating; +namespace DM.Services.Forum.Storage.Storages.Topics; /// internal class TopicUpdatingRepository( diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs index 36833b9f..233fcd7b 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Deleting/ICommentaryDeletingRepository.cs @@ -11,7 +11,7 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Deleting; /// /// Deleting commentary storage /// -internal interface ICommentaryDeletingRepository +public interface ICommentaryDeletingRepository { /// /// Get single comment to delete by its identifier diff --git a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs index e8c0476a..5af39bba 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Commentaries/Reading/ICommentaryReadingRepository.cs @@ -10,7 +10,7 @@ namespace DM.Services.Forum.BusinessProcesses.Commentaries.Reading; /// /// Forum comments storage /// -internal interface ICommentaryReadingRepository +public interface ICommentaryReadingRepository { /// /// Count comments of the topic diff --git a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs index 714181ef..88a121da 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Fora/IForumRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Forum.BusinessProcesses.Fora; /// /// Fora storage /// -internal interface IForumRepository +public interface IForumRepository { /// /// Get list of available fora by access policy diff --git a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs index 9ddbe0ca..dabd31bb 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Moderation/IModeratorRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Forum.BusinessProcesses.Moderation; /// /// Forum moderators storage /// -internal interface IModeratorRepository +public interface IModeratorRepository { /// /// Get list of forum moderators diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs index 4d603a55..75234405 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Creating/ITopicCreatingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Creating; /// /// Creating topics storage /// -internal interface ITopicCreatingRepository +public interface ITopicCreatingRepository { /// /// Create new topic diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs index 7bead0be..4d0ef314 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/ITopicReadingRepository.cs @@ -11,7 +11,7 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Reading; /// /// Forum topics storage /// -internal interface ITopicReadingRepository +public interface ITopicReadingRepository { /// /// Get number of forum topics @@ -37,6 +37,7 @@ Task> Get(Guid forumId, PagingData pagingData, bool attached, /// /// Topic identifier /// Forum access policy + /// /// - Task Get(Guid topicId, ForumAccessPolicy accessPolicy); + Task Get(Guid topicId, ForumAccessPolicy accessPolicy, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs index d379fcae..5839cb29 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Reading/TopicReadingService.cs @@ -64,7 +64,7 @@ public async Task GetTopic(Guid topicId, CancellationToken cancellationTo { var identity = identityProvider.Current; var accessPolicy = accessPolicyConverter.Convert(identity.User.Role); - var topic = await repository.Get(topicId, accessPolicy); + var topic = await repository.Get(topicId, accessPolicy, cancellationToken); if (topic == null) { throw new HttpException(HttpStatusCode.Gone, "Topic not found"); diff --git a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs index 8d9b2099..fbed95c1 100644 --- a/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs +++ b/src/DM.Services.Forum/BusinessProcesses/Topics/Updating/ITopicUpdatingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Forum.BusinessProcesses.Topics.Updating; /// /// Updating topics storage /// -internal interface ITopicUpdatingRepository +public interface ITopicUpdatingRepository { /// /// Update existing topic diff --git a/src/DM.Services.Forum/Dto/Internal/CommentToDelete.cs b/src/DM.Services.Forum/Dto/Internal/CommentToDelete.cs index a4093b88..0b7a2c1b 100644 --- a/src/DM.Services.Forum/Dto/Internal/CommentToDelete.cs +++ b/src/DM.Services.Forum/Dto/Internal/CommentToDelete.cs @@ -5,7 +5,7 @@ namespace DM.Services.Forum.Dto.Internal; /// /// DTO to remove the commentary /// -internal class CommentToDelete : Comment +public class CommentToDelete : Comment { /// /// Tells if the comment is last comment of its parent topic diff --git a/src/DM.Web.API/DM.Web.API.csproj b/src/DM.Web.API/DM.Web.API.csproj index d9e5407a..ddc562a9 100644 --- a/src/DM.Web.API/DM.Web.API.csproj +++ b/src/DM.Web.API/DM.Web.API.csproj @@ -24,6 +24,7 @@ + diff --git a/src/DM.Web.API/Startup.cs b/src/DM.Web.API/Startup.cs index 0019ed8b..d619d0f5 100644 --- a/src/DM.Web.API/Startup.cs +++ b/src/DM.Web.API/Startup.cs @@ -8,6 +8,7 @@ using DM.Services.Core.Parsing; using DM.Services.DataAccess; using DM.Services.Forum; +using DM.Services.Forum.Storage.Dependencies; using DM.Services.Gaming; using DM.Services.MessageQueuing; using DM.Services.Notifications; @@ -82,6 +83,8 @@ public void ConfigureServices(IServiceCollection services) services.AddSignalR(); + services.AddForumStorage(); + services .AddSwaggerGen(c => c.ConfigureGen()) .AddMvc(config => config.ModelBinderProviders.Insert(0, new ReadableGuidBinderProvider())) diff --git a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs index e6011415..1b990d1d 100644 --- a/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs +++ b/test/DM.Services.Forum.Tests/BusinessProcesses/Topics/TopicReadingServiceShould.cs @@ -54,14 +54,14 @@ public async Task ThrowHttpExceptionWhenAvailableTopicNotFound() .Returns(ForumAccessPolicy.SeniorModerator); topicRepository - .Setup(r => r.Get(It.IsAny(), It.IsAny())) + .Setup(r => r.Get(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Topic) null); (await service.Invoking(s => s.GetTopic(topicId, CancellationToken.None)) .Should().ThrowAsync()) .And.StatusCode.Should().Be(HttpStatusCode.Gone); - topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.SeniorModerator), Times.Once); + topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.SeniorModerator, It.IsAny()), Times.Once); topicRepository.VerifyNoOtherCalls(); } @@ -71,7 +71,7 @@ public async Task ReturnFoundTopic() var topicId = Guid.NewGuid(); var expected = new Topic(); topicRepository - .Setup(r => r.Get(It.IsAny(), It.IsAny())) + .Setup(r => r.Get(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(expected); accessPolicyConverter .Setup(c => c.Convert(It.IsAny())) @@ -81,7 +81,7 @@ public async Task ReturnFoundTopic() var actual = await service.GetTopic(topicId, CancellationToken.None); actual.Should().Be(expected); - topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.Player), Times.Once); + topicRepository.Verify(r => r.Get(topicId, ForumAccessPolicy.Player, It.IsAny()), Times.Once); } [Fact] @@ -91,7 +91,7 @@ public async Task FillUnreadCountersWhenUserAuthenticated() var userId = Guid.NewGuid(); var expected = new Topic(); topicRepository - .Setup(r => r.Get(It.IsAny(), It.IsAny())) + .Setup(r => r.Get(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(expected); accessPolicyConverter .Setup(c => c.Convert(It.IsAny())) From 2bed8855d39449ba86cdf667dd7447ac942fc2d7 Mon Sep 17 00:00:00 2001 From: Vladislav Quilin Date: Tue, 20 Aug 2024 01:24:37 +0200 Subject: [PATCH 4/4] [DM.CA] Community storage abstractions extracted to dedicated assembly --- DM.sln | 14 ++++ ...ices.Community.Storage.Dependencies.csproj | 18 +++++ .../ServiceCollectionExtensions.cs | 74 +++++++++++++++++++ .../DM.Services.Community.Storage.csproj | 14 ++++ .../Profiles}/ChatMessageProfile.cs | 3 +- .../Profiles}/MessagingProfile.cs | 4 +- .../Profiles}/ReadingProfile.cs | 3 +- .../Profiles}/ReviewProfile.cs | 3 +- .../Storages/Account}/ActivationRepository.cs | 13 +--- .../Account}/EmailChangeRepository.cs | 8 +- .../Account/PasswordChangeRepository.cs | 46 ++++++++++++ .../Account}/PasswordResetRepository.cs | 5 +- .../Account}/RegistrationRepository.cs | 5 +- .../Account/TokenVerificationRepository.cs | 22 ++++++ .../Messaging}/ChatCreatingRepository.cs | 6 +- .../Messaging}/ChatReadingRepository.cs | 17 ++--- .../ConversationReadingRepository.cs | 41 +++++----- .../Messaging}/MessageCreatingRepository.cs | 6 +- .../Messaging/MessageReadingRepository.cs | 40 ++++++++++ .../Storages/Polls}/PollCreatingRepository.cs | 10 +-- .../Storages/Polls}/PollReadingRepository.cs | 8 +- .../Storages/Polls}/PollVotingRepository.cs | 6 +- .../Reviews}/ReviewCreatingRepository.cs | 6 +- .../Reviews}/ReviewReadingRepository.cs | 10 +-- .../Reviews}/ReviewUpdatingRepository.cs | 6 +- .../Storages/Users}/UserReadingRepository.cs | 19 ++--- .../Storages/Users}/UserUpdatingRepository.cs | 5 +- .../Activation/IActivationRepository.cs | 2 +- .../EmailChange/IEmailChangeRepository.cs | 2 +- .../IPasswordChangeRepository.cs | 5 +- .../PasswordChangeRepository.cs | 56 -------------- .../UserPasswordChangeValidator.cs | 4 +- .../PasswordReset/IPasswordResetRepository.cs | 2 +- .../Registration/IRegistrationRepository.cs | 2 +- .../ITokenVerificationRepository.cs | 2 +- .../TokenVerificationRepository.cs | 24 ------ .../Chat/Creating/IChatCreatingRepository.cs | 2 +- .../Chat/Reading/IChatReadingRepository.cs | 2 +- .../Creating/IMessageCreatingRepository.cs | 2 +- .../Reading/IConversationReadingRepository.cs | 2 +- .../Reading/IMessageReadingRepository.cs | 2 +- .../Reading/MessageReadingRepository.cs | 41 ---------- .../Polls/Creating/IPollCreatingRepository.cs | 2 +- .../Polls/Reading/IPollReadingRepository.cs | 2 +- .../Polls/Voting/IPollVotingRepository.cs | 2 +- .../Creating/IReviewCreatingRepository.cs | 2 +- .../Reading/IReviewReadingRepository.cs | 2 +- .../Updating/IReviewUpdatingRepository.cs | 2 +- .../Users/Reading/IUserReadingRepository.cs | 2 +- .../Users/Updating/IUserUpdatingRepository.cs | 2 +- src/DM.Web.API/DM.Web.API.csproj | 1 + src/DM.Web.API/Startup.cs | 2 + 52 files changed, 330 insertions(+), 251 deletions(-) create mode 100644 src/DM.Services.Community.Storage.Dependencies/DM.Services.Community.Storage.Dependencies.csproj create mode 100644 src/DM.Services.Community.Storage.Dependencies/ServiceCollectionExtensions.cs create mode 100644 src/DM.Services.Community.Storage/DM.Services.Community.Storage.csproj rename src/{DM.Services.Community/BusinessProcesses/Chat/Reading => DM.Services.Community.Storage/Profiles}/ChatMessageProfile.cs (71%) rename src/{DM.Services.Community/BusinessProcesses/Messaging/Reading => DM.Services.Community.Storage/Profiles}/MessagingProfile.cs (85%) rename src/{DM.Services.Community/BusinessProcesses/Users/Reading => DM.Services.Community.Storage/Profiles}/ReadingProfile.cs (73%) rename src/{DM.Services.Community/BusinessProcesses/Reviews/Reading => DM.Services.Community.Storage/Profiles}/ReviewProfile.cs (77%) rename src/{DM.Services.Community/BusinessProcesses/Account/Activation => DM.Services.Community.Storage/Storages/Account}/ActivationRepository.cs (77%) rename src/{DM.Services.Community/BusinessProcesses/Account/EmailChange => DM.Services.Community.Storage/Storages/Account}/EmailChangeRepository.cs (77%) create mode 100644 src/DM.Services.Community.Storage/Storages/Account/PasswordChangeRepository.cs rename src/{DM.Services.Community/BusinessProcesses/Account/PasswordReset => DM.Services.Community.Storage/Storages/Account}/PasswordResetRepository.cs (76%) rename src/{DM.Services.Community/BusinessProcesses/Account/Registration => DM.Services.Community.Storage/Storages/Account}/RegistrationRepository.cs (88%) create mode 100644 src/DM.Services.Community.Storage/Storages/Account/TokenVerificationRepository.cs rename src/{DM.Services.Community/BusinessProcesses/Chat/Creating => DM.Services.Community.Storage/Storages/Messaging}/ChatCreatingRepository.cs (86%) rename src/{DM.Services.Community/BusinessProcesses/Chat/Reading => DM.Services.Community.Storage/Storages/Messaging}/ChatReadingRepository.cs (75%) rename src/{DM.Services.Community/BusinessProcesses/Messaging/Reading => DM.Services.Community.Storage/Storages/Messaging}/ConversationReadingRepository.cs (65%) rename src/{DM.Services.Community/BusinessProcesses/Messaging/Creating => DM.Services.Community.Storage/Storages/Messaging}/MessageCreatingRepository.cs (88%) create mode 100644 src/DM.Services.Community.Storage/Storages/Messaging/MessageReadingRepository.cs rename src/{DM.Services.Community/BusinessProcesses/Polls/Creating => DM.Services.Community.Storage/Storages/Polls}/PollCreatingRepository.cs (62%) rename src/{DM.Services.Community/BusinessProcesses/Polls/Reading => DM.Services.Community.Storage/Storages/Polls}/PollReadingRepository.cs (91%) rename src/{DM.Services.Community/BusinessProcesses/Polls/Voting => DM.Services.Community.Storage/Storages/Polls}/PollVotingRepository.cs (88%) rename src/{DM.Services.Community/BusinessProcesses/Reviews/Creating => DM.Services.Community.Storage/Storages/Reviews}/ReviewCreatingRepository.cs (85%) rename src/{DM.Services.Community/BusinessProcesses/Reviews/Reading => DM.Services.Community.Storage/Storages/Reviews}/ReviewReadingRepository.cs (82%) rename src/{DM.Services.Community/BusinessProcesses/Reviews/Updating => DM.Services.Community.Storage/Storages/Reviews}/ReviewUpdatingRepository.cs (86%) rename src/{DM.Services.Community/BusinessProcesses/Users/Reading => DM.Services.Community.Storage/Storages/Users}/UserReadingRepository.cs (81%) rename src/{DM.Services.Community/BusinessProcesses/Users/Updating => DM.Services.Community.Storage/Storages/Users}/UserUpdatingRepository.cs (87%) delete mode 100644 src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs delete mode 100644 src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs delete mode 100644 src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs diff --git a/DM.sln b/DM.sln index e9f72f24..60fcddff 100644 --- a/DM.sln +++ b/DM.sln @@ -100,6 +100,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Forum.Storage", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Forum.Storage.Dependencies", "src\DM.Services.Forum.Storage.Dependencies\DM.Services.Forum.Storage.Dependencies.csproj", "{90B89BED-DBBA-41C7-B91D-12D2CE905FD5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Community.Storage", "src\DM.Services.Community.Storage\DM.Services.Community.Storage.csproj", "{6C2B575F-2E45-49DE-9F89-F554752767E4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DM.Services.Community.Storage.Dependencies", "src\DM.Services.Community.Storage.Dependencies\DM.Services.Community.Storage.Dependencies.csproj", "{D3D67774-BF7D-4BB3-A877-B706C8D87E73}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -218,6 +222,14 @@ Global {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Debug|Any CPU.Build.0 = Debug|Any CPU {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Release|Any CPU.ActiveCfg = Release|Any CPU {90B89BED-DBBA-41C7-B91D-12D2CE905FD5}.Release|Any CPU.Build.0 = Release|Any CPU + {6C2B575F-2E45-49DE-9F89-F554752767E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C2B575F-2E45-49DE-9F89-F554752767E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C2B575F-2E45-49DE-9F89-F554752767E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C2B575F-2E45-49DE-9F89-F554752767E4}.Release|Any CPU.Build.0 = Release|Any CPU + {D3D67774-BF7D-4BB3-A877-B706C8D87E73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3D67774-BF7D-4BB3-A877-B706C8D87E73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3D67774-BF7D-4BB3-A877-B706C8D87E73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3D67774-BF7D-4BB3-A877-B706C8D87E73}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {37EE71A5-6F98-42E7-B92F-3E2B65C67850} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} @@ -260,5 +272,7 @@ Global {28709B36-C22C-4EB9-906F-19CDCC769338} = {EA05C4AE-2D7E-4F1F-B112-64FB021BB3B9} {101BB826-5855-45C6-BA33-D73E530D4D84} = {74044CFF-FF4E-4604-AB39-018D19914357} {90B89BED-DBBA-41C7-B91D-12D2CE905FD5} = {74044CFF-FF4E-4604-AB39-018D19914357} + {6C2B575F-2E45-49DE-9F89-F554752767E4} = {755C13DD-F19B-450A-BC2D-5C195545DCE8} + {D3D67774-BF7D-4BB3-A877-B706C8D87E73} = {755C13DD-F19B-450A-BC2D-5C195545DCE8} EndGlobalSection EndGlobal diff --git a/src/DM.Services.Community.Storage.Dependencies/DM.Services.Community.Storage.Dependencies.csproj b/src/DM.Services.Community.Storage.Dependencies/DM.Services.Community.Storage.Dependencies.csproj new file mode 100644 index 00000000..d7405299 --- /dev/null +++ b/src/DM.Services.Community.Storage.Dependencies/DM.Services.Community.Storage.Dependencies.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/src/DM.Services.Community.Storage.Dependencies/ServiceCollectionExtensions.cs b/src/DM.Services.Community.Storage.Dependencies/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..069cf7f2 --- /dev/null +++ b/src/DM.Services.Community.Storage.Dependencies/ServiceCollectionExtensions.cs @@ -0,0 +1,74 @@ +using AutoMapper; +using DM.Services.Community.BusinessProcesses.Account.Activation; +using DM.Services.Community.BusinessProcesses.Account.EmailChange; +using DM.Services.Community.BusinessProcesses.Account.PasswordChange; +using DM.Services.Community.BusinessProcesses.Account.PasswordReset; +using DM.Services.Community.BusinessProcesses.Account.Registration; +using DM.Services.Community.BusinessProcesses.Account.Verification; +using DM.Services.Community.BusinessProcesses.Chat.Creating; +using DM.Services.Community.BusinessProcesses.Chat.Reading; +using DM.Services.Community.BusinessProcesses.Messaging.Creating; +using DM.Services.Community.BusinessProcesses.Messaging.Reading; +using DM.Services.Community.BusinessProcesses.Polls.Creating; +using DM.Services.Community.BusinessProcesses.Polls.Reading; +using DM.Services.Community.BusinessProcesses.Polls.Voting; +using DM.Services.Community.BusinessProcesses.Reviews.Creating; +using DM.Services.Community.BusinessProcesses.Reviews.Reading; +using DM.Services.Community.BusinessProcesses.Reviews.Updating; +using DM.Services.Community.BusinessProcesses.Users.Reading; +using DM.Services.Community.BusinessProcesses.Users.Updating; +using DM.Services.Community.Storage.Profiles; +using DM.Services.Community.Storage.Storages.Account; +using DM.Services.Community.Storage.Storages.Messaging; +using DM.Services.Community.Storage.Storages.Polls; +using DM.Services.Community.Storage.Storages.Reviews; +using DM.Services.Community.Storage.Storages.Users; +using Microsoft.Extensions.DependencyInjection; + +namespace DM.Services.Community.Storage.Dependencies; + +/// +/// Registrar +/// +public static class ServiceCollectionExtensions +{ + /// + /// Register community storage dependencies + /// + /// + /// + public static IServiceCollection AddCommunityStorage(this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + + // TODO: Switch to .AddAutoMapper + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/DM.Services.Community.Storage/DM.Services.Community.Storage.csproj b/src/DM.Services.Community.Storage/DM.Services.Community.Storage.csproj new file mode 100644 index 00000000..846317d5 --- /dev/null +++ b/src/DM.Services.Community.Storage/DM.Services.Community.Storage.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatMessageProfile.cs b/src/DM.Services.Community.Storage/Profiles/ChatMessageProfile.cs similarity index 71% rename from src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatMessageProfile.cs rename to src/DM.Services.Community.Storage/Profiles/ChatMessageProfile.cs index d6529b63..9537e845 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatMessageProfile.cs +++ b/src/DM.Services.Community.Storage/Profiles/ChatMessageProfile.cs @@ -1,7 +1,8 @@ using AutoMapper; +using DM.Services.Community.BusinessProcesses.Chat.Reading; using DbMessage = DM.Services.DataAccess.BusinessObjects.Common.ChatMessage; -namespace DM.Services.Community.BusinessProcesses.Chat.Reading; +namespace DM.Services.Community.Storage.Profiles; /// internal class ChatMessageProfile : Profile diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessagingProfile.cs b/src/DM.Services.Community.Storage/Profiles/MessagingProfile.cs similarity index 85% rename from src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessagingProfile.cs rename to src/DM.Services.Community.Storage/Profiles/MessagingProfile.cs index 8442e65a..bf319f7c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessagingProfile.cs +++ b/src/DM.Services.Community.Storage/Profiles/MessagingProfile.cs @@ -1,9 +1,9 @@ -using System.Linq; using AutoMapper; +using DM.Services.Community.BusinessProcesses.Messaging.Reading; using DbConversation = DM.Services.DataAccess.BusinessObjects.Messaging.Conversation; using DbMessage = DM.Services.DataAccess.BusinessObjects.Messaging.Message; -namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; +namespace DM.Services.Community.Storage.Profiles; /// internal class MessagingProfile : Profile diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/ReadingProfile.cs b/src/DM.Services.Community.Storage/Profiles/ReadingProfile.cs similarity index 73% rename from src/DM.Services.Community/BusinessProcesses/Users/Reading/ReadingProfile.cs rename to src/DM.Services.Community.Storage/Profiles/ReadingProfile.cs index 5d8d2032..ccb555a3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/ReadingProfile.cs +++ b/src/DM.Services.Community.Storage/Profiles/ReadingProfile.cs @@ -1,8 +1,9 @@ using AutoMapper; +using DM.Services.Community.BusinessProcesses.Users.Reading; using DM.Services.Core.Dto; using DM.Services.DataAccess.BusinessObjects.Users; -namespace DM.Services.Community.BusinessProcesses.Users.Reading; +namespace DM.Services.Community.Storage.Profiles; /// internal class ReadingProfile : Profile diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewProfile.cs b/src/DM.Services.Community.Storage/Profiles/ReviewProfile.cs similarity index 77% rename from src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewProfile.cs rename to src/DM.Services.Community.Storage/Profiles/ReviewProfile.cs index 192a832d..00bed08a 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewProfile.cs +++ b/src/DM.Services.Community.Storage/Profiles/ReviewProfile.cs @@ -1,7 +1,8 @@ using AutoMapper; +using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DbReview = DM.Services.DataAccess.BusinessObjects.Common.Review; -namespace DM.Services.Community.BusinessProcesses.Reviews.Reading; +namespace DM.Services.Community.Storage.Profiles; /// internal class ReviewProfile : Profile diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/ActivationRepository.cs similarity index 77% rename from src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs rename to src/DM.Services.Community.Storage/Storages/Account/ActivationRepository.cs index 5ce6ede3..60456718 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/ActivationRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Account/ActivationRepository.cs @@ -1,13 +1,10 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Account.Activation; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; using DM.Services.DataAccess.RelationalStorage; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Account.Activation; +namespace DM.Services.Community.Storage.Storages.Account; /// internal class ActivationRepository( @@ -15,13 +12,11 @@ internal class ActivationRepository( { /// public async Task FindUserToActivate(Guid tokenId, DateTimeOffset createdSince, - CancellationToken cancellationToken) - { - return (await dbContext.Tokens + CancellationToken cancellationToken) => + (await dbContext.Tokens .Where(t => t.TokenId == tokenId && t.CreateDate > createdSince) .Select(t => new {t.UserId}) .FirstOrDefaultAsync(cancellationToken))?.UserId; - } /// public Task ActivateUser(IUpdateBuilder updateUser, IUpdateBuilder updateToken, diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/EmailChangeRepository.cs similarity index 77% rename from src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs rename to src/DM.Services.Community.Storage/Storages/Account/EmailChangeRepository.cs index d6f68bd0..3bae48f6 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/EmailChangeRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Account/EmailChangeRepository.cs @@ -1,15 +1,13 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Authentication.Dto; +using DM.Services.Community.BusinessProcesses.Account.EmailChange; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; using DM.Services.DataAccess.RelationalStorage; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Account.EmailChange; +namespace DM.Services.Community.Storage.Storages.Account; /// internal class EmailChangeRepository( @@ -17,7 +15,7 @@ internal class EmailChangeRepository( IMapper mapper) : IEmailChangeRepository { /// - public Task FindUser(string login, CancellationToken cancellationToken) => dbContext.Users + public Task FindUser(string login, CancellationToken cancellationToken) => dbContext.Users .Where(u => u.Login.ToLower() == login.ToLower()) .ProjectTo(mapper.ConfigurationProvider) .FirstOrDefaultAsync(cancellationToken); diff --git a/src/DM.Services.Community.Storage/Storages/Account/PasswordChangeRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/PasswordChangeRepository.cs new file mode 100644 index 00000000..3ba07603 --- /dev/null +++ b/src/DM.Services.Community.Storage/Storages/Account/PasswordChangeRepository.cs @@ -0,0 +1,46 @@ +using AutoMapper; +using AutoMapper.QueryableExtensions; +using DM.Services.Authentication.Dto; +using DM.Services.Community.BusinessProcesses.Account.PasswordChange; +using DM.Services.DataAccess; +using DM.Services.DataAccess.BusinessObjects.Users; +using DM.Services.DataAccess.RelationalStorage; +using Microsoft.EntityFrameworkCore; + +namespace DM.Services.Community.Storage.Storages.Account; + +/// +internal class PasswordChangeRepository( + DmDbContext dbContext, + IMapper mapper) : IPasswordChangeRepository +{ + /// + public Task FindUser(string login, CancellationToken cancellationToken) => + dbContext.Users + .Where(u => u.Login.ToLower() == login.ToLower()) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); + + /// + public Task FindUser(Guid tokenId, CancellationToken cancellationToken) => + dbContext.Tokens + .Where(u => u.TokenId == tokenId) + .Select(u => u.User) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); + + /// + public Task TokenValid(Guid tokenId, DateTimeOffset createdSince, CancellationToken cancellationToken) => + dbContext.Tokens + .Where(t => t.TokenId == tokenId && t.Type == TokenType.PasswordChange && t.CreateDate > createdSince) + .AnyAsync(cancellationToken); + + /// + public Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate, + CancellationToken cancellationToken) + { + userUpdate.AttachTo(dbContext); + tokenUpdate?.AttachTo(dbContext); + return dbContext.SaveChangesAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/PasswordResetRepository.cs similarity index 76% rename from src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs rename to src/DM.Services.Community.Storage/Storages/Account/PasswordResetRepository.cs index db9c39e1..b2ef73e8 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/PasswordResetRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Account/PasswordResetRepository.cs @@ -1,9 +1,8 @@ -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Account.PasswordReset; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; -namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset; +namespace DM.Services.Community.Storage.Storages.Account; /// internal class PasswordResetRepository( diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/RegistrationRepository.cs similarity index 88% rename from src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs rename to src/DM.Services.Community.Storage/Storages/Account/RegistrationRepository.cs index 80205b4d..d388a722 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/RegistrationRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Account/RegistrationRepository.cs @@ -1,10 +1,9 @@ -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Account.Registration; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Account.Registration; +namespace DM.Services.Community.Storage.Storages.Account; /// internal class RegistrationRepository( diff --git a/src/DM.Services.Community.Storage/Storages/Account/TokenVerificationRepository.cs b/src/DM.Services.Community.Storage/Storages/Account/TokenVerificationRepository.cs new file mode 100644 index 00000000..09905935 --- /dev/null +++ b/src/DM.Services.Community.Storage/Storages/Account/TokenVerificationRepository.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Account.Verification; +using DM.Services.Core.Dto; +using DM.Services.DataAccess; +using Microsoft.EntityFrameworkCore; + +namespace DM.Services.Community.Storage.Storages.Account; + +/// +internal class TokenVerificationRepository( + DmDbContext dbContext, + IMapper mapper) : ITokenVerificationRepository +{ + /// + public Task GetTokenOwner(Guid tokenId, CancellationToken cancellationToken) => + dbContext.Tokens + .Where(t => t.TokenId == tokenId && !t.IsRemoved) + .Select(t => t.User) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); +} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Messaging/ChatCreatingRepository.cs similarity index 86% rename from src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Messaging/ChatCreatingRepository.cs index 19651522..130991e5 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/ChatCreatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Messaging/ChatCreatingRepository.cs @@ -1,14 +1,12 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Chat.Creating; using DM.Services.Community.BusinessProcesses.Chat.Reading; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; using DbMessage = DM.Services.DataAccess.BusinessObjects.Common.ChatMessage; -namespace DM.Services.Community.BusinessProcesses.Chat.Creating; +namespace DM.Services.Community.Storage.Storages.Messaging; /// internal class ChatCreatingRepository( diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Messaging/ChatReadingRepository.cs similarity index 75% rename from src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Messaging/ChatReadingRepository.cs index f43a39d2..2d4cf2af 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/ChatReadingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Messaging/ChatReadingRepository.cs @@ -1,16 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Chat.Reading; using DM.Services.Core.Dto; using DM.Services.Core.Extensions; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Chat.Reading; +namespace DM.Services.Community.Storage.Storages.Messaging; /// internal class ChatReadingRepository( @@ -40,8 +36,9 @@ await dbContext.ChatMessages .ToArrayAsync(cancellationToken); /// - public async Task Get(Guid id, CancellationToken cancellationToken) => await dbContext.ChatMessages - .Where(m => m.ChatMessageId == id) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); + public async Task Get(Guid id, CancellationToken cancellationToken) => + await dbContext.ChatMessages + .Where(m => m.ChatMessageId == id) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); } \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Messaging/ConversationReadingRepository.cs similarity index 65% rename from src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Messaging/ConversationReadingRepository.cs index 28f7ed85..6b343038 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/ConversationReadingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Messaging/ConversationReadingRepository.cs @@ -1,19 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Messaging.Reading; using DM.Services.Core.Dto; using DM.Services.Core.Extensions; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Messaging; using Microsoft.EntityFrameworkCore; +using Conversation = DM.Services.Community.BusinessProcesses.Messaging.Reading.Conversation; using DbConversation = DM.Services.DataAccess.BusinessObjects.Messaging.Conversation; -namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; +namespace DM.Services.Community.Storage.Storages.Messaging; /// internal class ConversationReadingRepository( @@ -45,24 +42,28 @@ await dbContext.Conversations .ToArrayAsync(cancellationToken); /// - public Task Get(Guid conversationId, Guid userId, CancellationToken cancellationToken) => dbContext.Conversations - .Where(UserParticipates(userId)) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); + public Task Get(Guid conversationId, Guid userId, CancellationToken cancellationToken) => + dbContext.Conversations + .Where(UserParticipates(userId)) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); /// - public async Task FindUser(string login, CancellationToken cancellationToken) => (await dbContext.Users - .Where(u => u.Login.ToLower() == login.ToLower() && !u.IsRemoved && u.Activated) - .Select(u => new {u.UserId}) - .FirstOrDefaultAsync(cancellationToken))?.UserId; + public async Task FindUser(string login, CancellationToken cancellationToken) => + (await dbContext.Users + .Where(u => u.Login.ToLower() == login.ToLower() && !u.IsRemoved && u.Activated) + .Select(u => new { u.UserId }) + .FirstOrDefaultAsync(cancellationToken))?.UserId; /// - public Task FindVisaviConversation(Guid userId, Guid visaviId, CancellationToken cancellationToken) => dbContext.Conversations - .Where(c => c.Visavi) - .Where(UserParticipates(userId)) - .Where(UserParticipates(visaviId)) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); + public Task FindVisaviConversation( + Guid userId, Guid visaviId, CancellationToken cancellationToken) => + dbContext.Conversations + .Where(c => c.Visavi) + .Where(UserParticipates(userId)) + .Where(UserParticipates(visaviId)) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); /// public async Task Create(DbConversation conversation, diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Messaging/MessageCreatingRepository.cs similarity index 88% rename from src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Messaging/MessageCreatingRepository.cs index 46b9c084..3b9117cc 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/MessageCreatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Messaging/MessageCreatingRepository.cs @@ -1,8 +1,6 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Messaging.Creating; using DM.Services.Community.BusinessProcesses.Messaging.Reading; using DM.Services.DataAccess; using DM.Services.DataAccess.RelationalStorage; @@ -10,7 +8,7 @@ using DbConversation = DM.Services.DataAccess.BusinessObjects.Messaging.Conversation; using DbMessage = DM.Services.DataAccess.BusinessObjects.Messaging.Message; -namespace DM.Services.Community.BusinessProcesses.Messaging.Creating; +namespace DM.Services.Community.Storage.Storages.Messaging; /// internal class MessageCreatingRepository( diff --git a/src/DM.Services.Community.Storage/Storages/Messaging/MessageReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Messaging/MessageReadingRepository.cs new file mode 100644 index 00000000..66d29861 --- /dev/null +++ b/src/DM.Services.Community.Storage/Storages/Messaging/MessageReadingRepository.cs @@ -0,0 +1,40 @@ +using AutoMapper; +using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Messaging.Reading; +using DM.Services.Core.Dto; +using DM.Services.Core.Extensions; +using DM.Services.DataAccess; +using Microsoft.EntityFrameworkCore; + +namespace DM.Services.Community.Storage.Storages.Messaging; + +/// +internal class MessageReadingRepository( + DmDbContext dbContext, + IMapper mapper) : IMessageReadingRepository +{ + /// + public Task Count(Guid conversationId, CancellationToken cancellationToken) => + dbContext.Messages + .Where(m => !m.IsRemoved && m.ConversationId == conversationId) + .CountAsync(cancellationToken); + + /// + public async Task> Get(Guid conversationId, PagingData paging, + CancellationToken cancellationToken) => + await dbContext.Messages + .Where(m => !m.IsRemoved && m.ConversationId == conversationId) + .OrderBy(m => m.CreateDate) + .Page(paging) + .ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken); + + /// + public Task Get(Guid messageId, Guid userId, CancellationToken cancellationToken) => + dbContext.Conversations + .Where(ConversationReadingRepository.UserParticipates(userId)) + .SelectMany(c => c.Messages) + .Where(m => !m.IsRemoved && m.MessageId == messageId) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); +} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Polls/PollCreatingRepository.cs similarity index 62% rename from src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Polls/PollCreatingRepository.cs index c52b20d5..5b5b07bd 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/PollCreatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Polls/PollCreatingRepository.cs @@ -1,19 +1,17 @@ -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Polls.Creating; using DM.Services.Community.BusinessProcesses.Polls.Reading; using DM.Services.DataAccess.MongoIntegration; using MongoDB.Driver; using DbPoll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; -using Poll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; -namespace DM.Services.Community.BusinessProcesses.Polls.Creating; +namespace DM.Services.Community.Storage.Storages.Polls; /// internal class PollCreatingRepository(DmMongoClient client) - : MongoCollectionRepository(client), IPollCreatingRepository + : MongoCollectionRepository(client), IPollCreatingRepository { /// - public async Task Create(DbPoll poll, CancellationToken cancellationToken) + public async Task Create(DbPoll poll, CancellationToken cancellationToken) { await Collection.InsertOneAsync(poll, cancellationToken: cancellationToken); return await Collection.Find(Filter.Eq(p => p.Id, poll.Id)) diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Polls/PollReadingRepository.cs similarity index 91% rename from src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Polls/PollReadingRepository.cs index 0dea0553..91935f3c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/PollReadingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Polls/PollReadingRepository.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Polls.Reading; using DM.Services.Core.Dto; using DM.Services.DataAccess.MongoIntegration; using MongoDB.Driver; using DbPoll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; -namespace DM.Services.Community.BusinessProcesses.Polls.Reading; +namespace DM.Services.Community.Storage.Storages.Polls; /// internal class PollReadingRepository(DmMongoClient client) diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs b/src/DM.Services.Community.Storage/Storages/Polls/PollVotingRepository.cs similarity index 88% rename from src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Polls/PollVotingRepository.cs index 645a5172..c9b22306 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/PollVotingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Polls/PollVotingRepository.cs @@ -1,13 +1,11 @@ -using System; -using System.Threading; -using System.Threading.Tasks; using DM.Services.Community.BusinessProcesses.Polls.Reading; +using DM.Services.Community.BusinessProcesses.Polls.Voting; using DM.Services.DataAccess.MongoIntegration; using MongoDB.Driver; using MongoDB.Driver.Linq; using DbPoll = DM.Services.DataAccess.BusinessObjects.Fora.Poll; -namespace DM.Services.Community.BusinessProcesses.Polls.Voting; +namespace DM.Services.Community.Storage.Storages.Polls; /// internal class PollVotingRepository(DmMongoClient client) diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewCreatingRepository.cs similarity index 85% rename from src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Reviews/ReviewCreatingRepository.cs index afecd76c..8e942784 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/ReviewCreatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewCreatingRepository.cs @@ -1,14 +1,12 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Reviews.Creating; using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; using DbReview = DM.Services.DataAccess.BusinessObjects.Common.Review; -namespace DM.Services.Community.BusinessProcesses.Reviews.Creating; +namespace DM.Services.Community.Storage.Storages.Reviews; /// internal class ReviewCreatingRepository( diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewReadingRepository.cs similarity index 82% rename from src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Reviews/ReviewReadingRepository.cs index d8434135..2f3862ab 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/ReviewReadingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewReadingRepository.cs @@ -1,16 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Reviews.Reading; using DM.Services.Core.Dto; using DM.Services.Core.Extensions; using DM.Services.DataAccess; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Reviews.Reading; +namespace DM.Services.Community.Storage.Storages.Reviews; /// internal class ReviewReadingRepository( @@ -34,7 +30,7 @@ await dbContext.Reviews .ToArrayAsync(cancellationToken); /// - public Task Get(Guid id, CancellationToken cancellationToken) => + public Task Get(Guid id, CancellationToken cancellationToken) => dbContext.Reviews .Where(r => !r.IsRemoved && r.ReviewId == id) .ProjectTo(mapper.ConfigurationProvider) diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewUpdatingRepository.cs similarity index 86% rename from src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Reviews/ReviewUpdatingRepository.cs index c9fc61af..557293ab 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/ReviewUpdatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Reviews/ReviewUpdatingRepository.cs @@ -1,14 +1,12 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using DM.Services.Community.BusinessProcesses.Reviews.Reading; +using DM.Services.Community.BusinessProcesses.Reviews.Updating; using DM.Services.DataAccess; using DM.Services.DataAccess.RelationalStorage; using Microsoft.EntityFrameworkCore; -namespace DM.Services.Community.BusinessProcesses.Reviews.Updating; +namespace DM.Services.Community.Storage.Storages.Reviews; /// internal class ReviewUpdatingRepository( diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs b/src/DM.Services.Community.Storage/Storages/Users/UserReadingRepository.cs similarity index 81% rename from src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Users/UserReadingRepository.cs index 5e148193..7444892c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/UserReadingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Users/UserReadingRepository.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; +using DM.Services.Community.BusinessProcesses.Users.Reading; using DM.Services.Core.Dto; using DM.Services.Core.Extensions; using DM.Services.Core.Implementation; @@ -15,7 +11,7 @@ using Microsoft.EntityFrameworkCore; using MongoDB.Driver; -namespace DM.Services.Community.BusinessProcesses.Users.Reading; +namespace DM.Services.Community.Storage.Storages.Users; /// internal class UserReadingRepository( @@ -56,13 +52,14 @@ private IQueryable GetQuery(bool withInactive) } /// - public Task GetUser(string login, CancellationToken cancellationToken) => dmDbContext.Users - .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); + public Task GetUser(string login, CancellationToken cancellationToken) => + dmDbContext.Users + .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) + .ProjectTo(mapper.ConfigurationProvider) + .FirstOrDefaultAsync(cancellationToken); /// - public async Task GetUserDetails(string login, CancellationToken cancellationToken) + public async Task GetUserDetails(string login, CancellationToken cancellationToken) { var userDetails = await dmDbContext.Users .Where(u => !u.IsRemoved && u.Activated && u.Login.ToLower() == login.ToLower()) diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs b/src/DM.Services.Community.Storage/Storages/Users/UserUpdatingRepository.cs similarity index 87% rename from src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs rename to src/DM.Services.Community.Storage/Storages/Users/UserUpdatingRepository.cs index 3a58acad..07d564f3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/UserUpdatingRepository.cs +++ b/src/DM.Services.Community.Storage/Storages/Users/UserUpdatingRepository.cs @@ -1,12 +1,11 @@ -using System.Threading; -using System.Threading.Tasks; +using DM.Services.Community.BusinessProcesses.Users.Updating; using DM.Services.DataAccess; using DM.Services.DataAccess.BusinessObjects.Users; using DM.Services.DataAccess.BusinessObjects.Users.Settings; using DM.Services.DataAccess.MongoIntegration; using DM.Services.DataAccess.RelationalStorage; -namespace DM.Services.Community.BusinessProcesses.Users.Updating; +namespace DM.Services.Community.Storage.Storages.Users; /// internal class UserUpdatingRepository( diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs index 8117bf2d..dea28ed5 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Activation/IActivationRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.Activation; /// /// Activation storage /// -internal interface IActivationRepository +public interface IActivationRepository { /// /// Find user identifier by its activation token identifier diff --git a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs index 7aab154e..24da9ffc 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/EmailChange/IEmailChangeRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.EmailChange; /// /// Storage for email changing /// -internal interface IEmailChangeRepository +public interface IEmailChangeRepository { /// /// Find user by login diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs index ba28df51..4503c9ce 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/IPasswordChangeRepository.cs @@ -10,7 +10,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordChange; /// /// Storage for password change /// -internal interface IPasswordChangeRepository +public interface IPasswordChangeRepository { /// /// Find existing user @@ -33,8 +33,9 @@ internal interface IPasswordChangeRepository /// /// /// + /// /// - Task TokenValid(Guid tokenId, DateTimeOffset createdSince); + Task TokenValid(Guid tokenId, DateTimeOffset createdSince, CancellationToken cancellationToken); /// /// Save user password changes diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs deleted file mode 100644 index 05efab7a..00000000 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/PasswordChangeRepository.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using DM.Services.Authentication.Dto; -using DM.Services.DataAccess; -using DM.Services.DataAccess.BusinessObjects.Users; -using DM.Services.DataAccess.RelationalStorage; -using Microsoft.EntityFrameworkCore; - -namespace DM.Services.Community.BusinessProcesses.Account.PasswordChange; - -/// -internal class PasswordChangeRepository : IPasswordChangeRepository -{ - private readonly DmDbContext dbContext; - private readonly IMapper mapper; - - /// - public PasswordChangeRepository( - DmDbContext dbContext, - IMapper mapper) - { - this.dbContext = dbContext; - this.mapper = mapper; - } - - /// - public Task FindUser(string login, CancellationToken cancellationToken) => dbContext.Users - .Where(u => u.Login.ToLower() == login.ToLower()) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); - - /// - public Task FindUser(Guid tokenId, CancellationToken cancellationToken) => dbContext.Tokens - .Where(u => u.TokenId == tokenId) - .Select(u => u.User) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); - - /// - public Task TokenValid(Guid tokenId, DateTimeOffset createdSince) => dbContext.Tokens - .AnyAsync(t => t.TokenId == tokenId && - t.Type == TokenType.PasswordChange && t.CreateDate > createdSince); - - /// - public Task UpdatePassword(IUpdateBuilder userUpdate, IUpdateBuilder tokenUpdate, - CancellationToken cancellationToken) - { - userUpdate.AttachTo(dbContext); - tokenUpdate?.AttachTo(dbContext); - return dbContext.SaveChangesAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs index 313dd7d1..11f155e2 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordChange/UserPasswordChangeValidator.cs @@ -20,10 +20,10 @@ public UserPasswordChangeValidator( When(c => c.Token.HasValue, () => RuleFor(c => c.Token.Value) .NotEmpty().WithMessage(ValidationError.Empty) - .MustAsync(async (token, _) => + .MustAsync(async (token, ct) => { var tokenValid = await passwordChangeRepository.TokenValid( - token, dateTimeProvider.Now - TimeSpan.FromDays(1)); + token, dateTimeProvider.Now - TimeSpan.FromDays(1), ct); return tokenValid; }) .WithMessage(ValidationError.Invalid)) diff --git a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs index 77797310..04855530 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/PasswordReset/IPasswordResetRepository.cs @@ -7,7 +7,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.PasswordReset; /// /// Storage for password resetting /// -internal interface IPasswordResetRepository +public interface IPasswordResetRepository { /// /// Create password restoration token diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs index a25c4542..ff2b3bde 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Registration/IRegistrationRepository.cs @@ -7,7 +7,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.Registration; /// /// Registration information storage /// -internal interface IRegistrationRepository +public interface IRegistrationRepository { /// /// Tells if user with certain email is already registered diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs index 74f91fbb..e4c772c6 100644 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Account/Verification/ITokenVerificationRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Account.Verification; /// /// Storage for token verification /// -internal interface ITokenVerificationRepository +public interface ITokenVerificationRepository { /// /// Get user that token was generated for diff --git a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs b/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs deleted file mode 100644 index f6e4ba4b..00000000 --- a/src/DM.Services.Community/BusinessProcesses/Account/Verification/TokenVerificationRepository.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using DM.Services.Core.Dto; -using DM.Services.DataAccess; -using Microsoft.EntityFrameworkCore; - -namespace DM.Services.Community.BusinessProcesses.Account.Verification; - -/// -internal class TokenVerificationRepository( - DmDbContext dbContext, - IMapper mapper) : ITokenVerificationRepository -{ - /// - public Task GetTokenOwner(Guid tokenId, CancellationToken cancellationToken) => dbContext.Tokens - .Where(t => t.TokenId == tokenId && !t.IsRemoved) - .Select(t => t.User) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); -} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs index 19f0d330..6f32f152 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Creating/IChatCreatingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Chat.Creating; /// /// Storage for chat creating /// -internal interface IChatCreatingRepository +public interface IChatCreatingRepository { /// /// Create new chat message diff --git a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs index e5861caf..4065d522 100644 --- a/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Chat/Reading/IChatReadingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Chat.Reading; /// /// Storage for reading chat messages /// -internal interface IChatReadingRepository +public interface IChatReadingRepository { /// /// Count chat messages diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs index 83418d0b..c368ee11 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Creating/IMessageCreatingRepository.cs @@ -10,7 +10,7 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Creating; /// /// Storage for message creating /// -internal interface IMessageCreatingRepository +public interface IMessageCreatingRepository { /// /// Save message diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs index 021a309f..6be2f996 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IConversationReadingRepository.cs @@ -11,7 +11,7 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// /// Storage for reading user conversations /// -internal interface IConversationReadingRepository +public interface IConversationReadingRepository { /// /// Count user participated conversations diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs index 02073ed7..cbcb7b7c 100644 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/IMessageReadingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; /// /// Storage for reading the messages /// -internal interface IMessageReadingRepository +public interface IMessageReadingRepository { /// /// Count messages in conversation diff --git a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs deleted file mode 100644 index 034de7d2..00000000 --- a/src/DM.Services.Community/BusinessProcesses/Messaging/Reading/MessageReadingRepository.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using DM.Services.Core.Dto; -using DM.Services.Core.Extensions; -using DM.Services.DataAccess; -using Microsoft.EntityFrameworkCore; - -namespace DM.Services.Community.BusinessProcesses.Messaging.Reading; - -/// -internal class MessageReadingRepository( - DmDbContext dbContext, - IMapper mapper) : IMessageReadingRepository -{ - /// - public Task Count(Guid conversationId, CancellationToken cancellationToken) => dbContext.Messages - .Where(m => !m.IsRemoved && m.ConversationId == conversationId) - .CountAsync(cancellationToken); - - /// - public async Task> Get(Guid conversationId, PagingData paging, - CancellationToken cancellationToken) => await dbContext.Messages - .Where(m => !m.IsRemoved && m.ConversationId == conversationId) - .OrderBy(m => m.CreateDate) - .Page(paging) - .ProjectTo(mapper.ConfigurationProvider) - .ToArrayAsync(cancellationToken); - - /// - public Task Get(Guid messageId, Guid userId, CancellationToken cancellationToken) => dbContext.Conversations - .Where(ConversationReadingRepository.UserParticipates(userId)) - .SelectMany(c => c.Messages) - .Where(m => !m.IsRemoved && m.MessageId == messageId) - .ProjectTo(mapper.ConfigurationProvider) - .FirstOrDefaultAsync(cancellationToken); -} \ No newline at end of file diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs index 04e8a40a..c439e7c4 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Creating/IPollCreatingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Creating; /// /// Storage for poll creating /// -internal interface IPollCreatingRepository +public interface IPollCreatingRepository { /// /// Create new poll diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs index 192f46a4..262fdda8 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Reading/IPollReadingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Reading; /// /// Storage for reading polls /// -internal interface IPollReadingRepository +public interface IPollReadingRepository { /// /// Count all diff --git a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs index 7732f95c..fc18812e 100644 --- a/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Polls/Voting/IPollVotingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Polls.Voting; /// /// Storage for poll voting /// -internal interface IPollVotingRepository +public interface IPollVotingRepository { /// /// Vote for the poll option diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs index 40228df8..bed248c3 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Creating/IReviewCreatingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Creating; /// /// Storage for review creating /// -internal interface IReviewCreatingRepository +public interface IReviewCreatingRepository { /// /// Create new review diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs index f432c3c3..d8a5d694 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Reading/IReviewReadingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Reading; /// /// Storage for reading the site reviews /// -internal interface IReviewReadingRepository +public interface IReviewReadingRepository { /// /// Get total count of reviews diff --git a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs index e1a3a29e..ccf7c7ae 100644 --- a/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Reviews/Updating/IReviewUpdatingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Reviews.Updating; /// /// Storage for updating review /// -internal interface IReviewUpdatingRepository +public interface IReviewUpdatingRepository { /// /// Update review diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs index 59e2b8f6..2e9166b8 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Reading/IUserReadingRepository.cs @@ -8,7 +8,7 @@ namespace DM.Services.Community.BusinessProcesses.Users.Reading; /// /// Community users storage /// -internal interface IUserReadingRepository +public interface IUserReadingRepository { /// /// Count community users by filter diff --git a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs index 3b48f5cd..14d098ba 100644 --- a/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs +++ b/src/DM.Services.Community/BusinessProcesses/Users/Updating/IUserUpdatingRepository.cs @@ -9,7 +9,7 @@ namespace DM.Services.Community.BusinessProcesses.Users.Updating; /// /// Storage for user updating /// -internal interface IUserUpdatingRepository +public interface IUserUpdatingRepository { /// /// Save user changes diff --git a/src/DM.Web.API/DM.Web.API.csproj b/src/DM.Web.API/DM.Web.API.csproj index ddc562a9..39fdbf77 100644 --- a/src/DM.Web.API/DM.Web.API.csproj +++ b/src/DM.Web.API/DM.Web.API.csproj @@ -22,6 +22,7 @@ + diff --git a/src/DM.Web.API/Startup.cs b/src/DM.Web.API/Startup.cs index d619d0f5..9dbf5a71 100644 --- a/src/DM.Web.API/Startup.cs +++ b/src/DM.Web.API/Startup.cs @@ -2,6 +2,7 @@ using Autofac; using DM.Services.Common; using DM.Services.Community; +using DM.Services.Community.Storage.Dependencies; using DM.Services.Core.Configuration; using DM.Services.Core.Extensions; using DM.Services.Core.Logging; @@ -84,6 +85,7 @@ public void ConfigureServices(IServiceCollection services) services.AddSignalR(); services.AddForumStorage(); + services.AddCommunityStorage(); services .AddSwaggerGen(c => c.ConfigureGen())