3
5

【Swift】DIとは?コンストラクタインジェクションについて説明

Posted at

目次

1.DIとは?
2.コンストラクタインジェクションの実例
3.おわりに

1. DIとは?

正式名称Dependency Injection、通称DI。日本語で言うと「依存性注入」です。
訳分からないですよね?、、
でも、大丈夫です。本記事で誤解を恐れずに、なるべく簡単に説明します。

DIとは、簡単に言うと「オブジェクトを生成する際に(、もしくは遅れて)、必要なデータセットを渡しますよ〜」と言うことです。
その中でもSwiftのDIではコンストラクタインジェクションというものがあります。
コンストラクタインへクションとは簡単にいうと「オブジェクトを生成する際に、必要なデータセットを渡しますよ〜」です。

2. コンストラクタインジェクションの実例

早速コードを見てみます。

コンストラクタインジェクションを使用しない場合

HogeWireframe.swift
protocol Wireframe {
    associatedtype ViewController: UIViewController
    var viewController: ViewController? { get set }
}

class HogeWireFrame: Wireframe {
    typealias ViewController = HogeViewController
    weak var viewController: HogeViewController?
    init(viewController: ViewController) {
        //↓ここが外部から渡されるべきプロパティ
        self.viewController = viewController
    }

    func printName() {
        print(String(describing: viewController.self))
    }
}
HogeViewController.swift
class HogeViewController: UIViewController {
    let wireframe: HogeWireFrame
    // wireframe.viewController = selfを忘れてしまう可能性あり
    wireframe.viewController = self
    func printVCName() {
        wireframe.printName()
    }
}

ごにょごにょと書きましたが、要は、クラスで定義した外部から与えられるべきプロパティviewControllerがnilのままになる可能性があります。
実際にwireframe.viewController = selfの処理を記述を忘れたとしてもnilを許容しているので、デバッカーのエラーすら吐かれないのです。怖い!

そこで登場するのがコンストラクタインジェクションです。

コンストラクタインジェクションを使用する場合

HogeWireframe.swift
import UIKit

protocol Wireframe {
    associatedtype ViewController: UIViewController
    var viewController: ViewController? { get set }
}

class HogeWireFrame: Wireframe {
    typealias ViewController = HogeViewController
    weak var viewController: HogeViewController?
    init(viewController: ViewController) {
        //↓ここが外部から渡されるべきプロパティ
        self.viewController = viewController
    }

    func printName() {
        print(String(describing: viewController.self))
    }
}
HogeViewController.swift
import UIKit
class HogeViewController: UIViewController {
    // ↓ここがコンストラクタインジェクション、インスタンス生成と同時にプロパティの値を注入
    private lazy var wireframe: HogeWireFrame = .init(viewController: self)
    func printVCName() {
        wireframe.printName()
    }
}

以上のようにDIを正しく行うことで、クラスのプロパティへの値の渡し忘れを防ぐことができます。

3. おわりに

コードの規模が大きくなると、クラスのプロパティが内部で値を持っているもの、外部から渡されるべきものが混沌として、整理がつかなくなります。
その結果、、プロパティ値の渡し忘れなどが発生して正しく画面遷移できないなどのバグが発生し得ます。

DIのひとつコンストラクタインジェクションはこれを解決してくれる、一つの最適解なので頭に入れておいてください!
本記事を読んでいただき、ありがとうございました!!

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5