Skip to content

Instantly share code, notes, and snippets.

@Nillerr
Created September 27, 2022 11:18
Show Gist options
  • Save Nillerr/88c8e7dbe00c67709e0e6839ce13b574 to your computer and use it in GitHub Desktop.
Save Nillerr/88c8e7dbe00c67709e0e6839ce13b574 to your computer and use it in GitHub Desktop.
import Swinject
private let prefix = "<asOneOf:"
private func nameOf<T>(_ serviceType: T) -> String {
return "\(prefix):\(String(reflecting: serviceType))>"
}
class AggregateBehavior<Common> : Behavior {
private var factories: [(Resolver) -> Common?] = []
func container<Type, Service>(_ container: Container, didRegisterType type: Type.Type, toService entry: ServiceEntry<Service>, withName name: String?) {
guard Type.self == Common.self, let name = name, name.starts(with: prefix) else { return }
if factories.isEmpty {
container.register([Common].self) { resolver in
return self.factories.map { factory in factory(resolver)! }
}
}
factories.append({ resolver in
let name = nameOf(Service.self)
return resolver.resolve(Type.self, name: name) as? Common
})
}
}
extension Container {
func aggregate<Service>(_ serviceType: Service.Type) {
addBehavior(AggregateBehavior<Service>())
}
}
extension ServiceEntry {
@discardableResult
func asOneOf<T>(_ serviceType: T.Type) -> ServiceEntry<Service> {
let name = nameOf(Service.self)
return implements(serviceType, name: name)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment