-
Notifications
You must be signed in to change notification settings - Fork 13
redesign binding api with generics #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
kgrigorev
wants to merge
4
commits into
i-love-flamingo:master
from
kgrigorev:claude/redesign-binding-api-generics-017S6YMM1v9BDn7Efs4zqhmq
Closed
redesign binding api with generics #80
kgrigorev
wants to merge
4
commits into
i-love-flamingo:master
from
kgrigorev:claude/redesign-binding-api-generics-017S6YMM1v9BDn7Efs4zqhmq
Conversation
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
Introduce a new comprehensive generic binding API that provides type safety,
ergonomic usage, and fail-fast validation while maintaining full compatibility
with the existing reflection-based API.
Key Features:
- Type-safe bindings using Go generics (type parameters)
- Fail-fast validation at binding time (not resolution time)
- Clean, idiomatic Go API design
- Returns *Binding for compatibility and method chaining
- Full feature parity with existing API
New Files:
- binding_generic.go: Core generic binding functions
* Bind[T]() - Type-safe binding creation
* BindTo[F, T]() - Explicit type relationship with validation
* BindInstance[T]() - Instance binding with type safety
* BindProvider[T]() - Provider binding with type safety
* BindProviderFunc[T]() - Provider with dependency injection
- multi_binding_generic.go: Generic multi-binding functions
* BindMulti[T]() - Type-safe multi-binding
* BindMultiTo[F, T]() - Explicit multi-binding type relationship
* BindMultiInstance[T]() - Multi-binding instance
* BindMultiProvider[T]() - Multi-binding provider
- map_binding_generic.go: Generic map-binding functions
* BindMap[T]() - Type-safe map-binding
* BindMapTo[F, T]() - Explicit map-binding type relationship
* BindMapInstance[T]() - Map-binding instance
* BindMapProvider[T]() - Map-binding provider
- injector_generic.go: Generic injector helper functions
* GetInstance[T]() - Type-safe instance retrieval
* GetAnnotatedInstance[T]() - Type-safe annotated instance retrieval
* RequestInjection[T]() - Type-safe injection request
* Override[T]() - Type-safe override
* BindInterceptor[T]() - Type-safe interceptor binding
* GetMultiInstance[T]() - Convenience for multi-bindings
* GetMapInstance[T]() - Convenience for map-bindings
- example_generic_api.go: Comprehensive examples and API comparison
Benefits:
- Compile-time type checking where possible
- No type assertions needed when retrieving instances
- All validation happens at binding time (fail-fast)
- Clean and intuitive API surface
- Fully compatible with existing code
- Can mix old and new API freely
Migration Path:
The new API is fully interchangeable with the existing API:
- Old: injector.Bind((*Logger)(nil)).To(ConsoleLogger{})
- New: Bind[Logger](injector).To(&ConsoleLogger{})
Both APIs work with the same underlying *Binding type and *Injector.
Refactor the generic binding API to eliminate chaining and use the idiomatic
Go functional options pattern. This makes the API cleaner, more concise, and
easier to use.
Major Changes:
1. **Functional Options Pattern**
- Introduce BindingOption type and option functions
- WithAnnotation(string) - set annotation
- WithScope(Scope) - set custom scope
- AsSingleton() - convenience for singleton scope
- AsChildSingleton() - convenience for child singleton scope
- AsEagerSingleton() - mark as eager singleton
- Options are composable and extensible
2. **Combined Bind+To in Single Function**
- Old: Bind[Logger](injector).To(&ConsoleLogger{})
- New: Bind[Logger, *ConsoleLogger](injector)
- Both "from" and "to" types specified in type parameters
- No more chaining needed for basic bindings
- Type validation happens at binding time (fail-fast)
3. **Simplified Function Signatures**
All binding functions now follow this pattern:
- Bind[F, T](injector, ...BindingOption) *Binding
- BindMulti[F, T](injector, ...BindingOption) *Binding
- BindMap[F, T](injector, key, ...BindingOption) *Binding
- BindInstance[T](injector, instance, ...BindingOption) *Binding
- BindProvider[T](injector, provider, ...BindingOption) *Binding
4. **Updated Override Functions**
- Override[F, T](injector, annotation, ...BindingOption) *Binding
- OverrideInstance[T](injector, annotation, instance, ...BindingOption) *Binding
- Follows same pattern as main binding functions
Benefits:
- More concise: Bind[Logger, *ConsoleLogger](injector, AsSingleton())
- No chaining: All configuration in single function call
- Idiomatic Go: Follows established functional options pattern
- Extensible: Easy to add new options without breaking API
- Clean: Clear separation between required and optional parameters
- Type-safe: Full compile-time type checking where possible
Example Comparisons:
// Before:
Bind[Logger](injector).To(&ConsoleLogger{}).AnnotatedWith("console").In(Singleton)
// After:
Bind[Logger, *ConsoleLogger](injector, WithAnnotation("console"), AsSingleton())
// Before:
BindMulti[Plugin](injector).To(&PluginA{}).AnnotatedWith("prod").In(Singleton)
// After:
BindMulti[Plugin, *PluginA](injector, WithAnnotation("prod"), AsSingleton())
The new API is cleaner, more Go-idiomatic, and easier to read and maintain.
Consolidate all generic binding API implementation into a single well-organized file for better maintainability and discoverability. Changes: - Merge binding_generic.go, multi_binding_generic.go, map_binding_generic.go, and injector_generic.go into generics.go - Rename example_generic_api.go to generics_example.go for consistency - Organize generics.go with clear section comments: * Functional Options * Core Binding Functions * Multi-Binding Functions * Map-Binding Functions * Injector Helper Functions Benefits: - Single source of truth for generic API - Easier to navigate and maintain - Clear file naming convention (generics.go, generics_example.go) - Better organization with section markers - Reduced file clutter File structure: - generics.go (~1340 lines) - Complete generic API implementation - generics_example.go (~470 lines) - 15 comprehensive examples
Added comprehensive type safety enhancements to the generic binding API:
Type-Safe Provider Functions:
- Added Provider0-5 and ProviderWithError0-5 type aliases
- Added BindProvider1-5 and BindProviderWithError1-5 functions
- These provide compile-time type safety for provider dependencies
- Eliminates need for interface{} in provider function signatures
Interface Verification:
- Added Implements[I, T]() for runtime interface verification
- Added MustImplement[I, T]() for defensive programming patterns
- Both provide clear panic messages on type mismatches
Comprehensive Examples:
- Added 6 new examples (16-21) demonstrating type safety features
- Examples show compile-time vs runtime verification
- Demonstrate type-safe providers with 1-5 dependencies
- Include comparison showing benefits over BindProviderFunc
- Show advanced patterns with complex dependency graphs
All code compiles and maintains full backward compatibility.
19b8cde to
f70f181
Compare
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.