Parse-SDK-dotNET icon indicating copy to clipboard operation
Parse-SDK-dotNET copied to clipboard

feat: Architectural Refactor of Dependency Injection and Query System

Open YBTopaz8 opened this issue 4 months ago β€’ 6 comments

PR Classification:

Major architectural improvement, new features, and increased test coverage.

PR Summary:

This is a major stability and quality-of-life release that overhauls the internal architecture of the SDK, making it more reliable and easier to use. It also lays the critical groundwork for future features like the Parse Local Datastore (LDS)!

BREAKING CHANGE ⚠️

If you have created a custom implementation of the IParseDataDecoder interface, its Decode method signature has changed. It no longer requires the IServiceHub parameter. Please update your implementation to match the new interface. This change was made to eliminate a common source of NullReferenceExceptions.

  • The IJsonConvertible.ConvertToJSON method now returns a strongly-typed IDictionary<string, object>.

New Features & Improvements

Easier Access to the Current User! You can now get the current user with a simple shortcut:

ParseUser currentUser = ParseClient.Instance.CurrentUser;
  • Added over 50 new unit tests covering the entire query pipeline, user management, and internal helper utilities. This means a more stable and reliable SDK for your production apps.

Foundation for Offline Storage (LDS): The SDK can now fully understand all server-side data operations (Increment, AddUnique, etc.). This is the first and most important step toward enabling full offline data caching and synchronization. Stay tuned!

Summary by CodeRabbit

  • New Features

    • Added support for combining multiple queries with a logical OR condition.
    • Introduced new unit tests for attribute handling, geo distance, query controllers, query building, internal extensions, Parse operations, and transient cache behavior.
  • Bug Fixes

    • Improved error handling for HTTP responses, including detailed handling for various status codes and error payloads.
    • Enhanced exception precision in tests and encoding logic.
  • Refactor

    • Streamlined and localized test setup and teardown across many test classes.
    • Centralized service access within data decoders and encoders.
    • Improved test isolation and coverage for ACL, user, and object state scenarios.
  • Chores

    • Upgraded test project dependencies for improved test reliability and coverage.
    • Removed obsolete or redundant test methods and formatting/comment cleanups.
  • Documentation

    • Improved test descriptions and added more comprehensive test coverage for edge cases and error conditions.
  • Style

    • Formatting and whitespace adjustments in test files for readability.

These updates enhance reliability, maintainability, and test coverage across the platform.

YBTopaz8 avatar Jul 26 '25 13:07 YBTopaz8

πŸš€ Thanks for opening this pull request!

πŸ“ Walkthrough

Walkthrough

This update introduces extensive changes to both the Parse SDK and its test suite. The core SDK refactors the data decoding pipeline, standardizes JSON conversion return types to IDictionary<string, object>, and enhances error handling for HTTP responses. The test suite receives new and refactored tests, improved isolation, and coverage for previously untested scenarios. Several internal APIs are updated to streamline dependencies and clarify method contracts.

Changes

File(s) / Group Change Summary
Parse.Tests/ACLTests.cs Expanded ACL unit tests: added scenarios for permissions, roles, error handling, and JSON conversion.
Parse.Tests/AnalyticsTests.cs, Parse.Tests/CloudControllerTests.cs, Parse.Tests/CloudTests.cs, Parse.Tests/ConfigTests.cs, Parse.Tests/GeoPointTests.cs, Parse.Tests/ObjectControllerTests.cs, Parse.Tests/ObjectTests.cs, Parse.Tests/ProgressTests.cs Refactored test setup/teardown, improved isolation, updated or removed shared fields, and adjusted decoder calls.
Parse.Tests/AttributeTests.cs, Parse.Tests/GeoDistanceTest.cs, Parse.Tests/InternalExtensionsTests.cs, Parse.Tests/ParseOperationsTests.cs, Parse.Tests/ParseQueryControllerTests.cs, Parse.Tests/ParseQueryTests.cs, Parse.Tests/TransientCacheControllerTests.cs Added new test classes covering attributes, geo distance, internal extensions, Parse operations, query controller, query building, and transient cache.
Parse.Tests/DecoderTests.cs, Parse.Tests/EncoderTests.cs, Parse.Tests/ObjectCoderTests.cs, Parse.Tests/ObjectStateTests.cs, Parse.Tests/UserTests.cs Added or expanded tests for decoding, encoding, object controller, object state, and user behaviors; improved coverage and edge case validation.
Parse.Tests/RelationTests.cs Removed all but one test; deleted user relation management helpers and tests.
Parse.Tests/Parse.Tests.csproj Updated test dependencies: added coverlet.collector, upgraded MSTest and Microsoft.NET.Test.Sdk.
Parse/Abstractions/Infrastructure/CustomServiceHub.cs, Parse/Abstractions/Platform/Users/IParseCurrentUserController.cs Added CurrentUser property to service hub and user controller interfaces.
Parse/Abstractions/Infrastructure/Data/IParseDataDecoder.cs, Parse/Infrastructure/Data/ParseDataDecoder.cs, Parse/Infrastructure/LateInitializedMutableServiceHub.cs, Parse/Infrastructure/MutableServiceHub.cs, Parse/Infrastructure/ServiceHub.cs, Parse/Platform/Cloud/ParseCloudCodeController.cs, Parse/Platform/Configuration/ParseConfiguration.cs Refactored decoder pipeline: removed serviceHub parameter from Decode, injected service hub, updated decoder initialization and usage.
Parse/Abstractions/Infrastructure/IJsonConvertible.cs, Parse/Infrastructure/Control/ParseAddOperation.cs, Parse/Infrastructure/Control/ParseAddUniqueOperation.cs, Parse/Infrastructure/Control/ParseDeleteOperation.cs, Parse/Infrastructure/Control/ParseIncrementOperation.cs, Parse/Infrastructure/Control/ParseRelationOperation.cs, Parse/Infrastructure/Control/ParseRemoveOperation.cs, Parse/Infrastructure/Control/ParseSetOperation.cs, Parse/Platform/Configuration/ParseConfiguration.cs, Parse/Platform/Files/ParseFile.cs, Parse/Platform/Location/ParseGeoPoint.cs, Parse/Platform/Relations/ParseRelation.cs, Parse/Platform/Security/ParseACL.cs Standardized ConvertToJSON return type to IDictionary<string, object> across all relevant entities.
Parse/Infrastructure/Control/ParseFieldOperations.cs Implemented Decode method for field operations; added static comparer property.
Parse/Infrastructure/Data/ParseDataEncoder.cs Refactored dictionary encoding logic, consolidated methods, improved handling of nested and primitive types.
Parse/Infrastructure/Data/ParseObjectCoder.cs Simplified decoder calls, minor refactorings for clarity.
Parse/Infrastructure/Execution/ParseCommandRunner.cs Enhanced HTTP response handling: added explicit error code mapping, improved error payload extraction, and comprehensive status code processing.
Parse/Infrastructure/ParseFailureException.cs Added BadRequest error code and ParseErrorPayload class for error details.
Parse/Platform/ParseClient.cs Ensured recursive decoder initialization for all service hubs during client construction.
Parse/Platform/Queries/ParseQuery.cs Added static Or method for query composition and implemented GetHashCode.
Parse/Platform/Users/ParseUser.cs Removed obsolete commented code.
Parse/Utilities/ParseQueryExtensions.cs Removed commented-out code in query normalization logic.

Sequence Diagram(s)

sequenceDiagram
    participant Client as ParseClient
    participant Hub as ServiceHub/MutableServiceHub
    participant Decoder as ParseDataDecoder
    participant Controller as ParseCloudCodeController
    participant Runner as ParseCommandRunner
    participant Server as HTTP Server

    Client->>Hub: Initialize services
    Client->>Decoder: Ensure Decoder is set for each hub
    Controller->>Runner: Prepare and send command
    Runner->>Server: HTTP request
    Server-->>Runner: HTTP response (status, content)
    Runner->>Runner: Handle status codes (200, 400, 401, 403, 404, 410, 5xx)
    alt Success (200/201)
        Runner->>Decoder: Decode response data
        Decoder->>Hub: Access ClassController as needed
        Decoder-->>Controller: Return decoded result
        Controller-->>Client: Return result
    else Error (400/401/403/404/410/5xx)
        Runner-->>Controller: Throw ParseFailureException (with error code/message)
        Controller-->>Client: Propagate exception
    end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40–60 minutes

Complexity:

  • Broad refactoring of the decoding/encoding pipeline and error handling.
  • Standardization of JSON serialization interfaces.
  • Numerous new and updated unit tests, including new classes and expanded coverage.
  • Significant changes to test isolation, dependency injection, and error scenarios.
  • Some breaking changes to method signatures and interface contracts.
  • High-impact changes to core SDK control and data flow.

Estimated review time:
Reviewers should expect to spend significant time verifying interface changes, test coverage, error handling logic, and the consistency of SDK and test suite updates.

[!NOTE]

⚑️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


πŸ“œ Recent review details

Configuration used: CodeRabbit UI Review profile: CHILL Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 10234303da20a8e044cb08f2b8a66e7bd723dd0b and b342554c3d2dee3fca96a1c5350599b23b86055f.

πŸ“’ Files selected for processing (2)
  • Parse/Infrastructure/Execution/ParseCommandRunner.cs (2 hunks)
  • Parse/Infrastructure/ParseFailureException.cs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Parse/Infrastructure/ParseFailureException.cs
  • Parse/Infrastructure/Execution/ParseCommandRunner.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: .NET 9.0
  • GitHub Check: .NET 8.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share
πŸͺ§ Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar Jul 26 '25 13:07 coderabbitai[bot]

Codecov Report

:x: Patch coverage is 47.66839% with 101 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 54.53%. Comparing base (2e81163) to head (1023430). :warning: Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...rse/Infrastructure/Control/ParseFieldOperations.cs 28.20% 23 Missing and 5 partials :warning:
...rse/Infrastructure/Execution/ParseCommandRunner.cs 20.00% 19 Missing and 5 partials :warning:
Parse/Platform/Queries/ParseQuery.cs 0.00% 22 Missing :warning:
Parse/Infrastructure/Data/ParseDataEncoder.cs 26.31% 13 Missing and 1 partial :warning:
Parse/Infrastructure/Control/ParseSetOperation.cs 0.00% 8 Missing :warning:
Parse/Infrastructure/ParseFailureException.cs 0.00% 2 Missing :warning:
...se/Abstractions/Infrastructure/CustomServiceHub.cs 0.00% 1 Missing :warning:
...Infrastructure/LateInitializedMutableServiceHub.cs 0.00% 1 Missing :warning:
Parse/Infrastructure/MutableServiceHub.cs 0.00% 0 Missing and 1 partial :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #412      +/-   ##
==========================================
+ Coverage   48.20%   54.53%   +6.33%     
==========================================
  Files         106      106              
  Lines        6199     6273      +74     
  Branches      950      981      +31     
==========================================
+ Hits         2988     3421     +433     
+ Misses       2907     2523     -384     
- Partials      304      329      +25     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Jul 26 '25 13:07 codecov[bot]

@YBTopaz8 First of all, thanks for your efforts with this PR. If you remember the discussion from the last redesign, it was incredibly complex to review because many changes were packed into a single PR. Is there a way to break this down into smaller, discrete PRs, also to minimize the risk of bugs? We also try to avoid breaking changes as much as possible.

mtrezza avatar Jul 26 '25 13:07 mtrezza

Thank you for the feedback.

I need to be clear that this changeset is a single, atomic architectural upgrade. The core of this work is a critical bug fix to the DI system, and all subsequent features and tests are built directly upon that new, stable foundation. As such, these changes cannot be broken up into smaller, preceding PRs unless one has time for that β€”the dependency is foundational.

This refactor is not a redesign for its own sake; it's a necessary stabilization of the previous architecture that simplifies the developer experience and eliminates a class of runtime bugs, as detailed in the PR description.

I understand your team's process, but it's also difficult to provide the necessary documentation and context when my foundational README PR from last March still hasn't been reviewed. A comprehensive review of this PR would depend on that context.

This contribution is offered as a complete, necessary solution. Please let me know if you are able to review and accept this foundational contribution as a whole. I do not mind answering any questions at all. If not, I will close the PR and focus my efforts on other projects. Thank you.

YBTopaz8 avatar Jul 26 '25 14:07 YBTopaz8

@YBTopaz8 #410 seems to be just a few lines in the README. If a PR falls through the cracks please comment as reminder. I posted a comment there.

Major architectural improvement, new features

Could you break this down briefly - what are the improvements and new features? We'd need a list of all breaking changes for the changelog entry.

mtrezza avatar Jul 26 '25 23:07 mtrezza