platform/packages/reflection/README.md

168 lines
4 KiB
Markdown
Raw Normal View History

2024-11-28 23:13:19 +00:00
# Dart Pure Reflection
A lightweight, cross-platform reflection system for Dart that provides runtime type introspection and manipulation without using `dart:mirrors` or code generation.
## Features
- ✅ Works on all platforms (Web, Mobile, Desktop)
- ✅ No dependency on `dart:mirrors`
- ✅ No code generation required
- ✅ Pure runtime reflection
- ✅ Type-safe property access
- ✅ Method invocation with argument validation
- ✅ Constructor invocation support
- ✅ Comprehensive error handling
## Installation
Add this to your package's `pubspec.yaml` file:
```yaml
dependencies:
reflection: ^1.0.0
```
## Usage
### Basic Setup
1. Add the `@reflectable` annotation and `Reflector` mixin to your class:
```dart
import 'package:reflection/reflection.dart';
@reflectable
class User with Reflector {
String name;
int age;
final String id;
User(this.name, this.age, {required this.id});
}
```
2. Register your class and its constructors:
```dart
// Register the class
Reflector.register(User);
// Register constructors
Reflector.registerConstructor(
User,
'', // Default constructor
(String name, int age, {String? id}) {
if (id == null) throw ArgumentError.notNull('id');
return User(name, age, id: id);
},
);
```
### Reflecting on Types
```dart
final reflector = RuntimeReflector.instance;
// Get type metadata
final userType = reflector.reflectType(User);
print('Type name: ${userType.name}');
print('Properties: ${userType.properties.keys.join(', ')}');
print('Methods: ${userType.methods.keys.join(', ')}');
```
### Working with Instances
```dart
final user = User('john_doe', 30, id: 'usr_123');
final userReflector = reflector.reflect(user);
// Read properties
final name = userReflector.getField('name'); // john_doe
final age = userReflector.getField('age'); // 30
// Write properties
userReflector.setField('name', 'jane_doe');
userReflector.setField('age', 25);
// Invoke methods
userReflector.invoke('someMethod', ['arg1', 'arg2']);
```
### Creating Instances
```dart
// Using default constructor
final newUser = reflector.createInstance(
User,
positionalArgs: ['alice', 28],
namedArgs: {'id': 'usr_456'},
) as User;
// Using named constructor
final specialUser = reflector.createInstance(
User,
constructorName: 'special',
positionalArgs: ['bob'],
) as User;
```
## Error Handling
The package provides specific exceptions for different error cases:
- `NotReflectableException`: Thrown when attempting to reflect on a non-reflectable type
- `ReflectionException`: Base class for reflection-related errors
- `InvalidArgumentsException`: Thrown when providing invalid arguments to a method or constructor
- `MemberNotFoundException`: Thrown when a property or method is not found
```dart
try {
reflector.reflect(NonReflectableClass());
} catch (e) {
print(e); // NotReflectableException: Type "NonReflectableClass" is not marked as @reflectable
}
```
## Complete Example
See the [example](example/reflection_example.dart) for a complete working demonstration.
## Limitations
1. Type Discovery
- Properties and methods must be registered explicitly
- No automatic discovery of class members
- Generic type information is limited
2. Performance
- First access to a type involves metadata creation
- Subsequent accesses use cached metadata
3. Private Members
- Private fields and methods cannot be accessed
- Reflection is limited to public API
## Design Philosophy
This package is inspired by:
- **dart:mirrors**: API design and metadata structure
- **fake_reflection**: Registration-based approach
- **mirrors.cc**: Runtime type handling
The goal is to provide a lightweight, cross-platform reflection system that:
- Works everywhere Dart runs
- Requires minimal setup
- Provides type-safe operations
- Maintains good performance
- Follows Dart best practices
## Contributing
Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting pull requests.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.