diff --git a/SwiftInjector.xcodeproj/project.pbxproj b/SwiftInjector.xcodeproj/project.pbxproj index 384b5b2..d4e9f3f 100644 --- a/SwiftInjector.xcodeproj/project.pbxproj +++ b/SwiftInjector.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + E6787CB022D6718F006B7C5B /* ContainerableProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6787CAF22D6718F006B7C5B /* ContainerableProtocolTests.swift */; }; + E6787CBC22D75D02006B7C5B /* ProtocolViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6787CBB22D75D02006B7C5B /* ProtocolViewController.swift */; }; + E6787CBE22D75D11006B7C5B /* ProtocolTestClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6787CBD22D75D11006B7C5B /* ProtocolTestClass.swift */; }; E6F3F5AF22D37D28003D86FA /* SwiftInjector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E6F3F5A522D37D28003D86FA /* SwiftInjector.framework */; }; E6F3F5B422D37D28003D86FA /* SwiftInjectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6F3F5B322D37D28003D86FA /* SwiftInjectorTests.swift */; }; E6F3F5B622D37D28003D86FA /* SwiftInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = E6F3F5A822D37D28003D86FA /* SwiftInjector.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -39,6 +42,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + E6787CAF22D6718F006B7C5B /* ContainerableProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerableProtocolTests.swift; sourceTree = ""; }; + E6787CBB22D75D02006B7C5B /* ProtocolViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolViewController.swift; sourceTree = ""; }; + E6787CBD22D75D11006B7C5B /* ProtocolTestClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolTestClass.swift; sourceTree = ""; }; E6F3F5A522D37D28003D86FA /* SwiftInjector.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftInjector.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E6F3F5A822D37D28003D86FA /* SwiftInjector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftInjector.h; sourceTree = ""; }; E6F3F5A922D37D28003D86FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -107,6 +113,8 @@ E6F3F5C222D37D9D003D86FA /* Container.swift */, E6F3F5CC22D37DC4003D86FA /* TestClass.swift */, E6F3F5CB22D37DC4003D86FA /* ViewController.swift */, + E6787CBB22D75D02006B7C5B /* ProtocolViewController.swift */, + E6787CBD22D75D11006B7C5B /* ProtocolTestClass.swift */, E6F3F5BF22D37D9D003D86FA /* Containerable.swift */, E6F3F5C022D37D9D003D86FA /* DIContainer.swift */, E6F3F5C322D37D9D003D86FA /* RootContainer.swift */, @@ -121,6 +129,7 @@ isa = PBXGroup; children = ( E6F3F5B322D37D28003D86FA /* SwiftInjectorTests.swift */, + E6787CAF22D6718F006B7C5B /* ContainerableProtocolTests.swift */, E6F3F5D522D37DE5003D86FA /* ContainerableFormattedStringTests.swift */, E6F3F5CF22D37DE5003D86FA /* ContainerableMainTests.swift */, E6F3F5D022D37DE5003D86FA /* ContainerablePropertyNameTests.swift */, @@ -244,6 +253,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E6787CBC22D75D02006B7C5B /* ProtocolViewController.swift in Sources */, E6F3F5CE22D37DC4003D86FA /* TestClass.swift in Sources */, E6F3F5C722D37D9D003D86FA /* TestContainer.swift in Sources */, E6F3F5C822D37D9D003D86FA /* Container.swift in Sources */, @@ -251,6 +261,7 @@ E6F3F5CA22D37D9D003D86FA /* SILogger.swift in Sources */, E6F3F5CD22D37DC4003D86FA /* ViewController.swift in Sources */, E6F3F5C622D37D9D003D86FA /* DIContainer.swift in Sources */, + E6787CBE22D75D11006B7C5B /* ProtocolTestClass.swift in Sources */, E6F3F5C522D37D9D003D86FA /* Containerable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -264,6 +275,7 @@ E6F3F5D922D37DE5003D86FA /* ContainerablePropertyTests.swift in Sources */, E6F3F5DE22D37DE5003D86FA /* ContrainerableManualRegistrationTests.swift in Sources */, E6F3F5D722D37DE5003D86FA /* ContainerableMainTests.swift in Sources */, + E6787CB022D6718F006B7C5B /* ContainerableProtocolTests.swift in Sources */, E6F3F5DC22D37DE5003D86FA /* ContainerableRegisterTests.swift in Sources */, E6F3F5B422D37D28003D86FA /* SwiftInjectorTests.swift in Sources */, E6F3F5DA22D37DE5003D86FA /* ContainerableRecordRelationsTests.swift in Sources */, diff --git a/SwiftInjector.xcodeproj/project.xcworkspace/xcuserdata/ghost.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftInjector.xcodeproj/project.xcworkspace/xcuserdata/ghost.xcuserdatad/UserInterfaceState.xcuserstate index 6d93b17..4cd8ac7 100644 Binary files a/SwiftInjector.xcodeproj/project.xcworkspace/xcuserdata/ghost.xcuserdatad/UserInterfaceState.xcuserstate and b/SwiftInjector.xcodeproj/project.xcworkspace/xcuserdata/ghost.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/SwiftInjector/Containerable.swift b/SwiftInjector/Containerable.swift index 0388a1e..45ba18c 100644 --- a/SwiftInjector/Containerable.swift +++ b/SwiftInjector/Containerable.swift @@ -31,12 +31,15 @@ public struct ContainerObject { var registrationType: RegistrationType var registration: Containerable.Service var object: Containerable.Object? = nil + var type: Containerable.Object.Type init(_ registration: @escaping Containerable.Service, name: String? = nil, - registrationType: RegistrationType) { + registrationType: RegistrationType, + objectType: Containerable.Object.Type) { self.registration = registration self.name = name self.registrationType = registrationType + self.type = objectType } } @@ -74,17 +77,31 @@ public extension Containerable { return object } else { + // There is no object with this protocol. (if it's really a protocol) Let's find out first class, conformable to protocol + + for service in services { + for object in service.value { + + let isConforms = (object.object as? TestClassProtocol) != nil || (object.registration() as? TestClassProtocol) != nil + if isConforms { + return resolveAny(typeString: service.key, name: name) + } + } + } + return nil } } - func resolve(name: String? = nil) -> T? { + func resolve(name: String? = nil, objectType: T.Type? = nil) -> T? { let key = String(describing: T.self) +// let protocolToResolve: Protocol? = objectType let object = resolveAny(typeString: key, name: name) as? T return object } + func finishRegistrations() { relations = [:] for object in recursiveNotResolvedObjects { @@ -119,7 +136,7 @@ public extension Containerable { } } - private func memmoryAddress(_ object: Object) -> String { + func memmoryAddress(_ object: Object) -> String { return "\(Unmanaged.passUnretained(object).toOpaque())" } @@ -176,10 +193,16 @@ public extension Containerable { let key = String(describing: type(of: object)) if let array = services[key] { var newArray = array - newArray.append(ContainerObject(registration, name: name, registrationType: registrationType)) + newArray.append(ContainerObject(registration, + name: name, + registrationType: registrationType, + objectType: T.self)) services[key] = newArray } else { - services[key] = [ContainerObject(registration, name: name, registrationType: registrationType)] + services[key] = [ContainerObject(registration, + name: name, + registrationType: registrationType, + objectType: T.self)] } dispatchRegistrationGroup.leave() } diff --git a/SwiftInjector/ProtocolTestClass.swift b/SwiftInjector/ProtocolTestClass.swift new file mode 100644 index 0000000..19d3529 --- /dev/null +++ b/SwiftInjector/ProtocolTestClass.swift @@ -0,0 +1,19 @@ +// +// ProtocolTestClass.swift +// SwiftInjector +// +// Created by Ghost on 11.07.2019. +// Copyright © 2019 Ghost. All rights reserved. +// + +import Foundation + +protocol TestClassProtocol { + +} + +class ProtocolTestClass: TestClassProtocol, Equatable { + static func == (lhs: ProtocolTestClass, rhs: ProtocolTestClass) -> Bool { + return "\(Unmanaged.passUnretained(lhs).toOpaque())" == "\(Unmanaged.passUnretained(rhs).toOpaque())" + } +} diff --git a/SwiftInjector/ProtocolViewController.swift b/SwiftInjector/ProtocolViewController.swift new file mode 100644 index 0000000..60113e2 --- /dev/null +++ b/SwiftInjector/ProtocolViewController.swift @@ -0,0 +1,13 @@ +// +// ViewControllerProtocolTests.swift +// SwiftInjector +// +// Created by Ghost on 11.07.2019. +// Copyright © 2019 Ghost. All rights reserved. +// + +import UIKit + +class ProtocolViewController: UIViewController { + var testClass: TestClassProtocol? +} diff --git a/SwiftInjector/TestClass.swift b/SwiftInjector/TestClass.swift index c76207f..131af41 100644 --- a/SwiftInjector/TestClass.swift +++ b/SwiftInjector/TestClass.swift @@ -16,3 +16,21 @@ class TestClass: Equatable { return "\(Unmanaged.passUnretained(lhs).toOpaque())" == "\(Unmanaged.passUnretained(rhs).toOpaque())" } } + + +//protocol TestClassable { +// +//} +// +//class VC1 { +// var testClassable: TestClassable? +//} +// +//class ProtocoledTestClass: TestClass { +// var name: String = "123" +// weak var viewController: TestClassable? +// +// static func == (lhs: TestClass, rhs: TestClass) -> Bool { +// return "\(Unmanaged.passUnretained(lhs).toOpaque())" == "\(Unmanaged.passUnretained(rhs).toOpaque())" +// } +//} diff --git a/SwiftInjectorTests/ContainerableProtocolTests.swift b/SwiftInjectorTests/ContainerableProtocolTests.swift new file mode 100644 index 0000000..7cf3411 --- /dev/null +++ b/SwiftInjectorTests/ContainerableProtocolTests.swift @@ -0,0 +1,33 @@ +// +// ContainerableProtocolTest.swift +// SwiftInjectorTests +// +// Created by Ghost on 10.07.2019. +// Copyright © 2019 Ghost. All rights reserved. +// + +import XCTest +@testable import SwiftInjector + +class ContainerableProtocolTests: XCTestCase { + + override func setUp() { + + } + + func testExampleProtocolInheritance() { + let containerable: Containerable = RootContainer() + containerable.register ({ ProtocolViewController() }) + containerable.register ({ ProtocolTestClass() }) + let vc: ProtocolViewController? = containerable.resolve() + XCTAssertNotNil(vc) + let testClass = containerable.resolve(objectType: TestClassProtocol.self) + + XCTAssertNotNil(testClass) + + XCTAssertNotNil(vc?.testClass) + XCTAssertEqual(containerable.memmoryAddress(vc?.testClass as AnyObject), containerable.memmoryAddress(testClass! as AnyObject)) + + } +} +