diff --git a/CHANGELOG.md b/CHANGELOG.md index ae22ac9..88972e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ #### New Features -* Added support for circular dependencies by adding `ObjectGraph` scope to reuse resolved instances. +* Added support for circular dependencies: + * Added `ObjectGraph` scope to reuse resolved instances + * Added `resolveDependencies` method on `DefinitionOf` class to resolve dependencies of resolved instance. [#11](https://github.com/AliSoftware/Dip/pull/11), [@ilyapuchka](https://github.com/ilyapuchka) * Added methods to register/remove individual definitions. [#11](https://github.com/AliSoftware/Dip/pull/11), [@ilyapuchka](https://github.com/ilyapuchka) @@ -14,6 +16,7 @@ * Removed container thread-safety to enable recursion calls to `resolve`. **Access to container from multiple threads should be handled by clients** from now on. * Deprecated `register(tag:instance:)` method in favor of `register(.Singleton, …)`. +* Added name for the first runtime argument in `resolve(tag:withArguments:)` methods to make more clear separation between tag and factory runtime arguments. ## 3.0.0 diff --git a/Dip/Dip/RuntimeArguments.swift b/Dip/Dip/RuntimeArguments.swift index 17519f1..f9e0660 100644 --- a/Dip/Dip/RuntimeArguments.swift +++ b/Dip/Dip/RuntimeArguments.swift @@ -56,6 +56,12 @@ extension DependencyContainer { - seealso: `resolve(tag:builder:)` */ + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1) -> T { + return resolve(tag: tag) { (factory: (Arg1) -> T) in factory(arg1) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1) -> T { return resolve(tag: tag) { (factory: (Arg1) -> T) in factory(arg1) } } @@ -68,6 +74,12 @@ extension DependencyContainer { } /// - seealso: `resolve(tag:_:)` + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2) -> T { + return resolve(tag: tag) { (factory: (Arg1, Arg2) -> T) in factory(arg1, arg2) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:_:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:_:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2) -> T { return resolve(tag: tag) { (factory: (Arg1, Arg2) -> T) in factory(arg1, arg2) } } @@ -78,7 +90,13 @@ extension DependencyContainer { return registerFactory(tag: tag, scope: scope, factory: factory) as DefinitionOf T> } - /// - seealso: `resolve(tag:_:)` + /// - seealso: `resolve(tag:withArguments:)` + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3) -> T { + return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3) -> T) in factory(arg1, arg2, arg3) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:_:_:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:_:_:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3) -> T { return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3) -> T) in factory(arg1, arg2, arg3) } } @@ -89,29 +107,47 @@ extension DependencyContainer { return registerFactory(tag: tag, scope: scope, factory: factory) as DefinitionOf T> } - /// - seealso: `resolve(tag:_:)` + /// - seealso: `resolve(tag:withArguments:)` + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4) -> T { + return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4) -> T) in factory(arg1, arg2, arg3, arg4) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:_:_:_:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:_:_:_:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4) -> T { return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4) -> T) in factory(arg1, arg2, arg3, arg4) } } - // MARK: 4 Runtime Arguments + // MARK: 5 Runtime Arguments public func register(tag tag: Tag? = nil, _ scope: ComponentScope = .Prototype, factory: (Arg1, Arg2, Arg3, Arg4, Arg5) -> T) -> DefinitionOf T> { return registerFactory(tag: tag, scope: scope, factory: factory) as DefinitionOf T> } - /// - seealso: `resolve(tag:_:)` + /// - seealso: `resolve(tag:withArguments:)` + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5) -> T { + return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4, Arg5) -> T) in factory(arg1, arg2, arg3, arg4, arg5) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:_:_:_:_:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:_:_:_:_:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5) -> T { return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4, Arg5) -> T) in factory(arg1, arg2, arg3, arg4, arg5) } } - // MARK: 5 Runtime Arguments + // MARK: 6 Runtime Arguments public func register(tag tag: Tag? = nil, _ scope: ComponentScope = .Prototype, factory: (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> T) -> DefinitionOf T> { return registerFactory(tag: tag, scope: scope, factory: factory) as DefinitionOf T> } - /// - seealso: `resolve(tag:_:)` + /// - seealso: `resolve(tag:withArguments:)` + public func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6) -> T { + return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> T) in factory(arg1, arg2, arg3, arg4, arg5, arg6) } + } + + ///**Deprecated** Use `resolve(tag:withArguments:_:_:_:_:_:)` method instead. + @available(*, deprecated, message="Use `resolve(tag:withArguments:_:_:_:_:_:)` method instead.") public func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6) -> T { return resolve(tag: tag) { (factory: (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> T) in factory(arg1, arg2, arg3, arg4, arg5, arg6) } } diff --git a/Dip/DipTests/RuntimeArgumentsTests.swift b/Dip/DipTests/RuntimeArgumentsTests.swift index e92d55b..7aeefcd 100644 --- a/Dip/DipTests/RuntimeArgumentsTests.swift +++ b/Dip/DipTests/RuntimeArgumentsTests.swift @@ -56,7 +56,7 @@ class RuntimeArgumentsTests: XCTestCase { }) //when - let service = container.resolve(arg1) as Service + let service = container.resolve(withArguments: arg1) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -72,7 +72,7 @@ class RuntimeArgumentsTests: XCTestCase { } //when - let service = container.resolve(arg1, arg2) as Service + let service = container.resolve(withArguments: arg1, arg2) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -88,7 +88,7 @@ class RuntimeArgumentsTests: XCTestCase { } //when - let service = container.resolve(arg1, arg2, arg3) as Service + let service = container.resolve(withArguments: arg1, arg2, arg3) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -105,7 +105,7 @@ class RuntimeArgumentsTests: XCTestCase { } //when - let service = container.resolve(arg1, arg2, arg3, arg4) as Service + let service = container.resolve(withArguments: arg1, arg2, arg3, arg4) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -123,7 +123,7 @@ class RuntimeArgumentsTests: XCTestCase { } //when - let service = container.resolve(arg1, arg2, arg3, arg4, arg5) as Service + let service = container.resolve(withArguments: arg1, arg2, arg3, arg4, arg5) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -142,7 +142,7 @@ class RuntimeArgumentsTests: XCTestCase { } //when - let service = container.resolve(arg1, arg2, arg3, arg4, arg5, arg6) as Service + let service = container.resolve(withArguments: arg1, arg2, arg3, arg4, arg5, arg6) as Service //then XCTAssertTrue(service is ServiceImp1) @@ -155,8 +155,8 @@ class RuntimeArgumentsTests: XCTestCase { container.register { (a1: Int, a2: Int) in ServiceImp2() as Service } //when - let service1 = container.resolve(arg1) as Service - let service2 = container.resolve(arg1, arg2) as Service + let service1 = container.resolve(withArguments: arg1) as Service + let service2 = container.resolve(withArguments: arg1, arg2) as Service //then XCTAssertTrue(service1 is ServiceImp1) @@ -170,8 +170,8 @@ class RuntimeArgumentsTests: XCTestCase { container.register(factory: { (a1: String) in ServiceImp2() as Service }) //when - let service1 = container.resolve(arg1) as Service - let service2 = container.resolve(arg2) as Service + let service1 = container.resolve(withArguments: arg1) as Service + let service2 = container.resolve(withArguments: arg2) as Service //then XCTAssertTrue(service1 is ServiceImp1) @@ -185,8 +185,8 @@ class RuntimeArgumentsTests: XCTestCase { container.register { (a1: String, a2: Int) in ServiceImp2() as Service } //when - let service1 = container.resolve(arg1, arg2) as Service - let service2 = container.resolve(arg2, arg1) as Service + let service1 = container.resolve(withArguments: arg1, arg2) as Service + let service2 = container.resolve(withArguments: arg2, arg1) as Service //then XCTAssertTrue(service1 is ServiceImp1) @@ -197,11 +197,11 @@ class RuntimeArgumentsTests: XCTestCase { //given let arg1 = 1, arg2 = 2 container.register { (a1: Int, a2: Int) in ServiceImp1() as Service } - let service1 = container.resolve(arg1, arg2) as Service + let service1 = container.resolve(withArguments: arg1, arg2) as Service //when container.register { (a1: Int, a2: Int) in ServiceImp2() as Service } - let service2 = container.resolve(arg1, arg2) as Service + let service2 = container.resolve(withArguments: arg1, arg2) as Service //then XCTAssertTrue(service1 is ServiceImp1) @@ -217,11 +217,11 @@ class RuntimeArgumentsTests: XCTestCase { //when let url: NSURL = NSURL(string: "http://example.com")! - let service1 = container.resolve(80, url) as Service - let service2 = container.resolve(80, NSURL(string: "http://example.com")) as Service + let service1 = container.resolve(withArguments: 80, url) as Service + let service2 = container.resolve(withArguments: 80, NSURL(string: "http://example.com")) as Service - let service3 = container.resolve(80, NSURL(string: "http://example.com")! as NSURL!) as Service - let service4 = container.resolve(80, NSURL(string: "http://example.com")!) as Service + let service3 = container.resolve(withArguments: 80, NSURL(string: "http://example.com")! as NSURL!) as Service + let service4 = container.resolve(withArguments: 80, NSURL(string: "http://example.com")!) as Service //then XCTAssertEqual(service1.getServiceName(), name1) diff --git a/DipPlayground.playground/Pages/Runtime arguments.xcplaygroundpage/Contents.swift b/DipPlayground.playground/Pages/Runtime arguments.xcplaygroundpage/Contents.swift index e9801e1..017c770 100644 --- a/DipPlayground.playground/Pages/Runtime arguments.xcplaygroundpage/Contents.swift +++ b/DipPlayground.playground/Pages/Runtime arguments.xcplaygroundpage/Contents.swift @@ -18,10 +18,10 @@ container.register { (port: Int, url: NSURL?) in ServiceImp4(name: "3", baseURL: container.register { (port: Int, url: NSURL!) in ServiceImp4(name: "4", baseURL: url, port: port) as Service } let url: NSURL = NSURL(string: "http://example.com")! -let service1 = container.resolve(url, 80) as Service -let service2 = container.resolve(80, url) as Service -let service3 = container.resolve(80, NSURL(string: "http://example.com")) as Service -let service4 = container.resolve(80, NSURL(string: "http://example.com")! as NSURL!) as Service +let service1 = container.resolve(withArguments: url, 80) as Service +let service2 = container.resolve(withArguments: 80, url) as Service +let service3 = container.resolve(withArguments: 80, NSURL(string: "http://example.com")) as Service +let service4 = container.resolve(withArguments: 80, NSURL(string: "http://example.com")! as NSURL!) as Service (service1 as! ServiceImp4).name (service2 as! ServiceImp4).name diff --git a/README.md b/README.md index 3520f63..f1aff0c 100644 --- a/README.md +++ b/README.md @@ -144,9 +144,9 @@ let webServices = DependencyContainer() { webServices in webServices.register { (port: Int, url: NSURL?) in WebServiceImp3(url!, port: port) as WebServiceAPI } } -let service1 = webServices.resolve(NSURL(string: "http://example.url")!, 80) as WebServiceAPI // service1 is WebServiceImp1 -let service2 = webServices.resolve(80, NSURL(string: "http://example.url")!) as WebServiceAPI // service2 is WebServiceImp2 -let service3 = webServices.resolve(80, NSURL(string: "http://example.url")) as WebServiceAPI // service3 is WebServiceImp3 +let service1 = webServices.resolve(withArguments: NSURL(string: "http://example.url")!, 80) as WebServiceAPI // service1 is WebServiceImp1 +let service2 = webServices.resolve(withArguments: 80, NSURL(string: "http://example.url")!) as WebServiceAPI // service2 is WebServiceImp2 +let service3 = webServices.resolve(withArguments: 80, NSURL(string: "http://example.url")) as WebServiceAPI // service3 is WebServiceImp3 ``` Though Dip provides support for up to six runtime arguments out of the box you can extend this number using following code snippet for seven arguments: @@ -156,7 +156,7 @@ func register(tag: Tag? = nil, scop return registerFactory(tag, scope: .Prototype, factory: factory) as DefinitionOf T)> } -func resolve(tag tag: Tag? = nil, _ arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6, _ arg7: Arg7) -> T { +func resolve(tag tag: Tag? = nil, withArguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6, _ arg7: Arg7) -> T { return resolve(tag) { (factory: (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> T) in factory(arg1, arg2, arg3, arg4, arg5, arg6, arg7) } }