Repository navigation
Split MessageProviderService into one service per message area - #977
Open
KrzysztofPajak wants to merge 3 commits into
Open
KrzysztofPajak wants to merge 3 commits into
KrzysztofPajak wants to merge 3 commits into
Conversation
added 2 commits
October 22, 2026 20:45
MessageProviderService was a 2100-line class behind a 50-member interface, so every caller (order handlers, account controllers, scheduled tasks, plugins) depended on every message the platform sends. The typed Send*Message methods move verbatim into seven services: Customer, Order, Newsletter, Catalog, MerchandiseReturn, Vendor and Cms (I<Area>MessageProviderService). The lookups they share (store, active template, email account, language) move to IMessageLookupService, and IMessageProviderService keeps only the generic SendNotification. Each caller now takes the one interface it uses. Breaking change: code outside the repository that calls a typed send method on IMessageProviderService, or overrides one in a subclass of MessageProviderService, must switch to the area interface. Template names, tokens and DI lifetimes are unchanged.
| //store in database | ||
| if (_commonSettings.StoreInDatabaseContactUsForm) | ||
| await _mediator.Send(new InsertContactUsCommand { | ||
| CustomerId = customer.Id, |
- Skip deleted bidders in the auction lost/outbid/store-owner sends and resolve the language per losing bidder instead of reusing the first one - Tolerate a null customer in the back-in-stock send and a missing vendor in the vendor review send - Publish MessageTokensAdded and use the customer's store in the customer-delete store owner notification - Resolve stores through IMessageLookupService.GetStore in the gift voucher and auction-expired sends, dropping IStoreService from the order and catalog services - Point the notification skill and agent at the per-area services and BuildAsync
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the architecture backlog (item S5: god classes,
MessageProviderService)Type: feature
Issue
Grand.Business.Messages/Services/MessageProviderService.cswas 2103 lines behind a 50-memberIMessageProviderService. Every caller (order and shipping handlers, account and login controllers, the auction task, the Facebook and Google login plugins) depended on every message the platform sends, and every test had to mock the whole interface.Solution
The typed
Send*Messagemethods move, unchanged and with their comments, into one service per message area, each registered as scoped like before:ICustomerMessageProviderServiceIOrderMessageProviderServiceINewsletterMessageProviderServiceICatalogMessageProviderServiceIMerchandiseReturnMessageProviderServiceIVendorMessageProviderServiceICmsMessageProviderServiceThe lookups they share (store, active template, email account, language) move from protected virtual helpers to
IMessageLookupService/MessageLookupService, bodies unchanged.IMessageProviderServicekeeps only the genericSendNotification;MessageProviderServicenow depends only onIQueuedEmailService.AddCustomerTokensIfNotNullbecame an internalLiquidObjectBuilderextension, since five services use it.Each caller used exactly one area, so each now takes that one interface.
.ai/skills/message-notification.mddescribes the new shape.Breaking changes
IMessageProviderServiceto the area interfaces. Code outside this repository that calls one of them must inject the matchingI<Area>MessageProviderService;SendNotificationstays where it was.MessageProviderServicethat overrides a send method or one of the protected helpers (GetStore,GetMessageTemplate,GetEmailAccountOfMessageTemplate,EnsureLanguageIsActive) must move that code to the new service or toMessageLookupService. TheMessageProviderServiceconstructor now takes onlyIQueuedEmailService.Testing
dotnet build GrandNode.slnx: no errors.dotnet testforGrand.Business.Messages.Tests(53, 4 new),Grand.Business.Checkout.Tests(304),Grand.Modules.Tests(397),Grand.Web.Tests(156),Grand.Web.Admin.Tests(1596),Grand.Web.Store.Tests(181),Grand.Web.Vendor.Tests(53) pass, the same counts as before. Only mock types and field names changed in existing tests; the new tests check that Order, Newsletter, MerchandiseReturn and Cms queue an email.