Catalyst Builder 是一个用于Dart和Flutter的依赖注入提供者构建器

Catalyst Builder 是一个用于Dart和Flutter的依赖注入提供者构建器

Catalyst Builder 简介

GitHub license GitHub issues GitHub Workflow Status Pub Pub Points Pub Publisher Pub Popularity Pub Likes

Catalyst Builder 是一个用于Dart和Flutter的依赖注入提供者构建器。它简化了依赖注入的过程,使开发者只需在服务类上添加@Service注解,通过build_runner即可自动生成服务提供者。

安装

请按照以下步骤安装:

  1. pubspec.yaml中添加依赖:
dev_dependencies:
  build_runner: ^2.2.0
  catalyst_builder: ^latest_version
  1. 运行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插件的详细使用说明和示例代码,希望对你有所帮助。如果你有任何问题或需要进一步的帮助,请随时提问!


更多关于Catalyst Builder 是一个用于Dart和Flutter的依赖注入提供者构建器的实战教程也可以访问 https://www.itying.com/category-92-b0.html

回到顶部