Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Static Dependency Injection by Code Generation

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Yosuke Ishikawa
September 17, 2017

Static Dependency Injection by Code Generation

Yosuke Ishikawa

September 17, 2017

Transcript

54 slides
  1. final class ImageDownloader { private let urlSession = URLSession.shared func

    downloadImage(with url: URL, completion: (UIImage) -> Void) { let task = urlSession.dataTask(with: url) {...} task.resume() } }
  2. final class ImageDownloader { private let urlSession: URLSession init(urlSession: URLSession)

    { self.urlSession = urlSession } func downloadImage(with url: URL, completion: (UIImage) -> Void) { let task = urlSession.dataTask(with: url) {...} task.resume() } }
  3. @Generated public final class DaggerAPIComponent implements APIComponent { private Provider<URLSession>

    urlSessionProvider; private Provider<Cache> cacheProvider; private Provider<APIClient> apiClientProvider; private void initialize() { urlSessionProvider = ... cacheProvider = ... apiClientProvider = APIModule_APIClientFactory .create(urlSessionProvider, cacheProvider); } @Override public APIClient apiClient() { return apiClientProvider.get() } } 生成されたコードで依存関係の解決を表現(Java)
  4. protocol Injectable { associatedtype Dependency init(dependency: Dependency) } final class

    APIClient: Injectable { struct Dependency { let urlSession: URLSession let cache: Cache } init(dependency: Dependency) {...} } Swi のDI 用のinitializer
  5. protocol AppResolver: Resolver { func provideURLSession() -> URLSession func provideCache()

    -> URLSession func provideAPIClient(urlSession: URLSession, cache: Cache) -> APIClient } Swi のDI 用のprovider method
  6. struct A: Injectable { struct Dependency { let b: B

    } init(dependency: Dependency) {} } struct B {} protocol ABResolver: Resolver { func provideB() -> B }
  7. extension ABResolver { func resolveA() -> A { let b

    = resolveB() return A(dependency: .init(b: b)) } func resolveB() -> B { return provideB() } } provideB() の実装はABResolver の準拠側に委ねられる
  8. final class UserProfileViewController: UIViewController, Injectable { struct Dependency { let

    userID: Int64 let apiClient: APIClient } init(dependency: Dependency) {} } final class APIClient {...} protocol AppResolver: Resolver { func provideAPIClient() -> APIClient }
  9. extension AppResolver { func resolveAPIClient() -> APIClient { return provideAPIClient()

    } func resolveUserProfileViewController(userID: Int64) -> UserProfileViewContr let apiClient = resolveAPIClient() return UserProfileViewController(dependency: .init(userID: userID, apiCl } }

More Decks by Yosuke Ishikawa

Other Decks in Technology