Compare commits

..

2 Commits

Author SHA1 Message Date
Ilya Puchka c3b601df0f Merge pull request #235 from AliSoftware/develop
Release 7.1.1
2019-12-27 11:36:42 +00:00
Ilya Puchka 07eb66e87d Merge pull request #231 from AliSoftware/develop
Release 7.1.0
2019-11-11 14:41:08 +00:00
20 changed files with 50 additions and 50 deletions
@@ -13,7 +13,7 @@ On the previous page you saw how auto-wiring helps us to get rid of boilerplate
Let's say you have following related components:
*/
protocol Service: AnyObject {
protocol Service: class {
var logger: Logger? { get }
var tracker: Tracker? { get }
}
@@ -101,11 +101,11 @@ serverWithNoClient.optionalClient.value
Another example of using auto-injection is circular dependencies. Let's say you have a `Server` and a `ServerClient` both referencing each other.
*/
protocol Server: AnyObject {
protocol Server: class {
weak var client: ServerClient? { get }
}
protocol ServerClient: AnyObject {
protocol ServerClient: class {
var server: Server? { get }
}
@@ -13,11 +13,11 @@ Very often we encounter situations when we have circular dependencies between co
Let's say you have some network client and it's delegate defined like this:
*/
protocol NetworkClientDelegate: AnyObject {
protocol NetworkClientDelegate: class {
var networkClient: NetworkClient { get }
}
protocol NetworkClient: AnyObject {
protocol NetworkClient: class {
weak var delegate: NetworkClientDelegate? { get set }
}
@@ -1,6 +1,6 @@
import Foundation
public protocol Service: AnyObject {}
public protocol Service: class {}
public class ServiceImp1: Service {
public init() {}
@@ -22,7 +22,7 @@ public class ServiceImp4: Service {
}
public protocol Client: AnyObject {
public protocol Client: class {
var service: Service {get}
init(service: Service)
}
@@ -74,9 +74,9 @@ public class DataProviderImp: DataProvider {
public init() {}
}
public protocol ListInteractorOutput: AnyObject {}
public protocol ListModuleInterface: AnyObject {}
public protocol ListInteractorInput: AnyObject {}
public protocol ListInteractorOutput: class {}
public protocol ListModuleInterface: class {}
public protocol ListInteractorInput: class {}
public class ListPresenter: NSObject {
public var listInteractor : ListInteractorInput?
public var listWireframe : ListWireframe?
@@ -96,8 +96,8 @@ public class ListWireframe : NSObject {
}
}
public protocol AddModuleDelegate: AnyObject {}
public protocol AddModuleInterface: AnyObject {}
public protocol AddModuleDelegate: class {}
public protocol AddModuleInterface: class {}
public class AddWireframe: NSObject {
let addPresenter : AddPresenter
public init(addPresenter: AddPresenter) {
@@ -8,7 +8,7 @@
import Foundation
///Provides Person entities fetching them with web service
///Provides Person entitis fetching them with web service
struct SWAPIPersonProvider : PersonProviderAPI {
let ws: NetworkLayer
@@ -8,7 +8,7 @@
import UIKit
protocol FetchableTrait: AnyObject {
protocol FetchableTrait: class {
associatedtype ObjectType
var objects: [ObjectType]? { get set }
var batchRequestID: Int { get set }
+2 -2
View File
@@ -237,7 +237,7 @@ public extension Injected {
For that reason if you resolve instance that has a _weak_ auto-injected property this property
will be released when `resolve` will complete.
Use `InjectedWeak<T>` to define one of two circular dependencies if another dependency is defined as `Injected<U>`.
Use `InjectedWeak<T>` to define one of two circular dependecies if another dependency is defined as `Injected<U>`.
This will prevent a retain cycle between resolved instances.
- warning: Do not define this property as optional or container will not be able to inject it.
@@ -299,7 +299,7 @@ public struct InjectedWeak<T>: _InjectedPropertyBox, AutoInjectedPropertyBox {
For that reason if you resolve instance that has a _weak_ auto-injected property this property
will be released when `resolve` will complete.
Use `InjectedWeak<T>` to define one of two circular dependencies if another dependency is defined as `Injected<U>`.
Use `InjectedWeak<T>` to define one of two circular dependecies if another dependency is defined as `Injected<U>`.
This will prevent a retain cycle between resolved instances.
- warning: Do not define this property as optional or container will not be able to inject it.
+5 -5
View File
@@ -61,7 +61,7 @@ public struct DefinitionKey: Hashable, CustomStringConvertible {
}
///Dummy protocol to store definitions for different types in collection
public protocol DefinitionType: AnyObject { }
public protocol DefinitionType: class { }
/**
`Definition<T, U>` describes how instances of type `T` should be created when this type is resolved by the `DependencyContainer`.
@@ -206,7 +206,7 @@ public final class Definition<T, U>: DefinitionType {
//definitions for types that can be resolved by `forwardsTo` definition
//can also be used to resolve self type and it's implementing types
//this way container properly reuses previously resolved instances
//this way container properly reuses previosly resolved instances
//when there are several forwarded definitions
//see testThatItReusesInstanceResolvedByTypeForwarding)
for definition in forwardsTo.forwardsFrom {
@@ -292,7 +292,7 @@ class DefinitionBuilder<T, U> {
typealias KeyDefinitionPair = (key: DefinitionKey, definition: _Definition)
/// Definitions are matched if they are registered for the same tag and their factories accept the same number of runtime arguments.
/// Definitions are matched if they are registered for the same tag and thier factories accept the same number of runtime arguments.
private func ~=(lhs: KeyDefinitionPair, rhs: KeyDefinitionPair) -> Bool {
guard lhs.key.type == rhs.key.type else { return false }
guard lhs.key.tag == rhs.key.tag else { return false }
@@ -300,9 +300,9 @@ private func ~=(lhs: KeyDefinitionPair, rhs: KeyDefinitionPair) -> Bool {
return true
}
/// Returns key-definition pairs with definitions able to resolve that type (directly or via type forwarding)
/// 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 if strictByTag is false.
/// In the end filters definitions by type of runtime arguments.
/// In the end filters defintions by type of runtime arguments.
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) })
+3 -3
View File
@@ -94,7 +94,7 @@ public final class DependencyContainer {
Call this method to complete container setup. After container is bootstrapped
you can not add or remove definitions. Trying to do so will cause runtime exception.
You can completely reset container, after reset you can bootstrap it again.
During bootstrap container will instantiate components registered with `EagerSingleton` scope.
During bootsrap container will instantiate components registered with `EagerSingleton` scope.
- throws: `DipError` if failed to instantiate any component
*/
@@ -298,7 +298,7 @@ extension DependencyContainer {
for collaborator in _collaborators {
//if container is already in a context resolving this type
//it means that it has been already called to resolve this type,
//so there is probably a circular reference between containers.
//so there is probably a cercular reference between containers.
//To break it skip this container
if let context = collaborator.context, context.resolvingType == key.type && context.tag == key.tag { continue }
@@ -453,7 +453,7 @@ extension DependencyContainer: CustomStringConvertible {
//MARK: - DependencyTagConvertible
/// Implement this protocol on your type if you want to use its instances as `DependencyContainer`'s tags.
/// `DependencyContainer.Tag`, `String`, `Int` and any `RawRepresentable` with `RawType` of `String` or `Int` by default conform to this protocol.
/// `DependencyContainer.Tag`, `String`, `Int` and any `RawRepresentable` with `RawType` of `String` or `Int` by default confrom to this protocol.
public protocol DependencyTagConvertible {
var dependencyTag: DependencyContainer.Tag { get }
}
+1 -1
View File
@@ -66,7 +66,7 @@ public enum DipError: Error, CustomStringConvertible {
case ambiguousDefinitions(type: Any.Type, definitions: [DefinitionType])
/**
Thrown by `resolve(tag:)` if resolved instance does not implement resolved type (i.e. when type-forwarding).
Thrown by `resolve(tag:)` if resolved instance does not implemenet resolved type (i.e. when type-forwarding).
- parameters:
- resolved: Resolved instance
+1 -1
View File
@@ -81,7 +81,7 @@ extension DependencyContainer {
- parameters:
- tag: The arbitrary tag to use to lookup definition.
- builder: Generic closure that accepts generic factory and returns instance created by that factory.
- builder: Generic closure that accepts generic factory and returns inctance created by that factory.
- throws: `DipError.DefinitionNotFound`, `DipError.AutoInjectionFailed`, `DipError.AmbiguousDefinitions`, `DipError.InvalidType`
+2 -2
View File
@@ -98,7 +98,7 @@ extension DependencyContainer {
}
```
Though before you do so you should probably review your design and try to reduce number of dependencies.
Though before you do so you should probably review your design and try to reduce number of depnedencies.
*/
public func register<T, U>(scope: ComponentScope, type: T.Type, tag: DependencyTagConvertible?, factory: @escaping (U) throws -> T, numberOfArguments: Int, autoWiringFactory: @escaping (DependencyContainer, Tag?) throws -> T) -> Definition<T, U> {
let definition = DefinitionBuilder<T, U> {
@@ -141,7 +141,7 @@ extension DependencyContainer {
which factories accept any number of runtime arguments and are tagged with the same tag,
passed to `resolve` method, or with no tag. Container will try to use these definitions
to resolve a component one by one until one of them succeeds, starting with tagged definitions
in order of decreasing their's factories number of arguments. If none of them succeeds it will
in order of decreasing their's factories number of arguments. If none of them succeds it will
throw an error. If it finds two definitions with the same number of arguments - it will throw
an error.
+3 -3
View File
@@ -25,12 +25,12 @@
import XCTest
@testable import Dip
private protocol Server: AnyObject {
private protocol Server: class {
var client: Client! {get}
var anotherClient: Client! {get set}
}
private protocol Client: AnyObject {
private protocol Client: class {
var server: Server? {get}
var anotherServer: Server! {get set}
}
@@ -488,7 +488,7 @@ class AutoInjectionTests: XCTestCase {
XCTAssertNil(server)
}
func testThatItAutoInjectsWhenOverriddenInDefinition() {
func testThatItAutoInjectsWhenOverridenInDefinition() {
let container = DependencyContainer(autoInjectProperties: false)
container.register { ServerImp() as Server }
container.register { ClientImp() as Client }
+2 -2
View File
@@ -25,12 +25,12 @@
import XCTest
@testable import Dip
private protocol Service: AnyObject { }
private protocol Service: class { }
private class ServiceImp1: Service { }
private class ServiceImp2: Service { }
private class ServiceImp3 {}
private protocol AutoWiredClient: AnyObject {
private protocol AutoWiredClient: class {
var service1: Service! { get set }
var service2: Service! { get set }
}
+2 -2
View File
@@ -25,7 +25,7 @@
import XCTest
@testable import Dip
private protocol Service: AnyObject {}
private protocol Service: class {}
private class ServiceImp1: Service {}
private class ServiceImp2: Service {}
@@ -316,7 +316,7 @@ class ComponentScopeTests: XCTestCase {
container.register(service, type: Service.self)
//when
//resolve and release right away
//resolve and realease reight away
_ = try? container.resolve() as ServiceImp1
//then
+1 -1
View File
@@ -100,7 +100,7 @@ class DefinitionTests: XCTestCase {
XCTAssertFalse(blockCalled)
}
func testThatItRegistersOptionalTypesAsForwardedTypes() {
func testThatItRegisteresOptionalTypesAsForwardedTypes() {
let def = Definition<Service, ()>(scope: .unique) { ServiceImp() as Service }
XCTAssertTrue(def.implementingTypes.contains(where: { $0 == Service?.self }))
+3 -3
View File
@@ -25,14 +25,14 @@
import XCTest
@testable import Dip
private protocol Service: AnyObject { }
private protocol Service: class { }
private class ServiceImp1: Service { }
private class ServiceImp2: Service { }
private protocol Server: AnyObject {
private protocol Server: class {
var client: Client! { get }
}
private protocol Client: AnyObject {
private protocol Client: class {
var server: Server! { get }
}
+5 -5
View File
@@ -164,10 +164,10 @@ class DipUITests: XCTestCase {
}
}
protocol SomeService: AnyObject {
protocol SomeService: class {
var delegate: SomeServiceDelegate? { get set }
}
protocol SomeServiceDelegate: AnyObject { }
protocol SomeServiceDelegate: class { }
class SomeServiceImp: SomeService {
weak var delegate: SomeServiceDelegate?
init(delegate: SomeServiceDelegate) {
@@ -176,10 +176,10 @@ class SomeServiceImp: SomeService {
init(){}
}
protocol OtherService: AnyObject {
protocol OtherService: class {
var delegate: OtherServiceDelegate? { get set }
}
protocol OtherServiceDelegate: AnyObject {}
protocol OtherServiceDelegate: class {}
class OtherServiceImp: OtherService {
weak var delegate: OtherServiceDelegate?
init(delegate: OtherServiceDelegate){
@@ -189,7 +189,7 @@ class OtherServiceImp: OtherService {
}
protocol SomeScreen: AnyObject {
protocol SomeScreen: class {
var someService: SomeService? { get set }
var otherService: OtherService? { get set }
}
+1 -1
View File
@@ -268,7 +268,7 @@ class RuntimeArgumentsTests: XCTestCase {
//Due to incomplete implementation of SE-0054 (bug: https://bugs.swift.org/browse/SR-2143)
//registering definition with T? and T! arguments types will produce two different definitions
//but when argument of T! will be passed to `resolve` method it will be transformed to T?
//but when argement of T! will be passed to `resolve` method it will be transformed to T?
//and wrong definition will be used
//When fixed using T? and T! should not register two different definitions
+2 -2
View File
@@ -26,11 +26,11 @@
import XCTest
@testable import Dip
private protocol Server: AnyObject {
private protocol Server: class {
var client: Client! { get set }
}
private protocol Client: AnyObject {
private protocol Client: class {
var server: Server { get }
}
+3 -3
View File
@@ -25,8 +25,8 @@
import XCTest
@testable import Dip
private protocol Service: AnyObject { }
private protocol ForwardedType: AnyObject { }
private protocol Service: class { }
private protocol ForwardedType: class { }
#if os(Linux)
private class ServiceImp1: Service, ForwardedType { }
private class ServiceImp2: Service, ForwardedType { }
@@ -136,7 +136,7 @@ class TypeForwardingTests: XCTestCase {
resolveDependenciesCalled = true
//when
//resolving via type-forwarding for tag different then tag for original definition
//resolving via type-forawrding for tag different then tag for original definition
let forwardType = try container.resolve(tag: "tag") as ForwardedType
let anyForwardType = try container.resolve(ForwardedType.self, tag: "tag") as! ForwardedType