依赖注入(IOC)就是通过容器,将当前这个类所需的对象实例化,而不需要这个类自身去实例化这个对象。目的是为了类的解耦。在小项目里面可能无法体现依赖注入的价值,但是在大型多人合作的项目里面,依赖注入能让整个项目更加健壮和易于维护。 说起依赖注入,最大名鼎鼎的莫过于Java的Spring系列。在Flutter开发中也有很多的依赖注入框架,其中官方推荐的框架就是本文的主角 Inject 由于Inject不支持导包的形式,因此只能通过导入源码的方式引入。 然后在pubspec.yaml文件中引用 之后在项目根目录下创建一个名为inject_generator.build.yaml的文件复制以下配置内容 直接说原理和概念容易让人一头雾水,因此先展示一个简单的示例 首先写一个非常简单的Presenter 可以看到我们给这个类加了一个@provide的注解 接下来需要一个Widget来使用我们的Presenter 使用这个Presenter也很简单,只需要在构造函数里传入即可,并且给该类加上@provide的注解。 这么写很好理解,但是下一个问题就来了, 按照正常的Ioc来说,必然是有一个注射器来注入实例化对象的,Inject当然也不例外,这里就要用到另外一个注解 由于我们还没有编译,会出现找不到 现在基本的代码已经完成了,我们编译一下生成所需的代码 最后 在main函数里使用该注射器 可以看到,整个依赖注入已经完成了。 上面是比较常规的使用,Inject还有别的注解 这个注解的含义比较简单,让当前类成为一个单例,只会实例化一次。 我们给之前的UserWidget增加一个singleton注解,重新build之后 可以看到当 平时开发经常会有一个module里面包含多个Repository的写法,如果像上面一样把所有东西扔到 首先 写两个有依赖的 然后 需要一个module来提供Repository 最后,在上面的 重新运行后,可以看到UserRepository也已经被成功注入了序言
Inject
导入
在lib同级别目录新建vendor文件夹
在vendor文件夹里导入inject源码git clone https://github.com/google/inject.dart.git
注意 Inject依赖于build runner,因此也需要引入build runnerdependencies: inject: path: ./vendor/inject.dart/package/inject dev_dependencies: build_runner: ^1.0.0 inject_generator: path: ./vendor/inject.dart/package/inject_generator
builders: inject_generator: target: ":inject_generator" import: "package:inject_generator/inject_generator.dart" builder_factories: - "summarizeBuilder" - "generateBuilder" build_extensions: ".dart": - ".inject.summary" - ".inject.dart" auto_apply: dependents build_to: cache
简单入门
@provide class UserPresenter{ String getUserName() { return "Nike"; } }
provide这个注解用于告诉Inject,当前这个类是需要让Inject来帮助我们实例化的,当我们编译时Inject会帮我们把这个类放入注射器里面,当有类需要用到UserPresenter的实例化对象时,Inject会再帮我们从注射器里将UserPresenter对象注入到该类。@provide class UserWidget extends StatelessWidget { UserPresenter _userPresenter; UserWidget(this._userPresenter); @override Widget build(BuildContext context) { return Text(_userPresenter.getUserName()); } }
UserPresenter
UserWidget
这两个对象既然不能通过直接new来实例化,那它们到底是在哪里被实例化的呢?@Injector()
来配置我们需要的注射器。import 'app_injector.inject.dart' as g; @Injector() abstract class AppInjector { @provide UserWidget get userWidget; static Future<AppInjector> create() { return g.AppInjector$Injector.create(); } }
app_injector.inject.dart
的错误提示@Injector()
这个注解告诉Inject,当前这个类是一个注射器,我们需要的实例都可以通过注射器来获取。比如当前我们需要UserWidget
的实例。我们需要这么一行代码 @provide UserWidget get userWidget;
在命令行执行flutter packages pub run build_runner build
void main() async { final container = await AppInjector.create(); runApp( MaterialApp( home: Scaffold( body: Center(child: container.userWidget), ), )); }
进阶
@singleton
@singleton @provide class UserWidget extends StatelessWidget {
我们进入到自动生成的app_injector.inject.dart代码里面 _i2.UserWidget _singletonUserWidget; _i2.UserWidget _createUserWidget() => _singletonUserWidget ??= _i2.UserWidget(_createUserPresenter());
UserWidget
不为空时,会重用之前的对象。@module
Injector
会使Injector
变得很臃肿。我们可以通过@module
注解来解决这个问题Repository
@provide class UserRepository { GoodRepository _goodRepository; UserRepository(this._goodRepository); Future<List<String>> getAllUsers() { print("getAllUsers"); _goodRepository.getAllGoods(); return null; } } @provide class GoodRepository { Future<List<String>> getAllGoods() { print("getAllGoods"); return null; } }
@module class UserService{ @provide UserRepository userRepository(GoodRepository goodRepository) => UserRepository(goodRepository); }
UserPresenter
里使用这个Repository
@provide class UserPresenter{ UserRepository _userRepository; UserPresenter(this._userRepository); String getUserName() { _userRepository.getAllUsers(); return "Nike"; } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算