update: updating example
This commit is contained in:
parent
3cb8feb43e
commit
5c762c27e4
1 changed files with 241 additions and 41 deletions
|
@ -1,35 +1,136 @@
|
||||||
import 'package:platform_reflection/reflection.dart';
|
import 'package:platform_reflection/reflection.dart';
|
||||||
|
|
||||||
|
// Custom annotation to demonstrate metadata
|
||||||
|
class Validate {
|
||||||
|
final String pattern;
|
||||||
|
const Validate(this.pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface to demonstrate reflection with interfaces
|
||||||
@reflectable
|
@reflectable
|
||||||
class Person {
|
abstract class Identifiable {
|
||||||
|
String get id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base class to demonstrate inheritance
|
||||||
|
@reflectable
|
||||||
|
abstract class Entity implements Identifiable {
|
||||||
|
final String _id;
|
||||||
|
|
||||||
|
Entity(this._id);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id => _id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'Entity($_id)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic class to demonstrate type parameters
|
||||||
|
@reflectable
|
||||||
|
class Container<T> {
|
||||||
|
final T value;
|
||||||
|
|
||||||
|
Container(this.value);
|
||||||
|
|
||||||
|
T getValue() => value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@reflectable
|
||||||
|
class User extends Entity {
|
||||||
|
@Validate(r'^[a-zA-Z\s]+$')
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
int age;
|
int age;
|
||||||
|
|
||||||
Person(this.name, this.age);
|
final List<String> tags;
|
||||||
|
|
||||||
Person.guest()
|
User(String id, this.name, this.age, [this.tags = const []]) : super(id) {
|
||||||
: name = 'Guest',
|
_userCount++;
|
||||||
age = 0;
|
}
|
||||||
|
|
||||||
|
User.guest() : this('guest', 'Guest User', 0);
|
||||||
|
|
||||||
|
static int _userCount = 0;
|
||||||
|
static int get userCount => _userCount;
|
||||||
|
|
||||||
String greet([String greeting = 'Hello']) {
|
String greet([String greeting = 'Hello']) {
|
||||||
return '$greeting $name!';
|
return '$greeting $name!';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addTag(String tag) {
|
||||||
|
if (!tags.contains(tag)) {
|
||||||
|
tags.add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName() => name;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$name ($age)';
|
String toString() =>
|
||||||
|
'User($id, $name, age: $age)${tags.isNotEmpty ? " [${tags.join(", ")}]" : ""}';
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() async {
|
||||||
// Register Person class for reflection
|
// Register classes for reflection
|
||||||
Reflector.register(Person);
|
Reflector.register(Identifiable);
|
||||||
|
Reflector.register(Entity);
|
||||||
|
Reflector.register(User);
|
||||||
|
Reflector.register(Container);
|
||||||
|
|
||||||
// Register properties
|
// Register Container<int> specifically for reflection
|
||||||
Reflector.registerProperty(Person, 'name', String);
|
final container = Container<int>(42);
|
||||||
Reflector.registerProperty(Person, 'age', int);
|
Reflector.register(container.runtimeType);
|
||||||
|
|
||||||
// Register methods
|
// Register property metadata directly
|
||||||
|
Reflector.registerPropertyMetadata(
|
||||||
|
User,
|
||||||
|
'name',
|
||||||
|
PropertyMetadata(
|
||||||
|
name: 'name',
|
||||||
|
type: String,
|
||||||
|
isReadable: true,
|
||||||
|
isWritable: true,
|
||||||
|
attributes: [Validate(r'^[a-zA-Z\s]+$')],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Reflector.registerPropertyMetadata(
|
||||||
|
User,
|
||||||
|
'age',
|
||||||
|
PropertyMetadata(
|
||||||
|
name: 'age',
|
||||||
|
type: int,
|
||||||
|
isReadable: true,
|
||||||
|
isWritable: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Reflector.registerPropertyMetadata(
|
||||||
|
User,
|
||||||
|
'tags',
|
||||||
|
PropertyMetadata(
|
||||||
|
name: 'tags',
|
||||||
|
type: List,
|
||||||
|
isReadable: true,
|
||||||
|
isWritable: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Reflector.registerPropertyMetadata(
|
||||||
|
User,
|
||||||
|
'id',
|
||||||
|
PropertyMetadata(
|
||||||
|
name: 'id',
|
||||||
|
type: String,
|
||||||
|
isReadable: true,
|
||||||
|
isWritable: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register User methods
|
||||||
Reflector.registerMethod(
|
Reflector.registerMethod(
|
||||||
Person,
|
User,
|
||||||
'greet',
|
'greet',
|
||||||
[String],
|
[String],
|
||||||
false,
|
false,
|
||||||
|
@ -37,48 +138,147 @@ void main() {
|
||||||
isRequired: [false],
|
isRequired: [false],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register constructors
|
Reflector.registerMethod(
|
||||||
|
User,
|
||||||
|
'addTag',
|
||||||
|
[String],
|
||||||
|
true,
|
||||||
|
parameterNames: ['tag'],
|
||||||
|
isRequired: [true],
|
||||||
|
);
|
||||||
|
|
||||||
|
Reflector.registerMethod(
|
||||||
|
User,
|
||||||
|
'getName',
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register constructors with creators
|
||||||
Reflector.registerConstructor(
|
Reflector.registerConstructor(
|
||||||
Person,
|
User,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, int],
|
parameterTypes: [String, String, int, List],
|
||||||
parameterNames: ['name', 'age'],
|
parameterNames: ['id', 'name', 'age', 'tags'],
|
||||||
|
isRequired: [true, true, true, false],
|
||||||
|
creator: (id, name, age, [tags]) => User(
|
||||||
|
id as String,
|
||||||
|
name as String,
|
||||||
|
age as int,
|
||||||
|
tags as List<String>? ?? const [],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerConstructor(
|
Reflector.registerConstructor(
|
||||||
Person,
|
User,
|
||||||
'guest',
|
'guest',
|
||||||
|
creator: () => User.guest(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create reflector instance
|
// Create reflector instance
|
||||||
final reflector = RuntimeReflector.instance;
|
final reflector = RuntimeReflector.instance;
|
||||||
|
|
||||||
// Create Person instance using reflection
|
// Demonstrate generic type reflection
|
||||||
final person = reflector.createInstance(
|
print('Container value: ${container.getValue()}');
|
||||||
Person,
|
|
||||||
positionalArgs: ['John', 30],
|
|
||||||
) as Person;
|
|
||||||
|
|
||||||
print(person); // John (30)
|
try {
|
||||||
|
// Create User instance using reflection
|
||||||
|
final user = reflector.createInstance(
|
||||||
|
User,
|
||||||
|
positionalArgs: [
|
||||||
|
'user1',
|
||||||
|
'John Doe',
|
||||||
|
30,
|
||||||
|
['admin', 'user']
|
||||||
|
],
|
||||||
|
) as User;
|
||||||
|
|
||||||
// Create guest instance using reflection
|
print('\nCreated user: $user');
|
||||||
final guest = reflector.createInstance(
|
|
||||||
Person,
|
|
||||||
constructorName: 'guest',
|
|
||||||
) as Person;
|
|
||||||
|
|
||||||
print(guest); // Guest (0)
|
// Create guest user using named constructor
|
||||||
|
final guest = reflector.createInstance(
|
||||||
|
User,
|
||||||
|
constructorName: 'guest',
|
||||||
|
) as User;
|
||||||
|
|
||||||
// Get property values
|
print('Created guest: $guest');
|
||||||
final mirror = reflector.reflect(person);
|
|
||||||
print(mirror.getField(const Symbol('name')).reflectee); // John
|
|
||||||
print(mirror.getField(const Symbol('age')).reflectee); // 30
|
|
||||||
|
|
||||||
// Set property values
|
// Demonstrate property reflection
|
||||||
mirror.setField(const Symbol('name'), 'Jane');
|
final userMirror = reflector.reflect(user);
|
||||||
print(person.name); // Jane
|
|
||||||
|
|
||||||
// Invoke methods
|
// Get property values
|
||||||
final greeting = mirror.invoke(const Symbol('greet'), ['Hi']).reflectee;
|
print('\nProperty values:');
|
||||||
print(greeting); // Hi Jane!
|
print('ID: ${userMirror.getField(const Symbol('id')).reflectee}');
|
||||||
|
print('Name: ${userMirror.getField(const Symbol('name')).reflectee}');
|
||||||
|
print('Age: ${userMirror.getField(const Symbol('age')).reflectee}');
|
||||||
|
print('Tags: ${userMirror.getField(const Symbol('tags')).reflectee}');
|
||||||
|
|
||||||
|
// Try to modify properties
|
||||||
|
userMirror.setField(const Symbol('name'), 'Jane Doe');
|
||||||
|
userMirror.setField(const Symbol('age'), 25);
|
||||||
|
print('\nAfter property changes: $user');
|
||||||
|
|
||||||
|
// Try to modify read-only property (should throw)
|
||||||
|
try {
|
||||||
|
userMirror.setField(const Symbol('id'), 'new_id');
|
||||||
|
print('ERROR: Should not be able to modify read-only property');
|
||||||
|
} catch (e) {
|
||||||
|
print('\nExpected error when modifying read-only property id: $e');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke methods
|
||||||
|
final greeting = userMirror.invoke(const Symbol('greet'), ['Hi']).reflectee;
|
||||||
|
print('\nGreeting: $greeting');
|
||||||
|
|
||||||
|
userMirror.invoke(const Symbol('addTag'), ['vip']);
|
||||||
|
print('After adding tag: $user');
|
||||||
|
|
||||||
|
final name = userMirror.invoke(const Symbol('getName'), []).reflectee;
|
||||||
|
print('Got name: $name');
|
||||||
|
|
||||||
|
// Demonstrate type metadata and relationships
|
||||||
|
final userType = reflector.reflectType(User);
|
||||||
|
print('\nType information:');
|
||||||
|
print('Type name: ${userType.name}');
|
||||||
|
|
||||||
|
// Show available properties
|
||||||
|
final properties = (userType as dynamic).properties;
|
||||||
|
print('\nDeclared properties:');
|
||||||
|
properties.forEach((name, metadata) {
|
||||||
|
print(
|
||||||
|
'- $name: ${metadata.type}${metadata.isWritable ? "" : " (read-only)"}');
|
||||||
|
if (metadata.attributes.isNotEmpty) {
|
||||||
|
metadata.attributes.forEach((attr) {
|
||||||
|
if (attr is Validate) {
|
||||||
|
print(' @Validate(${attr.pattern})');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show available methods
|
||||||
|
final methods = (userType as dynamic).methods;
|
||||||
|
print('\nDeclared methods:');
|
||||||
|
methods.forEach((name, metadata) {
|
||||||
|
print('- $name');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show constructors
|
||||||
|
final constructors = (userType as dynamic).constructors;
|
||||||
|
print('\nDeclared constructors:');
|
||||||
|
constructors.forEach((metadata) {
|
||||||
|
print('- ${metadata.name}');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Demonstrate type relationships
|
||||||
|
final identifiableType = reflector.reflectType(Identifiable);
|
||||||
|
print('\nType relationships:');
|
||||||
|
print(
|
||||||
|
'User is assignable to Identifiable: ${userType.isAssignableTo(identifiableType)}');
|
||||||
|
print(
|
||||||
|
'User is subtype of Entity: ${userType.isSubtypeOf(reflector.reflectType(Entity))}');
|
||||||
|
} catch (e) {
|
||||||
|
print('Error: $e');
|
||||||
|
print(e.runtimeType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue