Flutter未知功能探索插件catalyst_builder的使用
Flutter未知功能探索插件catalyst_builder的使用
Catalyst Builder 简介
Catalyst Builder 是一个用于Dart和Flutter的依赖注入提供者构建器。它简化了依赖注入的过程,使开发者只需在服务类上添加@Service
注解,通过build_runner
即可自动生成服务提供者。
安装
请按照以下步骤安装:
- 在
pubspec.yaml
中添加依赖:
dev_dependencies:
build_runner: ^2.2.0
catalyst_builder: ^latest_version
- 运行
flutter pub get
以获取依赖包。
使用方法
基本用法
创建服务
在需要注册为服务的类上添加@Service
注解:
@Service()
class MyService {}
注册服务提供者
在入口文件(如main.dart
)中添加@GenerateServiceProvider
注解:
import 'package:catalyst_builder/catalyst_builder.dart';
@GenerateServiceProvider()
void main() {
// ...
}
构建服务提供者
运行以下命令生成服务提供者文件:
flutter pub run build_runner build
或者使用watch模式自动更新:
flutter pub run build_runner watch
使用服务提供者
生成的服务提供者文件通常命名为*.catalyst_builder.g.dart
。导入该文件并创建服务提供者的实例:
import 'my_entrypoint.catalyst_builder.g.dart';
void main() {
var provider = DefaultServiceProvider();
provider.boot();
var myService1 = provider.resolve<MyService>();
MyService myService2 = provider.resolve();
}
高级用法
服务生命周期
可以指定服务的生命周期,默认为单例(Singleton),也可以设置为瞬态(Transient):
@Service(
lifetime: ServiceLifetime.singleton,
)
class SingletonService {}
@Service(
lifetime: ServiceLifetime.transient,
)
class TransientService {}
生命周期 | 描述 |
---|---|
Singleton | 实例存储在提供者中,每次解析返回相同的实例 |
Transient | 每次解析时返回新的实例 |
暴露接口
可以通过exposeAs
参数暴露服务的接口:
abstract class Transport {
void transferData(String data);
}
@Service(exposeAs: Transport)
class ConsoleTransport implements Transport {
@override
void transferData(String data) {}
}
abstract class ChatProvider {
Transport transport;
Future<void> sendChatMessage(String message);
}
@Service(exposeAs: ChatProvider)
class CoolChatProvider implements ChatProvider {
@override
Transport transport;
CoolChatProvider(this.transport);
@override
Future<void> sendChatMessage(String message) {}
}
void main() {
var provider = DefaultServiceProvider();
var chatService = provider.resolve<ChatProvider>();
print(chatService is CoolChatProvider); // true
print(chatService.transport is ConsoleTransport); // true
}
预加载服务
使用@Preload
注解可以在启动时预加载服务:
@Service()
@Preload()
class MyService {
MyService() {
print('Service was created');
}
}
void main() {
ServiceProvider provider;
provider.boot(); // 打印 "Service was created"
provider.resolve<MyService>(); // 不打印任何内容
}
参数注入
可以通过名称注入参数:
@Service()
class MyService {
String username;
MyService(@Inject(parameter: 'senderUserName') this.username);
}
void main() {
ServiceProvider provider;
provider['senderUserName'] = 'Test 2';
provider.boot();
var myService = provider.resolve<MyService>();
print(myService.username); // Test 2
}
动态注册服务
可以在运行时注册服务:
void main() {
var provider = ExampleProvider();
provider.register(
(provider) => MySelfRegisteredService(provider.resolve()),
);
var selfRegistered = provider.resolve<MySelfRegisteredService>();
selfRegistered.sayHello();
}
创建子提供者
可以创建带有额外服务或参数的子提供者:
void main() {
var provider = ExampleProvider();
var newProvider = provider.enhance(
parameters: {
'foo': 'overwritten',
},
services: [
LazyServiceDescriptor<MySelfRegisteredService>(
(p) => MySelfRegisteredService(p.resolve(), p.parameters['foo']),
const Service(exposeAs: SelfRegisteredService),
),
],
);
var mySvc = newProvider.resolve<SelfRegisteredService>();
expect(mySvc.foo, equals('overwritten'));
}
标签化服务
可以给服务打标签,方便分组管理:
@Service(tags: ['#groupTag', '#anotherTag'])
class MyService1 {}
@Service(tags: ['#groupTag', '#anotherDifferentTag'])
class MyService2 {}
void main() {
var provider = ExampleProvider();
provider.boot();
var groupTagServices = provider.resolveByTag('#groupTag');
// groupTagServices = [MyService1, MyService2]
var anotherTagServices = provider.resolveByTag('#anotherTag');
// anotherTagServices = [MyService1]
var anotherDifferentTagServices = provider.resolveByTag('#anotherDifferentTag');
// anotherDifferentTag = [MyService2]
var nonExistingTagServices = provider.resolveByTag('#nonExistingTag');
// servicesWithUnknownTag = []
}
注入标签化服务
可以通过标签注入一组服务:
abstract class MyServiceBase {}
@Service(tags: ['#groupTag', '#anotherTag'])
class MyService1 extends MyServiceBase {}
@Service(tags: ['#groupTag', '#anotherDifferentTag'])
class MyService2 extends MyServiceBase {}
@Service()
class ServiceWithDeps {
ServiceWithDeps(
@Inject(tag: '#groupTag') List<MyServiceBase> services,
) {
// services 包括 MyService1 和 MyService2
}
}
示例代码
import 'package:catalyst_builder/catalyst_builder.dart';
import './src/manually_wired_service.dart';
export './public_api.dart';
export './src/manually_wired_service.dart';
export 'example.catalyst_builder.g.dart';
/**
* Export the catalyst_exports that the watch command can recompile the
* ServiceProvider when the dependencies changes.
*/
export 'relative_deps_exports.dart';
@Preload()
@GenerateServiceProvider()
@ServiceMap(services: {
ManuallyWiredServiceImplementation: Service(
exposeAs: ManuallyWiredService,
),
})
void main() {
var provider = DefaultServiceProvider();
provider.boot();
var manuallyWiredService = provider.resolve<ManuallyWiredService>();
manuallyWiredService.doSomething();
}
以上是关于catalyst_builder
插件的详细使用说明和示例代码,希望对你有所帮助。如果你有任何问题或需要进一步的帮助,请随时提问!
更多关于Flutter未知功能探索插件catalyst_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter未知功能探索插件catalyst_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter开发中,catalyst_builder
是一个相对不太常见的插件,但它提供了一些独特的功能,用于在构建过程中动态生成代码或资源。虽然文档和社区资源可能有限,但我们可以基于其基本的用法来探索其功能。
首先,确保你已经在 pubspec.yaml
文件中添加了 catalyst_builder
依赖:
dependencies:
flutter:
sdk: flutter
dev_dependencies:
build_runner: ^x.y.z # 请替换为最新版本
catalyst_builder: ^a.b.c # 请替换为最新版本
然后运行 flutter pub get
来获取依赖。
catalyst_builder
的核心功能通常是通过自定义构建步骤来生成代码或资源。为了展示其基本用法,我们可以创建一个简单的示例,假设我们要生成一些 Dart 代码文件。
- 创建构建配置
首先,在你的项目根目录下创建一个 build.yaml
文件,用于配置构建步骤:
builders:
generate_code:
import: "package:catalyst_builder/builder.dart"
builder_factories: ["generateCodeBuilder"]
build_extensions: {".dart": [".g.dart"]}
auto_apply: root_package
build_to: cache
在这个配置中,我们定义了一个名为 generate_code
的构建器,它使用 catalyst_builder
包中的 generateCodeBuilder
函数。这个构建器会为每个 .dart
文件生成一个对应的 .g.dart
文件。
- 编写构建器逻辑
由于 catalyst_builder
的具体 API 可能会有所不同,这里我们假设需要实现一个自定义的构建器逻辑。在实际使用中,你可能需要查阅 catalyst_builder
的具体文档来了解如何编写构建器。但作为一个示例,我们可以模拟一个简单的构建器:
// lib/builder/generate_code_builder.dart
import 'package:build/build.dart';
Builder generateCodeBuilder(BuilderOptions options) {
return (BuildStep buildStep) async {
var inputId = buildStep.inputId;
var input = await buildStep.readAsString(inputId);
// 这里我们简单地将输入内容回显到生成的文件中,实际使用中你可能会有更复杂的逻辑
var outputContent = '''
// This is auto-generated code
part of '${inputId.path.split('.dart').first}';
void generatedFunction() {
print('Hello from generated code!');
}
''';
var outputId = inputId.changeExtension('.g.dart');
await buildStep.writeAsString(outputId, outputContent);
};
}
注意:上面的代码只是一个示例,实际上 catalyst_builder
可能不支持这种直接的构建器定义方式,或者你可能需要通过其他方式(如使用其提供的特定 API)来实现类似的功能。
- 应用构建器
在你的 Dart 代码中,你可以像这样引用生成的代码:
// lib/main.dart
part 'main.g.dart'; // 引用生成的代码文件
void main() {
print('Running main function');
generatedFunction(); // 调用生成代码中的函数
}
- 运行构建
最后,使用 flutter pub run build_runner build
命令来运行构建过程。如果一切正常,你应该会在 .dart_tool/build/generated/
目录下看到生成的 .g.dart
文件。
注意:上述代码和配置是基于假设和一般构建器的工作原理编写的,实际使用 catalyst_builder
时,你需要查阅其官方文档和示例来了解其具体的用法和 API。由于 catalyst_builder
不是一个广泛使用的插件,因此文档和社区支持可能有限,建议在使用前仔细阅读其源码和文档。