Skip to content

Commit

Permalink
Merge pull request #154 from AliSoftware/auto-wiring-tag-fix
Browse files Browse the repository at this point in the history
Fixed auto-wiring with tagged definitions
  • Loading branch information
ilyapuchka authored Apr 9, 2017
2 parents 3b943c1 + 218b5a4 commit 9b2a791
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ matrix:
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.1' ONLY_ACTIVE_ARCH=NO | xcpretty -c
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk macosx -destination 'platform=macOS,arch=x86_64' ONLY_ACTIVE_ARCH=NO | xcpretty -c
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV 1080p,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
- set -o pipefail && xcodebuild -workspace Dip.xcworkspace -scheme Dip -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty - c
# disable running watchos until https://github.com/travis-ci/travis-ci/issues/7580 is fixed
#- set -o pipefail && xcodebuild -workspace Dip.xcworkspace -scheme Dip -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty - c
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme DipSampleApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.1' ONLY_ACTIVE_ARCH=NO | xcpretty -c
- pod spec lint --allow-warnings
- carthage build --no-skip-current
Expand Down
19 changes: 12 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

## 5.1

* Fixed Swift 3.1 warnings
[#145](https://github.com/AliSoftware/Dip/issues/145), [@DenHeadless](https://github.com/DenHeadless)
* Dropped Swift 2.3 support
* Dropped Swift 2.3 support.
[#150](https://github.com/AliSoftware/Dip/issues/150), [@ilyapuchka](https://github.com/ilyapuchka)
* Fixed collaboration shared references
[#151](https://github.com/AliSoftware/Dip/issues/151), [@ilyapuchka](https://github.com/ilyapuchka)
* Added custom logging function.
* Added custom logging function.
[#146](https://github.com/AliSoftware/Dip/issues/146), [@Pr0Ger](https://github.com/Pr0Ger)

#### Fixed

* Fixed Swift 3.1 warnings.
[#145](https://github.com/AliSoftware/Dip/issues/145), [@DenHeadless](https://github.com/DenHeadless)
* Fixed collaboration shared references.
[#151](https://github.com/AliSoftware/Dip/issues/151), [@ilyapuchka](https://github.com/ilyapuchka)
* Fixed autowiring when using tags.
[#154](https://github.com/AliSoftware/Dip/issues/154), [@ilyapuchka](https://github.com/ilyapuchka)

## 5.0.4

#### Fixed

* Fixed broken compatibility for Swift 2.3 API in `resolve(tag:arguments:)` method.
* Fixed broken compatibility for Swift 2.3 API in `resolve(tag:arguments:)` method.
[#135](https://github.com/AliSoftware/Dip/issues/135), [@ilyapuchka](https://github.com/ilyapuchka)

## 5.0.3
Expand Down
19 changes: 15 additions & 4 deletions Sources/AutoWiring.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,30 @@ extension DependencyContainer {
}

private func autoWiringDefinition(byKey key: DefinitionKey) throws -> KeyDefinitionPair {
do {
return try autoWiringDefinition(byKey: key, strictByTag: true)
} catch {
if key.tag != nil {
return try autoWiringDefinition(byKey: key, strictByTag: false)
} else {
throw error
}
}
}

private func autoWiringDefinition(byKey key: DefinitionKey, strictByTag: Bool) throws -> KeyDefinitionPair {
var definitions = self.definitions.map({ (key: $0.0, definition: $0.1) })

definitions = filter(definitions: definitions, byKey: key)
definitions = filter(definitions: definitions, byKey: key, strictByTag: strictByTag)
definitions = definitions.sorted(by: { $0.definition.numberOfArguments > $1.definition.numberOfArguments })

guard definitions.count > 0 && definitions[0].definition.numberOfArguments > 0 else {
throw DipError.definitionNotFound(key: key)
}

let maximumNumberOfArguments = definitions.first?.definition.numberOfArguments
definitions = definitions.filter({ $0.definition.numberOfArguments == maximumNumberOfArguments })
definitions = order(definitions: definitions, byTag: key.tag)


//when there are several definitions with the same number of arguments but different arguments types
if definitions.count > 1 && definitions[0].key.typeOfArguments != definitions[1].key.typeOfArguments {
let error = DipError.ambiguousDefinitions(type: key.type, definitions: definitions.map({ $0.definition }))
Expand Down
6 changes: 3 additions & 3 deletions Sources/Definition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,12 @@ private func ~=(lhs: KeyDefinitionPair, rhs: KeyDefinitionPair) -> Bool {
}

/// Returns key-defintion pairs with definitions able to resolve that type (directly or via type forwarding)
/// and which tag matches provided key's tag or is nil.
/// and which tag matches provided key's tag or is nil if strictByTag is false.
/// In the end filters defintions by type of runtime arguments.
func filter(definitions _definitions: [KeyDefinitionPair], byKey key: DefinitionKey, byTypeOfArguments: Bool = false) -> [KeyDefinitionPair] {
func filter(definitions _definitions: [KeyDefinitionPair], byKey key: DefinitionKey, strictByTag: Bool = false, byTypeOfArguments: Bool = false) -> [KeyDefinitionPair] {
let definitions = _definitions
.filter({ $0.key.type == key.type || $0.definition.doesImplements(type: key.type) })
.filter({ $0.key.tag == key.tag || $0.key.tag == nil })
.filter({ $0.key.tag == key.tag || (!strictByTag && $0.key.tag == nil) })
if byTypeOfArguments {
return definitions.filter({ $0.key.typeOfArguments == key.typeOfArguments })
}
Expand Down
31 changes: 29 additions & 2 deletions Tests/DipTests/AutoWiringTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class AutoWiringTests: XCTestCase {
("testThatItCanResolveWithAutoWiring", testThatItCanResolveWithAutoWiring),
("testThatItUsesAutoWireFactoryWithMostNumberOfArguments", testThatItUsesAutoWireFactoryWithMostNumberOfArguments),
("testThatItThrowsAmbiguityErrorWhenUsingAutoWire", testThatItThrowsAmbiguityErrorWhenUsingAutoWire),
("testThatItFirstTriesToUseTaggedFactoriesWhenUsingAutoWire", testThatItFirstTriesToUseTaggedFactoriesWhenUsingAutoWire),
("testThatItUsesAutoWireFactoryWithMostNumberOfArguments", testThatItUsesAutoWireFactoryWithMostNumberOfArguments),
("testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire),
("testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire),
("testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire", testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire),
("testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments", testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments),
("testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency", testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency),
Expand Down Expand Up @@ -146,7 +148,7 @@ class AutoWiringTests: XCTestCase {
}
}

func testThatItFirstTriesToUseTaggedFactoriesWhenUsingAutoWire() {
func testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire() {
//given

//1 arg
Expand Down Expand Up @@ -176,6 +178,31 @@ class AutoWiringTests: XCTestCase {
XCTAssertTrue(taggedFactoryWithMostNumberOfArgumentsCalled)
}

func testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire() {
//given

//1 arg
container.register { AutoWiredClientImp(service1: $0, service2: try self.container.resolve()) as AutoWiredClient }

//2 args
container.register { AutoWiredClientImp(service1: $0, service2: $1) as AutoWiredClient }

//1 arg tagged
var taggedFactoryCalled = false
container.register(tag: "tag") { AutoWiredClientImp(service1: try self.container.resolve(), service2: $0) as AutoWiredClient }.resolvingProperties { _ in
taggedFactoryCalled = true
}

container.register() { ServiceImp1() as Service }
container.register { ServiceImp2() }

//when
let _ = try! container.resolve(tag: "tag") as AutoWiredClient

//then
XCTAssertTrue(taggedFactoryCalled)
}

func testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire() {
//given

Expand Down

0 comments on commit 9b2a791

Please sign in to comment.