iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Mobile Development

關於 Flutter 開發的一些設計雜談系列 第 22

Day 22 - 使用依賴注入套件

  • 分享至 

  • xImage
  •  

昨天我們談到使用 Repository 隔離使用端與實作端的直接相依,讓修改實作時變得容易一些。但是如果大家仔細想想可能會發現,假設今天我們有許多地方都使用了 NewsRepositroy,而每個地方都自己指定 NewsRepository 的實作。當今天我們真的想抽換實作時,雖然只要修改建構子的實作指定就好,還是不免要到每個使用到的地方去修改,今天我們就來聊聊如何解決這個問題。

it_img_20_1.png
https://dartpad.dev/?id=139bddfa16e5fb65fbc99734380a8406

依賴注入

為了解決這個問題,我們可以引入依賴注入,讓 NewsCubit 不再是自己建立 NewsRepositroy 的實作,而是跟依賴注入容器索取。以上面的例子來說,我們可以在 App 最外層包一個 RepositoryProvider,並在這邊決定 NewsRepository 的實作。

it_img_20_2.png

當建立 NewsCubit 時,則透過 context.read 取得 NewsRepository,由建構子注入 NewsCubit,NewsCubit 再也不需要負責建立 NewsRepository 了。

it_img_20_3.png
https://dartpad.dev/?id=d2e40b92642ef82f5f164c0a78fb5b5a

這也是依賴注入的功能之一:控制物件的生命週期,將管理物件生命週期的職責,從每個物件中轉移到依賴注入框架中。

抽換實作

當我們使用依賴注入框架,我們是在設定的地方決定實作。當我們決定把 NewsRepository 換成 SqliteDataSource 時,所有使用依賴注入取得 NewsRepository 的地方,都會轉而使用 SqliteDataSource,省去修改每一個類別。

it_img_20_4.png

使用依賴注入框架,當我們更換實作時,我們就不需要逐一到每個使用到的地方更換實作。

其他依賴注入的方式

由於 Flutter 框架本身並沒有提供依賴注入的功能,而在上面的例子中,我們使用 Bloc 提供的 RepositoryProvider 幫助我們在 Flutter 中把相依注入到 News。但是並非所有專案都選擇 Bloc 或 Provider 來做狀態管理。所幸我們還是能從 Flutter 眾多套中之尋找適合的依賴注入套件來搭配使用,我們就用 get_it + injectable 來改造一下範例吧。

首先我們還是得先把套件加入專案中

flutter pub add get_it
flutter pub add injectable
flutter pub add --dev injectable_generator
flutter pub add --dev build_runner

然後我們就能在 Repository 的實作中,設定依賴注入的規則

it_img_20_5.png
https://gist.github.com/a40e02de994bbff456358f3152d13234/revisions

最後當我們建立 NewsCubit 時,就能從 getIt 中取得相對應的實作。

it_img_20_6.png

不知道有沒有讀者會好奇,既然 Flutter 沒有反射,那又是如何從依賴注入中取得相對應的實作的呢?其實秘密是利用 build runner 幫我們產生依賴設定的程式碼,像是下圖那樣。

it_img_20_7.png

Provider V.S. GetIt

最後我們來思考一下,當我們想使用依賴注入時,該使用 Provider 或者是 GetIt 呢?在討論之前,我們先來看看兩者的使用方法。這兩種使用方式都有一個共通點,那就是都是 Service Locator 的方式取得相依,也就是無可避免的,我們的程式碼一定會相依於依賴注入框架。

// Provider
context.read<NewsRepositroy>();

// GetIt
getIt<NewsRepository>()

再來讓我們看看不同之處,當使用 Provider 取得相依時,必須有 context 才可以呼叫,原因是 Provider 尋找相依的方式是基於 Widget 樹,也就是說,只有在 View 層的程式碼,我們才能使用 context.read 來尋找相依。當今天使用的地方不在 View 時,我們就無法取得 context,也就無法取得相依,使用的地方會相對於 GetIt 更為受限。

結論

使用依賴注入,將物件建立與管理的職責可以轉移到依賴注入框架中,讓我們的程式碼可以專注如何與依賴注入框架互動即可。當我們想抽換實作,也可以直接修改依賴注入設定即可,而不必修改使用端程式碼。


上一篇
Day 21 - 避免讓資料源綁架程式
下一篇
Day 23 - 暫存一些資料,增加使用者體驗
系列文
關於 Flutter 開發的一些設計雜談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言