square / Cleanse

Lightweight Swift Dependency Injection Framework
Other
1.78k stars 90 forks source link

Property Injections #105

Closed a-shelyuk closed 5 years ago

a-shelyuk commented 5 years ago

I'm trying to resolve properties of my objects, but in one of them injectProperties method does not call.

Here is my code:

final class AppDelegate: UIApplicationDelegate {

    private var repository: Repository!
    private var view: View!

    private func inject() {
        let propertyInjector: PropertyInjector<AppDelegate> = try! ComponentFactory.of(AppComponent.self, validate: true).build(())
        propertyInjector.injectProperties(into: self)
    }

    func injectProperties(_ repository: Repository, view: View) {
        self.repository = repository
        self.view = view

        repository.exec()
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        inject()
        return true
    }
}

class View {

    let presenter: Presenter

    init(presenter: Presenter) {
        self.presenter = presenter
    }
}

class Presenter {

    weak var view: View? 

    init() {
    }

    func injectProperties(_ view: View) {
        self.view = view
    }
}

class Executor {
}

protocol Repository {
    func exec()
}

class RepositoryImpl: Repository {

    let executor: Executor

    init(executor: Executor) {
        self.executor = executor
    }

    func exec() {
        debugPrint("exec")
    }
}

struct UserScope: Scope {}
struct ApplicationScope: Scope {}

struct CoreModule: Module {
    typealias Scope = UserScope

    static func configure(binder: Binder<UserScope>) {
        binder.bind().to(factory: Executor.init)
        binder.bind(Repository.self).to(factory: RepositoryImpl.init)
    }
}

struct AppComponent: RootComponent {
    typealias Root = PropertyInjector<AppDelegate>
    typealias Scope = UserScope

    static func configure(binder: Binder<AppComponent.Scope>) {
        binder.include(module: CoreModule.self)

        binder.bind().to(factory: View.init)
        binder.bind().to(factory: Presenter.init)
        // looks like it do nothing
        binder.bindPropertyInjectionOf(Presenter.self).to(injector: Presenter.injectProperties)
    }

    static func configureRoot(binder bind: ReceiptBinder<AppComponent.Root>) -> BindingReceipt<AppComponent.Root> {
        return bind.propertyInjector(configuredWith: { (bind) -> BindingReceipt<PropertyInjector<AppDelegate>> in
            bind.to(injector: AppDelegate.injectProperties)
        })
    }
}

So, my questions is what I'm doing wrong? why Presenter.injectPoperties does not call?