AliSoftware/Dip

Pass containing instance in didInject block

Closed this issue · 1 comments

Auto injecting wrappers Injected and InjectedWeak currently have a block that will be called when wrapped instance is injected by container. The variable that holds reference to wrapper is stored, so it is impossible to reference self when initializing this variable with initial value:

private let _service = Injected<Service> { service in
  self.service = _service //error
}
private(set) var service: Service!

It makes this block not so powerful as didSet property observer.
But we can pass an instance that holds the variable as block argument:

private let _service = Injected<Service> { (me: SomeClass, service) in 
  me.service = _service //me is a reference to self
}
private(set) var service: Service!

This way users can operate on other instance variables or call instance methods easily. We can use generic argument for type of me, but we can not ensure compile time type-safety.
That will be a breaking change.

With Swift 3 generic type aliases (SE-0048) we could extend auto-injection wrappers to two generic parameters like InjectedIn<U, T> and define a type alias for auto-injection inside Resolvable (or any other) protocol like this: typealias Injected<T> = Injected<Self, T>. Then we would be able to use this type alias inside classes just by conforming to Resolvable protocol without needing to specify generic parameter. This will also insure type safety whether using InjectedIn<U, T> will be not type safe. But looks like that it is not yet possible.

We could still replace Injected<T> with InjectedIn<U, T> and let users define type-aliases manually (or not to use them at all), but that will clutter users code with unneeded definitions. So I will close this issue until there is any progress with generic type aliases.