Flutter未知功能插件toor的使用(注意:由于介绍为undefined,以下基于插件名进行合理推测)

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter未知功能插件toor的使用(注意:由于介绍为undefined,以下基于插件名进行合理推测)

🌱 什么是Toor

Toor 是一个用于管理服务定位器的库,它使服务定位器在编译时安全且易于管理。

目录

🚀 入门

首先,在项目中的某个地方定义你的依赖项。所有的全局和静态变量默认都是惰性的,因此你不必担心注册未使用的对象会消耗内存。

final toor = Toor.instance;

final httpClientSingleton = toor.registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

final authRepositoryFactory = toor.registerFactory<IAuthRepository>(
  () => AuthRepositoryImpl(httpClient: httpClientSingleton()),
);

之后,你可以安全地访问你注册的工厂或懒单例:

void authenticate(String email, String password) {
  authRepositoryFactory().authenticate(email, password);
}

✨ Toor 详细介绍

定位器类型

Toor 目前支持两种类型的对象:工厂和懒单例。

工厂

工厂是在每次获取时创建的定位器。

使用 Toor.registerFactory 创建工厂定位器:

final toor = Toor.instance;

final authRepositoryFactory = toor.registerFactory<IAuthRepository>(
  AuthRepositoryImpl.new,
);

懒单例

懒单例是在第一次调用时创建的定位器。第一次创建的对象将在后续每次获取时返回。

使用 Toor.registerLazySingleton 创建懒单例定位器:

final toor = Toor.instance;

final credentialManager = toor.registerLazySingleton<ICredentialManager>(
  CredentialManagerImpl.new,
);

可变懒单例

在某些情况下,你可能需要你的单例是可变的(例如,多环境)。Toor 提供了可变单例。使用 Toor.registerMutableLazySingleton 创建可变懒单例,并使用 put 方法更改其值:

final toor = Toor.instance;

final appFlavor = toor.registerMutableLazySingleton(
  create: () => Flavor.dev,
);
print(appFlavor()); // Flavor.dev

appFlavor.put(Flavor.prod);

print(appFlavor()); // Flavor.prod

当调用 reset 时,可变懒单例将被重置为其初始值。

额外的清理代码与 onDispose

Toor 允许你在注册懒单例时传递一个可选的 onDispose 函数,以便进行一些清理操作(例如,关闭套接字连接、取消订阅流等)。onDispose 还可以访问当前单例的值。使用方法如下:

final toor = Toor.instance;

final permissionManager = toor.registerLazySingleton<IPermissionManager>(
  PermissionManagerImpl.new,
  onDispose: (manager) {
    manager.dispose();
  },
);

异步工厂

异步工厂是在每次获取时异步创建的定位器。

使用 Toor.registerFactoryAsync 创建异步工厂定位器:

final toor = Toor.instance;

final dataPersisterFactory = toor.registerFactoryAsync<IDataPersister>(
  () async => SharedPreferencesDataPersister(
    sharedPreferences: await SharedPreferences.getInstance(),
  ),
);

等待工厂的创建并使用它:

final dataPersister = await dataPersisterFactory();
dataPersister.saveData('big');

带参数的工厂

你还可以创建接受1个或2个参数的工厂:

final toor = Toor.instance;

final personFactory = toor.registerFactoryWithParam<Person, String>(
  (name) => Person(name),
);

final vehicleFactory = toor.registerFactoryWithTwoParams<Vehicle, String, int>(
  (name, productionYear) => Vehicle(name, productionYear),
);

class Person {
  const Person(this.name);

  final String name;
}

class Vehicle {
  const Vehicle(this.name, this.productionYear);

  final String name;
  final int productionYear;
}

void main() {
  // 两者都是编译时安全的,并且知道类型
  final driver = personFactory('Doc');
  final vehicle = vehicleFactory('DeLorean', 1981);
}

异步工厂也支持通过 registerFactoryAsyncWithParamregisterFactoryAsyncWithTwoParams 创建。

高级用法

重置懒单例

你可以通过 reset 方法重置懒单例。这将删除当前对象并在下次调用时创建一个新的对象。

final toor = Toor.instance;

String value = 'Initial';

final lazySingleton = toor.registerLazySingleton<String>(
  () => value,
);

// 即使我们在这里更改了 `value` 变量,
// `lazySingleton` 的值仍将是 'Initial'。
value = 'Changed';

print(lazySingleton()); // 'Initial'

// 一旦我们重置 `lazySingleton`,它在下次调用时的值将为 'Changed'。
lazySingleton.reset();

print(lazySingleton()); // 'Changed'

重置所有懒单例

Toor 允许你通过其实例上的 reset 方法一次性重置所有懒单例。这将调用每个懒单例的 reset 方法。

final toor = Toor.instance;

String value = 'Initial';

final lazySingleton = toor.registerLazySingleton<String>(
  () => value,
);

value = 'Changed';

print(lazySingleton()); // 'Initial'

// 一旦我们重置 `toor`,所有通过 `toor.registerLazySingleton` 注册的懒单例都将被重置。
toor.reset();

print(lazySingleton()); // 'Changed'

创建新的Toor实例

你可能希望创建多个独立的 Toor 实例。Toor.instance 获取器将返回默认实例,但你不必使用它。你可以通过 Toor.newInstance() 创建新的 Toor 实例。你可能希望这样做以重置与特定域相关的懒单例(例如,在登出时重置所有持有用户数据的单例)。

final authToor = Toor.newInstance();
final analyticsToor = Toor.newInstance();

final credentialManager = authToor.registerLazySingleton<ICredentialManager>(
  CredentialManagerImpl.new,
);

final sessionRecorder = authToor.registerLazySingleton<ISessionRecorder>(
  SessionRecorderImpl(upload: false),
);

void logout() {
  // `credentialManager` 将被重置,但 `sessionRecorder` 不会被重置,因为它注册在 `analyticsToor` 而不是 `authToor` 中。
  authToor.reset();
}

使用顶级函数注册定位器

Toor 提供了几种在全局 Toor 实例中注册定位器的方法:

// 你可以使用 `Toor.instance` 获取器,然后调用 `registerLazySingleton` 或其他方法。
final toor = Toor.instance;

final httpClientSingleton = toor.registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

// 或者你可以使用同名的顶级函数,它基本上会在 `Toor.instance` 上调用该方法。
final httpClientSingleton = registerLazySingleton<IHttpClient>(
  DioHttpClientImpl.new,
);

🧪 使用Toor进行测试

有时,你需要在测试中创建不同的对象(例如,模拟对象)。使用 Toor 有以下两种方法实现:

  1. 根据某些变量或其他 Toor 单例决定要注册的对象(例如,多环境):
final toor = Toor.instance;

final authManager = toor.registerLazySingleton<IAuthManager>(
  flavor.isTesting ? MockAuthManager() : AuthManagerImpl(),
);
  1. 通过 toor_test 中的 override 方法覆盖已注册的对象。override 方法被注解为 visibleForTesting,因为它仅用于测试:
// dependencies.dart
import 'package:toor/toor.dart';

final toor = Toor.instance;

final authManager = toor.registerLazySingleton<IAuthManager>(
  AuthManagerImpl.new,
);
// app_test.dart
import 'package:toor/toor_test.dart';

void main() {
  setUpAll(() {
    authManager.override(() => MockAuthManager());
  });
}

希望这些信息对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter未知功能插件toor的使用(注意:由于介绍为undefined,以下基于插件名进行合理推测)的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter未知功能插件toor的使用(注意:由于介绍为undefined,以下基于插件名进行合理推测)的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,尽管toor这个插件的具体功能和定义在官方文档或主流资源中可能未被明确定义或标记为“undefined”,但基于插件名称的合理推测,它可能与设备根权限(root access)管理或系统级操作相关。由于直接处理系统级权限通常涉及敏感操作,这类插件在Flutter社区中并不常见,且使用不当可能会导致应用被拒绝上架或存在安全风险。

不过,为了展示如何在Flutter中集成和使用一个假设的、与设备根权限相关的插件(这里仅作为示例,并不代表toor插件的实际功能),我们可以构想一个简化的场景:假设toor插件提供了检查设备是否已root以及执行一些需要root权限的命令的功能。

请注意,以下代码仅作为示例,并不代表toor插件的真实API。在实际开发中,你需要参考插件的官方文档或源代码来了解其真实API。

示例代码

首先,假设toor插件的pubspec.yaml依赖声明如下(注意:这里的依赖项是虚构的,用于示例):

dependencies:
  flutter:
    sdk: flutter
  toor: ^0.0.1  # 假设的版本号,实际使用时需替换为真实版本号

然后,在Dart代码中,你可以这样使用它(再次强调,以下代码是假设性的,并不代表toor插件的真实用法):

import 'package:flutter/material.dart';
import 'package:toor/toor.dart'; // 假设的导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isRooted = false;
  String _commandOutput = '';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Root Check Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Device is rooted: $_isRooted'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _checkRootStatus,
                child: Text('Check Root Status'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _executeRootCommand,
                child: Text('Execute Root Command'),
                enabled: _isRooted, // 仅当设备已root时才启用此按钮
              ),
              SizedBox(height: 20),
              Text('Command Output:\n$_commandOutput'),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _checkRootStatus() async {
    setState(() {
      _isRooted = await Toor.checkRootStatus(); // 假设的方法调用
    });
  }

  Future<void> _executeRootCommand() async {
    String output = await Toor.executeCommand('your_root_command_here'); // 假设的方法调用,替换为实际的root命令
    setState(() {
      _commandOutput = output;
    });
  }
}

// 假设的Toor类,实际使用时需参考插件的真实API
class Toor {
  static Future<bool> checkRootStatus() async {
    // 这里应该是调用插件提供的检查root状态的方法
    // 由于是假设的,这里直接返回一个模拟值
    return Future.value(true); // 或 false,根据实际情况返回
  }

  static Future<String> executeCommand(String command) async {
    // 这里应该是调用插件提供的执行root命令的方法
    // 由于是假设的,这里直接返回一个模拟的命令输出
    return Future.value('Command executed successfully'); // 替换为实际的命令输出
  }
}

注意事项

  1. 安全风险:处理root权限时,务必小心,确保你的应用有充分的理由需要这些权限,并遵循最佳安全实践。
  2. 合规性:在应用商店上架时,处理root权限的应用可能会受到额外的审查,确保你的应用符合所有相关平台的政策和规定。
  3. 插件文档:在实际开发中,务必参考toor插件(如果存在的话)的官方文档,了解其真实API和用法。

由于toor插件的具体信息未知,上述代码仅为示例性质,不代表真实用法。在实际项目中,你需要根据插件的实际API进行调整。

回到顶部