It would be nice (?) to create a @propertyWrapper around dependencies when using a dependency container.
Something like:
class Something: Boomerang.DependencyContainer {
let container = ObjectContainer()
@Dependency(closure: { MyThingImplementation() }
var myThing: MyThing
init() {
}
}
As of today the main issues are:
1) there is no official way to access the "enclosing" object from withing a property wrapper. Some workaround is possible with undocumented api (see below)
2) when actually using the propertyWrapper (@Dependency in my example above), you cannot reference self, as it's not yet available. Therefore, all closures used for registration cannot use variables that may have been stored in self, and self should be passed to the closure itself
3) To pass self to the closure, we should define the enclosing type upon PW creation itself, which sounds awful and superfluous.
A possible implementation (for future reference) is:
@propertyWrapper struct Dependency<Value, Container: Boomerang.DependencyContainer> where Container.DependencyKey == ObjectIdentifier {
private let closure: (Container) -> Value
private let scope: Boomerang.Container<ObjectIdentifier>.Scope
init(_ containerType: Container.Type = Container.self,
scope: Boomerang.Container<ObjectIdentifier>.Scope = .singleton,
closure: @escaping (Container) -> Value) {
self.scope = scope
self.closure = closure
}
@available(*, unavailable,
message: "This property wrapper can only be applied to classes"
)
public var wrappedValue: Value {
get { fatalError() }
// swiftlint:disable unused_setter_value
set { fatalError() }
}
public static subscript(
_enclosingInstance instance: Container,
wrapped wrappedKeyPath: ReferenceWritableKeyPath<Container, Value>,
storage storageKeyPath: ReferenceWritableKeyPath<Container, Self>
) -> Value {
get {
guard let value = instance.resolve(Value.self) else {
instance.register(for: Value.self,
scope: instance[keyPath: storageKeyPath].scope,
handler: { instance[keyPath: storageKeyPath].closure(instance) })
return instance.unsafeResolve()
}
return value
}
set {}
}
}
It would be nice (?) to create a
@propertyWrapper
around dependencies when using a dependency container.Something like:
As of today the main issues are: 1) there is no official way to access the "enclosing" object from withing a property wrapper. Some workaround is possible with undocumented api (see below) 2) when actually using the propertyWrapper (
@Dependency
in my example above), you cannot referenceself
, as it's not yet available. Therefore, all closures used for registration cannot use variables that may have been stored in self, and self should be passed to the closure itself 3) To pass self to the closure, we should define the enclosing type upon PW creation itself, which sounds awful and superfluous.A possible implementation (for future reference) is: