Feature/advanced features#46
Merged
Merged
Conversation
- Add Scope enum with Singleton and Transient options - Add ScopeStorage for managing service scopes - Implement transient scope: new instance on each get() - Add ContainerConfig::withScope() method - Add buildTransient() method to Injector - Add 5 new tests for scope functionality - All tests passing (107 tests, 181 assertions) - Psalm: No errors, 99.88% type inference
**Bind Validation:** - Add InvalidBindingException for binding errors - Validate interface/abstract class existence - Validate implementation class exists and implements interface - Support abstract class bindings - Update DependencyMapper to handle abstract classes - Add 7 tests for bind validation **Callback Factories:** - Add FactoryStorage for factory management - Add factory() method to ContainerInterface - Factories have priority over autowiring - Factories create singletons by default - Container can resolve dependencies in factory callbacks - Add 6 tests for factory functionality Tests: 120 tests, 205 assertions Psalm: No errors (99.89% type coverage)
**Compile Method:** - Add compile() method to ContainerInterface - Validates all registered bindings without instantiation - Returns array of error messages (empty = all OK) - Detects missing dependencies and circular references - Helps find configuration errors before runtime - Add 5 tests for compile functionality Tests: 125 tests, 215 assertions Psalm: No errors (99.89% type coverage)
Added comprehensive documentation for new features: - Service Scopes (Singleton/Transient) - Callback Factories - Binding Validation - Compile-time Validation All sections include detailed examples and use cases.
For better clarity and consistency, explicitly declare has() method in ContainerInterface even though it's inherited from PSR-11. This makes the contract more explicit and improves IDE support.
Changed validation strategy to rely on ReflectionClass autoloading instead of manual interface_exists/class_exists checks. This fixes issues when binding classes from other packages that haven't been loaded yet. Changes: - Use ReflectionClass with try-catch for validation - Catch ReflectionException and wrap in InvalidBindingException - Remove premature existence checks - Update test expectations to match new error messages - Add Psalm type hints and suppressions This maintains validation quality while being compatible with Composer autoloading across multiple packages. Fixes: Fatal error when binding interfaces from external packages
BREAKING CHANGE: Binding validation no longer happens at bind() time Why this change? ================ The original implementation validated bindings immediately when bind() was called. This caused fatal errors when binding classes from external packages that haven't been autoloaded yet: Fatal error: InvalidBindingException: Invalid binding: "Duyler\Builder\Loader\ApplicationLoaderInterface" => "Duyler\Builder\ApplicationLoader". Class "Duyler\Builder\Loader\ApplicationLoaderInterface" does not exist The problem: ReflectionClass cannot validate classes that haven't been loaded by the autoloader. In multi-package projects, classes from external packages may not be loaded when bind() is called in the Container constructor. Solution: ========= Move validation to compile() method, which is explicitly designed for configuration validation. This makes validation: - Lazy: Only runs when compile() is explicitly called - Safe: Works with any class that can be autoloaded - Optional: Runtime code works without validation In production, dependencies are validated naturally when resolved. For pre-deployment checks, use compile() to validate all bindings. Changes: ======== 1. Remove validation from DependencyMapper::bind() 2. Add DependencyMapper::validateBindings() for lazy validation 3. Update Container::compile() to validate bindings first 4. Update tests to check validation via compile() not exceptions About @psalm-suppress: ====================== Used because Psalm cannot statically prove that strings from array<string, string> are valid class-string types. This is safe because validation catches all errors at runtime and returns them as error messages instead of throwing exceptions. Tests: 125 tests, 215 assertions - all passing
|
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.



No description provided.