Flutter插件darin的使用方法详解
Flutter插件darin的使用方法详解
Flutter插件darin特性
- 在Dart中以尽可能接近DSL的方式定义依赖项
- 使用作用域来控制对象的生命周期(依赖于垃圾回收机制)
- 半自动的依赖解析
- 没有魔法,所有功能都是通过常规Dart代码实现,没有不必要的代码生成
Flutter插件darin原则
- 使用工厂方法每次请求时获取新实例
- 使用作用域获取在整个作用域生命周期内持久化的实例
- 作用域是通用的,如果你想要单例,只需在一个始终存在的作用域中创建一个作用域
- 没有内置全局/静态容器,如果你想拥有一个,自己管理它
- 作用域存在于层次结构中,首先创建最宽的作用域,然后逐层创建更窄的作用域
- 如果当前作用域中找不到所需的依赖项,Darin会尝试在所有父作用域中解析
- 你的作用域将拥有所有者。概念上讲,理解作用域与其生命周期的绑定很重要。作用域应该在比其所有者更早被丢弃,否则会导致内存泄漏
开始使用
导入包:
dependencies:
darin:
Flutter插件darin使用
创建你的作用域:
final scope = Scope((scope) => scope
..factory<Interface1>((scope) => Implementation1())
..scoped<Interface2>((scope) => Implementation2(scope.get<Interface1>()))
..scope<Interface4>((scope) => scope
..factory<Interface4>((scope) => Implementation4(scope.get<Interface3>()))
..scoped<Interface5>((scope) => Implementation5(
scope.get<Interface3>(),
scope.get<Interface4>(),
))
)
);
你可以将应用特定部分的依赖项分离到多个作用域(甚至跨包),并在一个地方组合它们:
final scope = Scope.fromScopes([
scopeFromAPackage(),
scopeFromBPackage(),
scopeFromCPackage(),
]);
使用此scope
作为依赖注入容器。你可以将其用作服务定位器,但我建议避免这样做,而是定义所有类的提供者在你的作用域和子作用域中,并仅获取根对象,让Darin负责解析依赖项。如果你选择这种方式,请不要忘记利用提供者支持或创建子作用域。
获取你的依赖项:
final MyDep = scope.get<MyDep>();
获取更窄的作用域:
// 所有者将是 `existingObject`,并且在子作用域中可用
final subscope = scope.scope<MyDep>(existingObject);
// 或者
// 作用域的所有者将由 `scope` 提供,并且在子作用域中可用
final subscope = scope.scopeProvided(MyDep);
路线图
- ✅ 基本注入与作用域支持
- ✅ Flutter集成通过
InheritedWidget
- ✅ 支持Set/Map
- ✅ 获取提供者类似于获取依赖项
- ❌ 工厂参数
其他信息
对于Flutter集成,参见Darin Flutter。
对Koin用户
Koin设计为让你能够在应用程序的任何位置获取依赖注入容器,即使你没有引用。我的猜测是这样做是为了让你可以在Android Activity中使用val myDep by inject<MyDep>()
,因为在这些Activity中你没有任何可以利用的上下文/作用域,因此需要静态访问器。这在Flutter中不是问题,因为你在Flutter中实际控制屏幕的创建方式,以及你在BuildContext
中拥有的内容。因此,我没有包含任何静态内容,这可能会允许你依赖全局引用。有一些静态函数遵循Flutter模式(想想SomethingFluttery.of(BuildContext)
),但这些依赖于BuildContext
,因此你不会使用任何全局引用,即使是幕后操作也是如此。这是为了好理由,因为你总是可以为不同的原因设置并行作用域,而不会像Koin中的Darin.start()
那样互相覆盖。
示例代码
import 'package:darin/darin.dart';
import '_dependencies.dart';
/// 这个例子是一个企业级的Hello World(意味着绝对复杂)
/// 以演示依赖项及其如何定义DI配置。
/// 它展示了如何创建作用域、作用域化依赖项以及使用提供者。
///
/// 我不想过度解释代码,但一些解释有助于理解:
/// - 这个Hello World“访问地点”,并从那里问候(意思是打印的行具有地点)
/// - 每次访问都在自己的作用域中,因此当你使用位置提供者时,
/// 你会自动获取属于该访问的位置。
/// - 仅为了演示如何作用域化依赖项,[RandomNameProvider]被作用域化
/// (在最顶层作用域中,所以技术上来说它是单例的),因此记住第一次使用时随机化的值
/// 对整个应用生命周期有效。
void main() {
Scope mainScope = buildMainScope();
var locations = [Location("GitHub"), Location("pub.dev")];
for (var location in locations) {
var scope = mainScope.scope(location);
scope.get<GreetingPrinter>().printGreeting();
}
}
// 下面是所有与Darin相关的代码
/// 构建此示例中的主要作用域。这被视为单例,
/// 因为应用程序的逻辑在整个应用生命周期中保持它。
Scope buildMainScope() {
return Scope(
(builder) {
return builder
..scoped<NameProvider>((scope) => RandomNameProvider())
..factory<GreetingPrinter>(
(scope) => ConsoleGreetingPrinter(scope.get()),
)
..scope<Location>(
(builder) => builder
..factory(
(scope) => Greeter(scope.get(), scope.getProvider()),
),
);
},
);
}
更多关于Flutter插件darin的使用方法详解的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter插件darin的使用方法详解的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,在探讨一个未明确定义的Flutter插件(如 darin
)时,我们可以基于插件名称和常见的Flutter插件功能进行合理推测,并展示如何使用一个假设的插件接口。请注意,以下代码是基于假设构建的,因为实际的 darin
插件可能并不存在或者其功能完全不同。
假设 darin
插件是一个用于数据处理的库,可能提供了一些用于数据转换、加密或解密的功能。以下是一个如何使用这种假设插件的示例代码:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 darin
插件的依赖(注意:这里的 darin
是假设的,实际使用时需要替换为真实插件名):
dependencies:
flutter:
sdk: flutter
darin: ^0.0.1 # 假设的版本号,实际使用时需要替换为真实版本号
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 darin
插件:
import 'package:darin/darin.dart';
3. 使用插件功能
假设 darin
插件提供了一个数据转换功能,比如将字符串加密或解密。以下是一个使用这种功能的示例:
void main() {
// 假设的加密/解密功能使用示例
String originalData = "Hello, Flutter!";
String encryptedData;
String decryptedData;
// 加密数据
try {
encryptedData = Darin.encrypt(originalData);
print("Encrypted Data: $encryptedData");
} catch (e) {
print("Encryption failed: $e");
}
// 解密数据
try {
decryptedData = Darin.decrypt(encryptedData);
print("Decrypted Data: $decryptedData");
} catch (e) {
print("Decryption failed: $e");
}
}
4. 假设的插件接口定义
由于我们不知道 darin
插件的真实接口,以下是一个假设的插件接口定义,用于说明可能的实现方式:
library darin;
export 'src/darin_base.dart';
class Darin {
// 假设的加密方法
static String encrypt(String data) {
// 这里应该实现加密逻辑,但这里只是返回一个假设的加密字符串
return base64Encode(utf8.encode(data)) + "_encrypted";
}
// 假设的解密方法
static String decrypt(String encryptedData) {
// 去除假设的加密标记,并进行解密
if (encryptedData.endsWith("_encrypted")) {
String encodedData = encryptedData.substring(0, encryptedData.length - "_encrypted".length);
List<int> decodedBytes = base64Decode(encodedData);
return utf8.decode(decodedBytes);
} else {
throw Exception("Invalid encrypted data format");
}
}
}
注意:上述 Darin
类的实现只是为了演示目的,并不是实际的加密/解密逻辑。在实际应用中,应该使用安全的加密库来处理敏感数据。
由于 darin
插件是未知的,上述代码和假设可能并不符合实际情况。在实际开发中,你应该参考插件的官方文档或源代码来了解其真实功能和用法。