Skip to content

refactor: avoid tight coupling by using dependency injection - #13

Merged
alexgerardojacinto merged 3 commits into
feat/RMET-4099/camera-unificationfrom
feat/RMET-5076/refactor-bridge-android
Mar 23, 2026
Merged

refactor: avoid tight coupling by using dependency injection#13
alexgerardojacinto merged 3 commits into
feat/RMET-4099/camera-unificationfrom
feat/RMET-5076/refactor-bridge-android

Conversation

@alexgerardojacinto

@alexgerardojacinto alexgerardojacinto commented Mar 20, 2026

Copy link
Copy Markdown
Collaborator

Disclaimer: This PR was generated with Claude.

Problem

  • Cyclic dependency between CameraPlugin and flow classes (IonCameraFlow and LegacyCameraFlow)
  • Flows were receiving CameraPlugin instance via constructor and calling back to plugin methods
  • This created tight coupling: CameraPlugin → Flows → CameraPlugin
  • Made testing difficult and violated dependency inversion principle

Solution: Constructor Dependency Injection

  1. Created PermissionHelper class
  • Encapsulates permission-related operations without holding plugin reference
  • Uses lambda/function references instead of plugin instance
  • Accepts 4 function parameters: isPermissionDeclared, getPermissionState, requestPermissionForAlias, requestPermissionForAliases
  • Completely eliminates type dependency on CameraPlugin
  1. Refactored IonCameraFlow (Kotlin)
  • Changed constructor to accept explicit dependencies: Context, Activity, Bridge, appId, PermissionHelper
  • Replaced all plugin.* references with injected dependencies
  • No longer holds reference to CameraPlugin
  1. Refactored LegacyCameraFlow (Java)
  • Changed constructor to accept explicit dependencies: Context, AppCompatActivity, Bridge, appId, PermissionHelper, ActivityStarter
  • Created ActivityStarter functional interface for activity result launching (avoids naming conflict with AndroidX's ActivityResultLauncher)
  • Replaced all plugin.* references with injected dependencies
  • No longer holds reference to CameraPlugin
  1. Updated CameraPlugin
  • Modified load() method to instantiate flows with explicit dependencies
  • Creates PermissionHelper with lambda function references
  • Passes concrete dependencies (context, activity, bridge, appId) to flow constructors
  • Removed unnecessary wrapper methods (requestLegacyPermissionForAlias, requestLegacyPermissionForAliases)

Benefits

  • ✅ Eliminates cyclic dependency - flows only depend on interfaces/primitives, not plugin
  • ✅ Improves testability - flows can be unit tested with mock dependencies
  • ✅ Better separation of concerns - explicit, clear dependencies via constructor
  • ✅ Follows SOLID principles - dependency inversion, interface segregation
  • ✅ No behavioral changes - purely structural refactoring, maintains backward compatibility

Files Changed

  • New: PermissionHelper.kt - Permission operations wrapper
  • Modified: IonCameraFlow.kt - Constructor injection refactor
  • Modified: LegacyCameraFlow.java - Constructor injection refactor, added ActivityStarter interface
  • Modified: CameraPlugin.kt - Updated flow instantiation with dependencies

Comment on lines +46 to +50
private val context: Context,
private val activity: AppCompatActivity,
private val bridge: Bridge,
private val appId: String,
private val permissionHelper: PermissionHelper

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say this is much better.

I think one day we could look into not passing stuff like activity and context directly (and probably we'd only need activity, we could derive context from it), but don't think that needs to be addressed here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I also thought of that. We can probably do that in the future. For this one I specifically asked Claude to fix the tight coupling without changing the code too much and keeping the two separate classes (IonCameraFlow and LegacyCameraFlow (in Java)) without changing too much stuff, so I believe that's why it did it like this.

Comment thread android/src/main/java/com/capacitorjs/plugins/camera/PermissionHelper.kt Outdated
Comment thread android/src/main/java/com/capacitorjs/plugins/camera/CameraPlugin.kt Outdated
Comment thread android/src/main/java/com/capacitorjs/plugins/camera/CameraPlugin.kt Outdated
alexgerardojacinto and others added 2 commits March 23, 2026 08:35
Co-authored-by: Pedro Bilro <pedro.gustavo.bilro@outsystems.com>
@alexgerardojacinto
alexgerardojacinto merged commit 31ff8cd into feat/RMET-4099/camera-unification Mar 23, 2026
5 of 6 checks passed
@alexgerardojacinto
alexgerardojacinto deleted the feat/RMET-5076/refactor-bridge-android branch March 23, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants