reflection_factory

Creator: coderz1093

Last updated:

Add to Cart

Description:

reflection factory

reflection_factory #










reflection_factory allows Dart reflection with an easy approach, even for third-party classes,
using code generation portable for all Dart platforms.
Usage #
To enable/generate reflection for some class/type,
you can use two approaches:


@EnableReflection():
Annotation that indicates that a specific class/type will have reflection.


@ReflectionBridge([User, Profile]):
Annotation that indicates through a bridge class
that the types (User and Profile) will have reflection.


@EnableReflection #
The annotations @EnableReflection is used above your class/type
that you want to have reflection enabled.
File: some_source_file.dart:
import 'package:reflection_factory/reflection_factory.dart';

// Add a reference to the code generated by:
// $> dart run build_runner build
part 'some_source_file.reflection.g.dart';

// Indicates that reflection for class `User` will be generated/enabled:
@EnableReflection()
class User {
String? email;

String pass;

User(this.email, this.pass);

User.empty() : this(null,'') ;

bool get hasEmail => email != null;

bool checkPassword(String pass) {
return this.pass == pass;
}
}

void main() {
var user = User('joe@mail.com', '123');

// The generated reflection:
var userReflection = user.reflection;

var fieldEmail = userReflection.field('email')!;
print('email: ${fieldEmail.get()}');

var methodCheckPassword = userReflection.method('checkPassword')!;

var passOk1 = methodCheckPassword.invoke(['wrong']); // false
print('pass("wrong"): $passOk1');

var passOk2 = methodCheckPassword.invoke(['123']); // true
print('pass("123"): $passOk2');

// Using the generated `toJson` extension method:
print('User JSON:');
print(user.toJson());

// Using the generated `toJsonEncoded` extension method:
print('User JSON encoded:');
print(user.toJsonEncoded());

// Accessing reflection through class:
var userReflection2 = User$reflection();

// Creating an `User` instance from default or empty constructor:
var user2 = userReflection2.createInstance()!;

user2.email = 'smith@mail.com';
user2.pass = 'abc';

print('User 2 JSON:');
print(user2.toJson());

}

copied to clipboard
OUTPUT:
email: joe@mail.com
pass("wrong"): false
pass("123"): true
User JSON:
{email: joe@mail.com, hasEmail: true, pass: 123}
User JSON encoded:
{"email":"joe@mail.com","hasEmail":true,"pass":"123"}
User 2 JSON:
{email: smith@mail.com, hasEmail: true, pass: abc}
copied to clipboard
@ReflectionBridge #
The annotations @ReflectionBridge is used above a bridge class,
and indicates that third-party types will have reflection generated.
File: some_source_file.dart:

import 'package:reflection_factory/reflection_factory.dart';

// Class `User` is from a third-party package:
import 'package:some_api/user.dart';

// Add a reference to the code generated by:
// $> dart run build_runner build
part 'some_source_file.reflection.g.dart';

// Indicates that reflection for class `User` will be generated/enabled
// through a bridge class:
@ReflectionBridge([User])
class UserReflectionBridge {}

void main() {
var user = User('joe@mail.com', '123');

// The generated reflection through bridge class:
var userReflection = UserReflectionBridge().reflection(user);

var fieldEmail = userReflection.field('email')!;
print('email: ${fieldEmail.get()}');

print('User JSON encoded:');
print(user.toJsonEncoded());
}

copied to clipboard
OUTPUT:
email: joe@mail.com
User JSON encoded:
{"email":"joe@mail.com","pass":"123","hasEmail":true}
copied to clipboard
@ClassProxy #
Here's an example to create a class proxy that can intercept calls to its methods:
proxies.dart:
import 'package:reflection_factory/reflection_factory.dart';
import 'package:mime/mime.dart';

part 'proxies.reflection.g.dart';

@ClassProxy('MimeTypeResolver')
class MimeTypeResolverProxy implements ClassProxyListener {

@override
Object? onCall(instance, String methodName, Map<String, dynamic> parameters,
TypeReflection? returnType) {
var call = '$instance -> $methodName( $parameters ) -> $returnType';
calls.add(call);
print('CALL>> $call');
return call;
}

}
copied to clipboard
One common use case is to have a proxy to a class without need to import its package in
the code, having only the class structure methods in the proxy:
proxies_detached.dart:
import 'package:reflection_factory/reflection_factory.dart';

part 'proxies_detached.reflection.g.dart';

@ClassProxy('MimeTypeResolver', libraryPath: 'package:mime/mime.dart')
class MimeTypeResolverProxy implements ClassProxyListener {

@override
Object? onCall(instance, String methodName, Map<String, dynamic> parameters,
TypeReflection? returnType) {
var call = '$instance -> $methodName( $parameters ) -> $returnType';
calls.add(call);
print('CALL>> $call');
return call;
}

}
copied to clipboard
Using the proxy:
import 'proxies_detached.dart';

void main() {
var proxy = MimeTypeResolverProxy();

var proxyResult = proxy.lookup('path/foo'); // `onCall` returned value.
}
copied to clipboard
part directive #
The generated code will be in a separated file referenced by
a part directive in your code file:
file user_file.dart:
import 'package:reflection_factory/reflection_factory.dart';

// The reference to the generated reflection code:
part 'user_file.reflection.g.dart';

@EnableReflection()
class User {
String name;
String? email;

User(this.name, this.email);

User.empty() : this('','') ;
}
copied to clipboard
You can also use a subdirectory to have the generated reflection files:
file user_file.dart:
import 'package:reflection_factory/reflection_factory.dart';

// The reference to the generated reflection code inside a subdirectory:
part 'reflection/user_file.g.dart';

@EnableReflection()
class User {
//...
}
copied to clipboard
The builder will automatically detect the part directive and identify if the
generated code needs to be in a subdirectory or not,
but always using the parent file name (user_file.dart)
in the generated file name (user_file.reflection.g.dart or reflection/user_file.g.dart).
Dependencies #
You need to add 2 dependencies in your project:
File: pubspec.yaml
dependencies:
reflection_factory: ^1.2.10

dev_dependencies:
build_runner: ^2.2.0
copied to clipboard
Building/Generating Code #
To generate the reflection code just run build_runner in your Dart project:
$> dart run build_runner build
copied to clipboard
Options #
You can configure the builder declaring a build.yaml file in your project:
File: build.yaml
targets:
$default:
builders:
reflection_factory:
options:
verbose: true
sequential: true
timeout: 2 sec
copied to clipboard

Options:

verbose: If true builds the reflection code in verbose mode (default: false).
sequential: If true will process the BuildSteps sequentially. (default: true).
timeout: The sequential BuildStep timeout (default: 30 sec).



Source #
The official source code is hosted @ GitHub:

https://github.com/gmpassos/reflection_factory

Features and bugs #
Please file feature requests and bugs at the issue tracker.
Contribution #
Any help from the open-source community is always welcome and needed:

Found an issue?

Please fill a bug report with details.


Wish a feature?

Open a feature request with use cases.


Are you using and liking the project?

Promote the project: create an article, do a post or make a donation.


Are you a developer?

Fix a bug and send a pull request.
Implement a new feature.
Improve the Unit Tests.


Have you already helped in any way?

Many thanks from me, the contributors and everybody that uses this project!



If you donate 1 hour of your time, you can contribute a lot,
because others will do the same, just be part and start with your 1 hour.
Author #
Graciliano M. Passos: gmpassos@GitHub.
License #
Apache License - Version 2.0

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files:

Customer Reviews

There are no reviews.