refactor: extract JsonFilePersistence<T> to eliminate duplicated JSON persistence logic#160
Open
Copilot wants to merge 2 commits into
Open
refactor: extract JsonFilePersistence<T> to eliminate duplicated JSON persistence logic#160Copilot wants to merge 2 commits into
Copilot wants to merge 2 commits into
Conversation
…persistence code Co-authored-by: sunzhuoshi <592211+sunzhuoshi@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Refactor duplicate JSON file persistence in history classes
refactor: extract JsonFilePersistence<T> to eliminate duplicated JSON persistence logic
Mar 20, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR removes duplicated JSON file persistence code from NotificationHistory and ReviewRequestHistory by extracting it into a shared generic helper, keeping the history classes focused on in-memory state management.
Changes:
- Added
JsonFilePersistence<T>to encapsulate JSON load/save, file I/O locking, and consistent error logging. - Refactored
NotificationHistoryto delegate persistence toJsonFilePersistence<List<NotificationEntry>>. - Refactored
ReviewRequestHistoryto delegate persistence toJsonFilePersistence<List<string>>, keeping HashSet↔List conversion at the call sites.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/JsonFilePersistence.cs | Introduces shared generic JSON file load/save utility with internal locking and unified logging. |
| src/NotificationHistory.cs | Replaces bespoke JSON persistence with JsonFilePersistence<List<NotificationEntry>>. |
| src/ReviewRequestHistory.cs | Replaces bespoke JSON persistence with JsonFilePersistence<List<string>> and retains HashSet semantics in-memory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
NotificationHistoryandReviewRequestHistoryeach independently implemented ~22 lines of identical JSON file persistence logic (lock,Load(),Save(), error handling) with minor inconsistencies in error message formatting.Changes
src/JsonFilePersistence.cs— generic utility class encapsulating all file persistence concerns:_lockObjectguarding bothLoad()andSave()for thread-safe file I/ONotificationHistory— delegates toJsonFilePersistence<List<NotificationEntry>>; removes privateLoad()and inlineSave()bodyReviewRequestHistory— delegates toJsonFilePersistence<List<string>>; removes privateLoad()and inlineSave()body; HashSet↔List conversion kept at the call sitesThe history classes retain their own
_lockObjectto protect in-memory state during concurrent reads/writes — this is distinct from the_persistence-internal lock that guards file I/O.Original prompt
This section details on the original issue you should resolve
<issue_title>Duplicate Code: JSON File-Based Persistence Pattern in History Classes</issue_title>
<issue_description>Analysis of commit ebf44dd
Assignee:
@copilotSummary
NotificationHistoryandReviewRequestHistoryindependently implement nearly identical JSON file-based persistence logic — including lock objects,Load(), andSave()methods with the same structure. This is a classic copy-paste duplication that violates DRY and will lead to divergence and inconsistent bug fixes.Duplication Details
Pattern: JSON File Persistence (Load/Save with lock + error logging)
src/NotificationHistory.cs(lines 10, 18–50)src/ReviewRequestHistory.cs(lines 8, 15–49)Code Sample — NotificationHistory.cs (lines 10, 18–50):
Code Sample — ReviewRequestHistory.cs (lines 8, 15–49):
Impact Analysis
LogErrorcall differs between the two). Future bugs may be fixed in one class but not the other.Refactoring Recommendations
Extract a generic
JsonFilePersistence(T)utility classsrc/JsonFilePersistence.csLoad(T)()andSave(T)()logic with the file path, lock, and error handlingAlternative: Abstract base class
JsonFileHistory(TEntry, TCollection)NotificationHistoryandReviewRequestHistoryinherit from itLoad(),Save(),_lockObjectImplementation Checklist
NotificationHistoryto use the shared abstractionReviewRequestHistoryto use the shared abstractionAnalysis Metadata
.csfiles📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.