diff --git a/CHANGELOG.md b/CHANGELOG.md index faf23f19..ac36a673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v4.3.0 +Warning! This version change public API! +* Update arguments. Now inject arguments it's thread save operation. Also change syntax - remove extensions, and now inject arguments use resolve method in container. [see](Documentation/ru/core/modificated_injection.md#Аргумент) https://github.com/ivlevAstef/DITranquillity/issues/159 + # v4.2.3 * Fix potential crash into FastLock. For more information saw: https://github.com/ivlevAstef/SwiftLazy/issues/6 diff --git a/DITranquillity.podspec b/DITranquillity.podspec index 882ed753..7fd0d8f5 100644 --- a/DITranquillity.podspec +++ b/DITranquillity.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'DITranquillity' - s.version = '4.2.3' + s.version = '4.3.0' s.summary = 'DITranquillity - Dependency injection for iOS/macOS/tvOS (Swift) ' s.description = <<-DESC diff --git a/DITranquillity.xcodeproj/project.pbxproj b/DITranquillity.xcodeproj/project.pbxproj index c1f95c58..c22cc4f2 100644 --- a/DITranquillity.xcodeproj/project.pbxproj +++ b/DITranquillity.xcodeproj/project.pbxproj @@ -47,6 +47,10 @@ AB4F30F42503BD2100E74FB7 /* DIComponentPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F30F22503BD2100E74FB7 /* DIComponentPriority.swift */; }; AB4F30F52503BD2100E74FB7 /* DIComponentPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F30F22503BD2100E74FB7 /* DIComponentPriority.swift */; }; AB4F30F62503BD2100E74FB7 /* DIComponentPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F30F22503BD2100E74FB7 /* DIComponentPriority.swift */; }; + AB4F47A72670C98700EB5BF4 /* AnyArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */; }; + AB4F47A82670C98700EB5BF4 /* AnyArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */; }; + AB4F47A92670C98700EB5BF4 /* AnyArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */; }; + AB4F47AA2670C98700EB5BF4 /* AnyArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */; }; ABBE383D25FDE60F00DAFB62 /* ThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBE383C25FDE60F00DAFB62 /* ThreadDictionary.swift */; }; ABBE383E25FDE60F00DAFB62 /* ThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBE383C25FDE60F00DAFB62 /* ThreadDictionary.swift */; }; ABBE383F25FDE60F00DAFB62 /* ThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBE383C25FDE60F00DAFB62 /* ThreadDictionary.swift */; }; @@ -65,7 +69,6 @@ ABDA28A723ABBECD00BEB63F /* DIComponentBuilder+EmptySubviewsInject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EBF23AA75AC00DEA34A /* DIComponentBuilder+EmptySubviewsInject.swift */; }; ABDA28A823ABBECD00BEB63F /* Modificators.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EC523AA75AC00DEA34A /* Modificators.swift */; }; ABDA28AA23ABBECD00BEB63F /* DIPart.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60ECD23AA75AC00DEA34A /* DIPart.swift */; }; - ABDA28AB23ABBECD00BEB63F /* DIContainer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */; }; ABDA28AC23ABBECD00BEB63F /* TypeKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EBA23AA75AC00DEA34A /* TypeKey.swift */; }; ABDA28AD23ABBECD00BEB63F /* MethodMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EC323AA75AC00DEA34A /* MethodMaker.swift */; }; ABDA28AE23ABBECD00BEB63F /* FrameworksDependenciesContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EC823AA75AC00DEA34A /* FrameworksDependenciesContainer.swift */; }; @@ -173,9 +176,6 @@ ABE60F3B23AA75AC00DEA34A /* DIStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDC23AA75AC00DEA34A /* DIStorage.swift */; }; ABE60F3C23AA75AC00DEA34A /* DIStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDC23AA75AC00DEA34A /* DIStorage.swift */; }; ABE60F3D23AA75AC00DEA34A /* DIStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDC23AA75AC00DEA34A /* DIStorage.swift */; }; - ABE60F3E23AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */; }; - ABE60F3F23AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */; }; - ABE60F4023AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */; }; ABE60F5D23AA75B300DEA34A /* DIStoryboardBase.h in Headers */ = {isa = PBXBuildFile; fileRef = ABE60F4423AA75B300DEA34A /* DIStoryboardBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; ABE60F6023AA75B300DEA34A /* DIStoryboardBase.m in Sources */ = {isa = PBXBuildFile; fileRef = ABE60F4523AA75B300DEA34A /* DIStoryboardBase.m */; }; ABE60F6323AA75B300DEA34A /* NSStoryboard+Swizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = ABE60F4623AA75B300DEA34A /* NSStoryboard+Swizzling.m */; }; @@ -291,6 +291,7 @@ 16FADF3F24A701F7007BF1C1 /* Documentation */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Documentation; sourceTree = ""; }; A58875541D0944AE00D6DE92 /* DITranquillity.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DITranquillity.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AB4F30F22503BD2100E74FB7 /* DIComponentPriority.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DIComponentPriority.swift; sourceTree = ""; }; + AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyArguments.swift; sourceTree = ""; }; ABBE383C25FDE60F00DAFB62 /* ThreadDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadDictionary.swift; sourceTree = ""; }; ABDA28D323ABBECD00BEB63F /* DITranquillity.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DITranquillity.framework; sourceTree = BUILT_PRODUCTS_DIR; }; ABDA28EB23ABE13500BEB63F /* FastLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FastLock.swift; sourceTree = ""; }; @@ -325,7 +326,6 @@ ABE60EDA23AA75AC00DEA34A /* DITypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DITypes.swift; sourceTree = ""; }; ABE60EDB23AA75AC00DEA34A /* DIContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DIContainer.swift; sourceTree = ""; }; ABE60EDC23AA75AC00DEA34A /* DIStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DIStorage.swift; sourceTree = ""; }; - ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DIContainer+Extensions.swift"; sourceTree = ""; }; ABE60F4423AA75B300DEA34A /* DIStoryboardBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DIStoryboardBase.h; sourceTree = ""; }; ABE60F4523AA75B300DEA34A /* DIStoryboardBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DIStoryboardBase.m; sourceTree = ""; }; ABE60F4623AA75B300DEA34A /* NSStoryboard+Swizzling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSStoryboard+Swizzling.m"; sourceTree = ""; }; @@ -505,6 +505,7 @@ ABE60EC623AA75AC00DEA34A /* SpecificType.swift */, ABE60EC723AA75AC00DEA34A /* Component.swift */, ABE60EC823AA75AC00DEA34A /* FrameworksDependenciesContainer.swift */, + AB4F47A62670C98700EB5BF4 /* AnyArguments.swift */, ); path = Internal; sourceTree = ""; @@ -524,7 +525,6 @@ ABE60EDA23AA75AC00DEA34A /* DITypes.swift */, ABE60EDB23AA75AC00DEA34A /* DIContainer.swift */, ABE60EDC23AA75AC00DEA34A /* DIStorage.swift */, - ABE60EDD23AA75AC00DEA34A /* DIContainer+Extensions.swift */, 16ABEC1124B37D1F007577CF /* ComponentAlternativeType.swift */, ); path = API; @@ -946,6 +946,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AB4F47A82670C98700EB5BF4 /* AnyArguments.swift in Sources */, ABE60F3C23AA75AC00DEA34A /* DIStorage.swift in Sources */, 160F0EB724AB06F400723F28 /* DIGraph.swift in Sources */, 16ABEC1D24B37F49007577CF /* DIEdge.swift in Sources */, @@ -966,7 +967,6 @@ AB4F30F42503BD2100E74FB7 /* DIComponentPriority.swift in Sources */, ABE60F6623AA75B300DEA34A /* DIStoryboard.swift in Sources */, ABE60F1523AA75AC00DEA34A /* DIPart.swift in Sources */, - ABE60F3F23AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */, ABE60EE223AA75AC00DEA34A /* TypeKey.swift in Sources */, 1661095724AF18DB009603BF /* DIGraph+ValidationErrors.swift in Sources */, ABE60EFD23AA75AC00DEA34A /* MethodMaker.swift in Sources */, @@ -1012,6 +1012,7 @@ ABE60F3723AA75AC00DEA34A /* DITypes.swift in Sources */, ABE60EE923AA75AC00DEA34A /* ProtocolMagic.swift in Sources */, 16ABEC1E24B37F49007577CF /* DIEdge.swift in Sources */, + AB4F47A92670C98700EB5BF4 /* AnyArguments.swift in Sources */, ABE60EEC23AA75AC00DEA34A /* Log.swift in Sources */, ABE60EF523AA75AC00DEA34A /* Resolver.swift in Sources */, ABE60F1923AA75AC00DEA34A /* DISettings.swift in Sources */, @@ -1021,7 +1022,6 @@ ABE60F0423AA75AC00DEA34A /* Modificators.swift in Sources */, ABE60F6723AA75B300DEA34A /* DIStoryboard.swift in Sources */, ABE60F1623AA75AC00DEA34A /* DIPart.swift in Sources */, - ABE60F4023AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */, ABE60EE323AA75AC00DEA34A /* TypeKey.swift in Sources */, 16ABEC1424B37D1F007577CF /* ComponentAlternativeType.swift in Sources */, ABE60EFE23AA75AC00DEA34A /* MethodMaker.swift in Sources */, @@ -1073,6 +1073,7 @@ ABE60F3523AA75AC00DEA34A /* DITypes.swift in Sources */, ABE60EE723AA75AC00DEA34A /* ProtocolMagic.swift in Sources */, 16ABEC1C24B37F49007577CF /* DIEdge.swift in Sources */, + AB4F47A72670C98700EB5BF4 /* AnyArguments.swift in Sources */, ABE60EEA23AA75AC00DEA34A /* Log.swift in Sources */, ABE60EF323AA75AC00DEA34A /* Resolver.swift in Sources */, ABE60F1723AA75AC00DEA34A /* DISettings.swift in Sources */, @@ -1082,7 +1083,6 @@ ABE60F0223AA75AC00DEA34A /* Modificators.swift in Sources */, ABE60F6523AA75B300DEA34A /* DIStoryboard.swift in Sources */, ABE60F1423AA75AC00DEA34A /* DIPart.swift in Sources */, - ABE60F3E23AA75AC00DEA34A /* DIContainer+Extensions.swift in Sources */, ABE60EE123AA75AC00DEA34A /* TypeKey.swift in Sources */, 16ABEC1224B37D1F007577CF /* ComponentAlternativeType.swift in Sources */, ABE60EFC23AA75AC00DEA34A /* MethodMaker.swift in Sources */, @@ -1134,6 +1134,7 @@ 1661095924AF18DB009603BF /* DIGraph+ValidationErrors.swift in Sources */, ABDA28A023ABBECD00BEB63F /* SpecificType.swift in Sources */, ABDA28A123ABBECD00BEB63F /* DITypes.swift in Sources */, + AB4F47AA2670C98700EB5BF4 /* AnyArguments.swift in Sources */, ABDA28A223ABBECD00BEB63F /* ProtocolMagic.swift in Sources */, ABDA28A323ABBECD00BEB63F /* Log.swift in Sources */, ABDA28A423ABBECD00BEB63F /* Resolver.swift in Sources */, @@ -1143,7 +1144,6 @@ ABDA28A723ABBECD00BEB63F /* DIComponentBuilder+EmptySubviewsInject.swift in Sources */, ABDA28A823ABBECD00BEB63F /* Modificators.swift in Sources */, ABDA28AA23ABBECD00BEB63F /* DIPart.swift in Sources */, - ABDA28AB23ABBECD00BEB63F /* DIContainer+Extensions.swift in Sources */, 16ABEC1A24B37F22007577CF /* DIVertex.swift in Sources */, ABBE384025FDE60F00DAFB62 /* ThreadDictionary.swift in Sources */, ABDA28AC23ABBECD00BEB63F /* TypeKey.swift in Sources */, @@ -1220,7 +1220,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-OSX"; PRODUCT_NAME = DITranquillity; @@ -1260,7 +1260,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-OSX"; PRODUCT_NAME = DITranquillity; @@ -1301,7 +1301,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-tvOS"; PRODUCT_MODULE_NAME = DITranquillity; @@ -1344,7 +1344,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-tvOS"; PRODUCT_MODULE_NAME = DITranquillity; @@ -1507,7 +1507,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-iOS"; PRODUCT_NAME = DITranquillity; @@ -1551,7 +1551,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-iOS"; PRODUCT_NAME = DITranquillity; @@ -1594,7 +1594,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-WatchOS"; PRODUCT_MODULE_NAME = DITranquillity; @@ -1640,7 +1640,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 4.2.3; + MARKETING_VERSION = 4.3.0; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "com.sia.DITranquillity-WatchOS"; PRODUCT_MODULE_NAME = DITranquillity; diff --git a/Documentation/ru/core/modificated_injection.md b/Documentation/ru/core/modificated_injection.md index ed4c82ac..fefc36ff 100644 --- a/Documentation/ru/core/modificated_injection.md +++ b/Documentation/ru/core/modificated_injection.md @@ -85,21 +85,47 @@ container.register(BadgeUpdater.init) Но если вы уверены в своих силах, то давайте разбираться, как этим пользоваться. Для того чтобы в компонент можно было внедрять аргументы, как и в прошлых случаях достаточно указать модификатор внедрения: ```Swift container.register { Cat(name: arg($0)) } -.injection { $0.owner = arg($1) } -.injection(\.age) { arg($0) } + .as(Animal.self) + .injection { $0.owner = arg($1) } + .injection(\.age) { arg($0) } ``` Да аргументы можно передавать в любое место, а не только непосредственно в метод инициализации. Дальше обращаю внимание, что их количество может быть любым. В данном примере мы будем передавать три аргумента. При передаче важен порядок - он интуитивен - в каком порядке встречается `arg` в таком порядке надо будет и передавать аргументы. Следующая важная особенность. В отличии от наверное всех библиотек для внедрения зависимостей, в DITranquillity аргументы могут передаваться не только на первый получаемый объект, но и на любой объект который создается в ходе создания целевого. Это было сделано для того чтобы при получении ViewController-а можно было передать аргументы сразу в Presenter. Удобно? - Да. Безопасно? - Не очень, так как зависимости являются внутренней информацией объекта. -Как же это сделать? Для этого у библиотеки есть такой раздел как "расширения". В дальнейшем расширений будет больше, но пока они позволяют добавить аргументы к любому объекту при следующем его создании. В коде это выглядит так: +Как же это сделать? Для этого при получении объекта нужно передать специальный объект, с указанием аргументов. В коде это выглядит так: ```Swift -container.extensions(for: Cat.self).setArgs("Felix", "Peter", 2) +var arguments = AnyArguments() +arguments.addArgs(for: Cat.self, args: "Felix", "Peter", 2) +let cat: Cat = container.resolve(arguments: arguments) +``` +Такая запись позволяет передать аргументы не в один создаваемый объект, а сразу в несколько, в случае если при получении объекта создаются еще и другие объекты: +```Swift +var arguments = AnyArguments() +arguments.addArgs(for: Cat.self, args: "Felix", "Peter", 2) +arguments.addArgs(for: Dog.self, args: "Rex", "Peter", 4) +let home: Home = container.resolve(arguments: arguments) +// home.cat.name == "Fefix" +// home.dog.name == "Rex" +``` +Если вам нужно внедрить аргументы всего в один тип, то можно воспользоваться более короткой записью: +```Swift +let arguments = AnyArguments(for: Cat.self, args: "Felix", "Peter", 2) +let cat: Cat = container.resolve(arguments: arguments) +``` +И есть еще более короткая и привычная запись, в случае если аргументы нужно передать только в получаемый тип: +```Swift +let cat: Cat = container.resolve(args: "Felix", "Peter", 2) ``` -Вначале мы получаем экземпляр расширения для некоего типа. То есть указываем желание, что хотим для некоторого типа добавить дополнительное поведение на этапы его создания. -После этого для этого типа передаем аргументы. Как я писал выше - порядок и тип аргументов никак не проверяется на этапе компиляции, только во время исполнения. +При использовании этих возможностей стоит учитывать важные моменты: +* Порядок аргументов важен - внутри нет проверки на совпадение типов, и если тип не совпадет, то библиотека не создаст объект +* Если во время получения зависимости, нужно будет создать несколько объектов, то каждому объекту передастся список аргументов по отдельности. +* Библиотеке не обязательно указывать тип имплементации. Если у вашего типа [при регистрации были указаны сервисы](registration_and_service.md) то указать аргументы можно и для типов сервисов: +```Swift +let arguments = AnyArguments(for: Animal.self, args: "Felix", "Peter", 2) +let cat: Cat = container.resolve(arguments: arguments) +``` -Аргументы будут переданы только на ОДНУ следующую инициализацию. Существует более безопасный, и более красивый способ передачи аргументов - воспользоваться [отложенным внедрением](delayed_injection.md). Подробно про него написано на [странице](delayed_injection.md), тут будет лишь небольшой пример: ```Swift @@ -114,6 +140,4 @@ class Home { } } ``` -В этом примере используется тесная интеграция с отложенным внедрением. В класс дома внедряется специальный объект, который позволяет создавать кошку отложено. Такой способ чуть более безопасней, чем использование расширений, но и менее гибкий. - - +В этом примере используется тесная интеграция с отложенными внедрениями. В класс дома внедряется специальный объект, который позволяет создавать кошку отложено. Такой способ чуть более безопасней, чем использование контейнера на прямую, но и менее гибкий. diff --git a/Sources/Core/API/ComponentAlternativeType.swift b/Sources/Core/API/ComponentAlternativeType.swift index d70e56f9..1d1db009 100644 --- a/Sources/Core/API/ComponentAlternativeType.swift +++ b/Sources/Core/API/ComponentAlternativeType.swift @@ -2,7 +2,7 @@ // ComponentAlternativeType.swift // DITranquillity // -// Created by Ивлев А.Е. on 06.07.2020. +// Created by Alexander Ivlev on 06.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/Core/API/DIComponentBuilder.swift b/Sources/Core/API/DIComponentBuilder.swift index 6201b63e..3829c7b6 100644 --- a/Sources/Core/API/DIComponentBuilder.swift +++ b/Sources/Core/API/DIComponentBuilder.swift @@ -20,6 +20,8 @@ public final class DIComponentBuilder { #if os(iOS) || os(tvOS) useInjectIntoSubviewComponent() #endif + + container.extensions.componentRegistration?(componentInfo) } deinit { diff --git a/Sources/Core/API/DIContainer+Extensions.swift b/Sources/Core/API/DIContainer+Extensions.swift deleted file mode 100644 index 5ed02334..00000000 --- a/Sources/Core/API/DIContainer+Extensions.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// DIContainer+Extensions.swift -// DITranquillity -// -// Created by Ивлев Александр Евгеньевич on 17/08/2018. -// Copyright © 2018 Alexander Ivlev. All rights reserved. -// - -extension DIContainer -{ - - /// Method for creating an object capable of customizing extensions - /// - /// - Parameters: - /// - type: object type for which extensions are specified. Сan be tagged - /// - name: optional. Qualified name by which to retrieve a specific component - /// - framework: optinal. Qualified framework to which component belongs - /// - Returns: object for customizing extensions - public func extensions(for type: DIAType, name: String? = nil, framework: DIFramework.Type? = nil, file: String = #file, line: Int = #line) -> DIExtensions? { - let candidates = self.resolver.findComponents(by: ParsedType(type: type), with: name, from: framework) - if let component = candidates.first, 1 == candidates.count { - return extensionsContainer.get(by: component.info) - } - - if 0 == candidates.count { - log(.error, msg: "Until make extensions can't find component by type: \(type) in file: \(file.fileName) on line: \(line)") - } else { - log(.error, msg: "Until make extensions can't choose component by type: \(type) in file: \(file.fileName) on line: \(line) from: \(candidates)") - } - - return nil - } -} diff --git a/Sources/Core/API/DIContainer.swift b/Sources/Core/API/DIContainer.swift index c7904a2f..9cea2b13 100644 --- a/Sources/Core/API/DIContainer.swift +++ b/Sources/Core/API/DIContainer.swift @@ -25,6 +25,8 @@ public prefix func *(container: DIContainer) -> T { /// allows you to register new components, parts, frameworks and /// allows you to receive objects by type. public final class DIContainer { + /// Extensions for container. Use this components, for subscribe on event from container about registration or resolve or make component. + public let extensions = DIExtensions() /// Make entry point for library /// @@ -135,9 +137,21 @@ extension DIContainer { /// But if the type is optional, then the application will not crash, but it returns nil. /// /// - Parameter framework: Framework from which to resolve a object + /// - Parameter arguments: Information about injection arguments. Used only if your registration objects with `arg` modificator. /// - Returns: Object for the specified type, or nil (see description). - public func resolve(from framework: DIFramework.Type? = nil) -> T { - return resolver.resolve(from: framework) + public func resolve(from framework: DIFramework.Type? = nil, arguments: AnyArguments? = nil) -> T { + return resolver.resolve(from: framework, arguments: arguments) + } + + /// Resolve object by type. + /// Can crash application, if can't found the type. + /// But if the type is optional, then the application will not crash, but it returns nil. + /// + /// - Parameter framework: Framework from which to resolve a object + /// - Parameter arguments: arguments for resolved object by type. + /// - Returns: Object for the specified type, or nil (see description). + public func resolve(from framework: DIFramework.Type? = nil, args: Any?...) -> T { + return resolver.resolve(from: framework, arguments: AnyArguments(for: T.self, argsArray: args)) } /// Resolve object by type with tag. @@ -147,9 +161,10 @@ extension DIContainer { /// - Parameters: /// - tag: Resolve tag. /// - framework: Framework from which to resolve a object + /// - arguments: Information about injection arguments. Used only if your registration objects with `arg` modificator. /// - Returns: Object for the specified type with tag, or nil (see description). - public func resolve(tag: Tag.Type, from framework: DIFramework.Type? = nil) -> T { - return by(tag: tag, on: resolver.resolve(from: framework)) + public func resolve(tag: Tag.Type, from framework: DIFramework.Type? = nil, arguments: AnyArguments? = nil) -> T { + return by(tag: tag, on: resolver.resolve(from: framework, arguments: arguments)) } /// Resolve object by type with name. @@ -159,16 +174,18 @@ extension DIContainer { /// - Parameters: /// - name: Resolve name. /// - framework: Framework from which to resolve a object + /// - arguments: Information about injection arguments. Used only if your registration objects with `arg` modificator. /// - Returns: Object for the specified type with name, or nil (see description). - public func resolve(name: String, from framework: DIFramework.Type? = nil) -> T { - return resolver.resolve(name: name, from: framework) + public func resolve(name: String, from framework: DIFramework.Type? = nil, arguments: AnyArguments? = nil) -> T { + return resolver.resolve(name: name, from: framework, arguments: arguments) } /// Resolve many objects by type. /// + /// - Parameter arguments: Information about injection arguments. Used only if your registration objects with `arg` modificator. /// - Returns: Objects for the specified type. - public func resolveMany() -> [T] { - return many(resolver.resolve()) + public func resolveMany(arguments: AnyArguments? = nil) -> [T] { + return many(resolver.resolve(arguments: arguments)) } /// Injected all dependencies into object. diff --git a/Sources/Core/API/DILifetime.swift b/Sources/Core/API/DILifetime.swift index f0f64054..3fb63a9e 100644 --- a/Sources/Core/API/DILifetime.swift +++ b/Sources/Core/API/DILifetime.swift @@ -2,7 +2,7 @@ // DILifetime.swift // DITranquillity // -// Created by Ивлев Александр on 12/02/2019. +// Created by Alexander Ivlev on 12/02/2019. // Copyright © 2019 Alexander Ivlev. All rights reserved. // diff --git a/Sources/Core/API/DIScope.swift b/Sources/Core/API/DIScope.swift index b7846a91..57b38296 100644 --- a/Sources/Core/API/DIScope.swift +++ b/Sources/Core/API/DIScope.swift @@ -2,7 +2,7 @@ // DIScope.swift // DITranquillity // -// Created by Ивлев Александр on 12/02/2019. +// Created by Alexander Ivlev on 12/02/2019. // Copyright © 2019 Alexander Ivlev. All rights reserved. // diff --git a/Sources/Core/API/DIStorage.swift b/Sources/Core/API/DIStorage.swift index e630eee9..4dca3140 100644 --- a/Sources/Core/API/DIStorage.swift +++ b/Sources/Core/API/DIStorage.swift @@ -2,7 +2,7 @@ // DIStorage.swift // DITranquillity // -// Created by Ивлев Александр on 12/02/2019. +// Created by Alexander Ivlev on 12/02/2019. // Copyright © 2019 Alexander Ivlev. All rights reserved. // diff --git a/Sources/Core/API/Extensions/DIExtensions.swift b/Sources/Core/API/Extensions/DIExtensions.swift index 86e1a7f5..3f243bed 100644 --- a/Sources/Core/API/Extensions/DIExtensions.swift +++ b/Sources/Core/API/Extensions/DIExtensions.swift @@ -2,41 +2,18 @@ // DIExtensions.swift // DITranquillity // -// Created by Ивлев Александр Евгеньевич on 17/08/2018. -// Copyright © 2018 Alexander Ivlev. All rights reserved. +// Created by Alexander Ivlev on 09/06/2021. +// Copyright © 2021 Alexander Ivlev. All rights reserved. // - /// сlass to extend possible actions related to object creation public class DIExtensions { - private let mutex: PThreadMutex = PThreadMutex(normal: ()) - private var arguments: [Any?] = [] - - /// method for setting arguments injected into an object. - /// Example: - /// ``` - /// container.register{ YourClass(p1: $0, p2: arg($2)) } - /// .injection{ $0.property = arg($1) } - /// ... - /// container.extension(for: YourClass.self).setArgs(15, "it's work!") - /// let yourClass = *container // p1 - injected, p2 = 15, property = "it's work!" - /// ``` - /// - /// - Parameters: - /// - args: array of arguments - public func setArgs(_ args: Any?...) { - mutex.sync { - arguments = args - } - } + /// Subscribe on type registration into your container + public var componentRegistration: ((_ component: DIComponentInfo) -> Void)? - internal func getNextArg() -> Any? { - return mutex.sync { - if arguments.count > 0 { - return arguments.removeFirst() - } - return nil - } - } + /// Subscribe on object resolved into your container + public var objectResolved: ((_ component: DIComponentInfo, _ obj: Any?) -> Void)? + /// Subscribe on object maked into your container + public var objectMaked: ((_ component: DIComponentInfo, _ obj: Any?) -> Void)? } diff --git a/Sources/Core/API/Extensions/SwiftLazy.swift b/Sources/Core/API/Extensions/SwiftLazy.swift index 9f3cf7f1..f61b0ea6 100644 --- a/Sources/Core/API/Extensions/SwiftLazy.swift +++ b/Sources/Core/API/Extensions/SwiftLazy.swift @@ -18,9 +18,9 @@ extension Lazy: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { self.init { () -> Value in - return gmake(by: factory()) + return gmake(by: factory(nil)) } } } @@ -35,9 +35,9 @@ extension Provider: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { self.init { () -> Value in - return gmake(by: factory()) + return gmake(by: factory(nil)) } } } @@ -53,10 +53,9 @@ extension Provider1: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - self.init { (arg1) -> Value in - container.extensions(for: Value.self)?.setArgs(arg1) - return gmake(by: factory()) + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + self.init { arg1 -> Value in + return gmake(by: factory(AnyArguments(for: Value.self, args: arg1))) } } } @@ -71,10 +70,9 @@ extension Provider2: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - self.init { (arg1, arg2) -> Value in - container.extensions(for: Value.self)?.setArgs(arg1, arg2) - return gmake(by: factory()) + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + self.init { arg1, arg2 -> Value in + return gmake(by: factory(AnyArguments(for: Value.self, args: arg1, arg2))) } } } @@ -89,10 +87,9 @@ extension Provider3: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - self.init { (arg1, arg2, arg3) -> Value in - container.extensions(for: Value.self)?.setArgs(arg1, arg2, arg3) - return gmake(by: factory()) + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + self.init { arg1, arg2, arg3 -> Value in + return gmake(by: factory(AnyArguments(for: Value.self, args: arg1, arg2, arg3))) } } } @@ -107,10 +104,9 @@ extension Provider4: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - self.init { (arg1, arg2, arg3, arg4) -> Value in - container.extensions(for: Value.self)?.setArgs(arg1, arg2, arg3, arg4) - return gmake(by: factory()) + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + self.init { arg1, arg2, arg3, arg4 -> Value in + return gmake(by: factory(AnyArguments(for: Value.self, args: arg1, arg2, arg3, arg4))) } } } @@ -125,10 +121,9 @@ extension Provider5: SpecificType { } } - convenience init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - self.init { (arg1, arg2, arg3, arg4, arg5) -> Value in - container.extensions(for: Value.self)?.setArgs(arg1, arg2, arg3, arg4, arg5) - return gmake(by: factory()) + convenience init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + self.init { arg1, arg2, arg3, arg4, arg5 -> Value in + return gmake(by: factory(AnyArguments(for: Value.self, args: arg1, arg2, arg3, arg4, arg5))) } } } diff --git a/Sources/Core/Internal/AnyArguments.swift b/Sources/Core/Internal/AnyArguments.swift new file mode 100644 index 00000000..4fd087ab --- /dev/null +++ b/Sources/Core/Internal/AnyArguments.swift @@ -0,0 +1,80 @@ +// +// AnyArguments.swift +// DITranquillity +// +// Created by Alexander Ivlev on 09.06.2021. +// Copyright © 2021 Alexander Ivlev. All rights reserved. +// + +/// Stores information about arguments for any types. +/// Usage: +/// ``` +/// var arguments = AnyArguments() +/// arguments.addArgs(for: T1.self, args: arg1, arg2) +/// arguments.addArgs(for: T2.self, args: arg3, arg4) +/// +/// let obj: T = container.resolve(arguments: arguments) +/// assert(obj.t1.arg1 == arg1) +/// assert(obj.t1.arg2 == arg2) +/// assert(obj.t2.arg3 == arg3) +/// assert(obj.t2.arg4 == arg4) +/// ``` +/// Also if need arguments in resolved type, your can use short syntax: +/// ``` +/// let obj: T = container.resolve(args: arg1, arg2) +/// assert(obj.arg1 == arg1) +/// assert(obj.arg2 == arg2) +/// ``` +public struct AnyArguments { + private var typesWithArgs: [(type: ObjectIdentifier, args: Arguments)] = [] + + /// empty initialization + public init() { } + + /// If need inject arguments in one type, your can use this initialization + public init(for type: DIAType, args: Any?...) { + typesWithArgs.append((ObjectIdentifier(type), Arguments(args: args))) + } + + internal init(for type: DIAType, argsArray: [Any?]) { + typesWithArgs.append((ObjectIdentifier(type), Arguments(args: argsArray))) + } + + /// add arguments for specified type. + @discardableResult + public mutating func addArgs(for type: DIAType, args: Any?...) -> Self { + typesWithArgs.append((ObjectIdentifier(type), Arguments(args: args))) + return self + } + + internal func getArguments(for component: Component) -> Arguments? { + let types = Set(([component.info.type] + component.alternativeTypes.compactMap { + if case .type(let type) = $0 { + return type + } + return nil + }).map { ObjectIdentifier($0) }) + + let relevantTypesWithArgs = typesWithArgs.filter { types.contains($0.type) } + if relevantTypesWithArgs.count != 1 { + return nil + } + return relevantTypesWithArgs.first?.args + } +} + + +internal struct Arguments { + private var args: [Any?] = [] + + internal init(args: [Any?]) { + self.args = args + } + + internal mutating func getArgument(for type: DIAType) -> Any? { + if args.count > 0 { + return args.removeFirst() + } + return nil + } +} diff --git a/Sources/Core/Internal/ExtensionsContainer.swift b/Sources/Core/Internal/ExtensionsContainer.swift index 2acab058..20de0b76 100644 --- a/Sources/Core/Internal/ExtensionsContainer.swift +++ b/Sources/Core/Internal/ExtensionsContainer.swift @@ -2,7 +2,7 @@ // ExtensionsContainer.swift // DITranquillity // -// Created by Ивлев Александр Евгеньевич on 17/08/2018. +// Created by Alexander Ivlev on 17/08/2018. // Copyright © 2018 Alexander Ivlev. All rights reserved. // diff --git a/Sources/Core/Internal/ParsedType.swift b/Sources/Core/Internal/ParsedType.swift index 98f8f1f1..05cc16d7 100644 --- a/Sources/Core/Internal/ParsedType.swift +++ b/Sources/Core/Internal/ParsedType.swift @@ -2,7 +2,8 @@ // ParsedType.swift // DITranquillity // -// Created by Ивлев Александр on 06/12/2018. +// Created by Alexander Ivlev on 06/12/2018. +// Copyright © 2018 Alexander Ivlev. All rights reserved. // final class ParsedType { diff --git a/Sources/Core/Internal/Resolver.swift b/Sources/Core/Internal/Resolver.swift index b0d2fc10..1a0431ca 100644 --- a/Sources/Core/Internal/Resolver.swift +++ b/Sources/Core/Internal/Resolver.swift @@ -6,41 +6,43 @@ // Copyright © 2016 Alexander Ivlev. All rights reserved. // +import SwiftLazy + class Resolver { init(container: DIContainer) { self.container = container // unowned } - func resolve(type: T.Type = T.self, name: String? = nil, from framework: DIFramework.Type? = nil) -> T { + func resolve(type: T.Type = T.self, name: String? = nil, from framework: DIFramework.Type? = nil, arguments: AnyArguments? = nil) -> T { let pType = ParsedType(type: type) log(.verbose, msg: "Begin resolve \(description(type: pType))", brace: .begin) defer { log(.verbose, msg: "End resolve \(description(type: pType))", brace: .end) } - return gmake(by: make(by: pType, with: name, from: framework, use: nil)) + return gmake(by: make(by: pType, with: name, from: framework, use: nil, arguments: arguments)) } - func injection(obj: T, from framework: DIFramework.Type? = nil) { + func injection(obj: T, from framework: DIFramework.Type? = nil, arguments: AnyArguments? = nil) { log(.verbose, msg: "Begin injection in obj: \(obj)", brace: .begin) defer { log(.verbose, msg: "End injection in obj: \(obj)", brace: .end) } - _ = make(by: ParsedType(obj: obj), with: nil, from: framework, use: obj) + _ = make(by: ParsedType(obj: obj), with: nil, from: framework, use: obj, arguments: arguments) } - func resolveCached(component: Component) { + func resolveCached(component: Component, arguments: AnyArguments? = nil) { log(.verbose, msg: "Begin resolve cached object by component: \(component.info)", brace: .begin) defer { log(.verbose, msg: "End resolve cached object by component: \(component.info)", brace: .end) } - mutex.sync { _ = makeObject(by: component, use: nil) } + mutex.sync { _ = makeObject(by: component, use: nil, arguments: arguments) } } - func resolve(type: T.Type = T.self, component: Component) -> T { + func resolve(type: T.Type = T.self, component: Component, arguments: AnyArguments? = nil) -> T { let pType = ParsedType(type: type) log(.verbose, msg: "Begin resolve \(description(type: pType)) by component: \(component.info)", brace: .begin) defer { log(.verbose, msg: "End resolve \(description(type: pType)) by component: \(component.info)", brace: .end) } - return gmake(by: makeObject(by: component, use: nil)) + return gmake(by: makeObject(by: component, use: nil, arguments: arguments)) } /// Finds the most suitable components that satisfy the types. @@ -170,7 +172,7 @@ class Resolver { mutex.sync { cache.containerStorage.clean() } } - private func make(by parsedType: ParsedType, with name: String?, from framework: DIFramework.Type?, use object: Any?) -> Any? { + private func make(by parsedType: ParsedType, with name: String?, from framework: DIFramework.Type?, use object: Any?, arguments: AnyArguments?) -> Any? { log(.verbose, msg: "Begin make \(description(type: parsedType))", brace: .begin) defer { log(.verbose, msg: "End make \(description(type: parsedType))", brace: .end) } @@ -186,16 +188,16 @@ class Resolver { let saveGraph = cache.graph func makeDelayMaker(by parsedType: ParsedType, components: Components) -> Any? { - return delayMaker.init(container, { () -> Any? in + return delayMaker.init(container, { arguments -> Any? in return self.mutex.sync { // call `.value` into DI initialize. if saveGraph === self.cache.graph { - return self.make(by: parsedType, components: components, use: object) + return self.make(by: parsedType, components: components, use: object, arguments: arguments) } // Call `.value` firstly. if self.stack.isEmpty { self.cache.graph = saveGraph.toStrongCopy() - return self.make(by: parsedType, components: components, use: object) + return self.make(by: parsedType, components: components, use: object, arguments: arguments) } // Call `.value` into DI initialize, and DI graph has lifetimes perContainer, perRun, single... // For this case need call provider on her Cache Graph. @@ -206,7 +208,7 @@ class Resolver { self.cache.graph.toWeak() self.cache.graph = currentGraphCache } - return self.make(by: parsedType, components: components, use: object) + return self.make(by: parsedType, components: components, use: object, arguments: arguments) } }) } @@ -221,19 +223,19 @@ class Resolver { } } - return make(by: parsedType, components: components, use: object) + return make(by: parsedType, components: components, use: object, arguments: arguments) } } /// isMany for optimization - private func make(by parsedType: ParsedType, components: Components, use object: Any?) -> Any? { + private func make(by parsedType: ParsedType, components: Components, use object: Any?, arguments: AnyArguments?) -> Any? { if parsedType.hasMany { assert(nil == object, "Many injection not supported") - return components.sorted{ $0.order < $1.order }.compactMap{ makeObject(by: $0, use: nil) } + return components.sorted{ $0.order < $1.order }.compactMap{ makeObject(by: $0, use: nil, arguments: arguments) } } if let component = components.first, 1 == components.count { - return makeObject(by: component, use: object) + return makeObject(by: component, use: object, arguments: arguments) } if components.isEmpty { @@ -247,7 +249,7 @@ class Resolver { } /// Super function - private func makeObject(by component: Component, use usingObject: Any?) -> Any? { + private func makeObject(by component: Component, use usingObject: Any?, arguments: AnyArguments?) -> Any? { log(.verbose, msg: "Found component: \(component.info)") let uniqueKey = component.info @@ -282,12 +284,15 @@ class Resolver { return nil } - func getArgumentObject() -> Any? { - guard let extensions = container.extensionsContainer.optionalGet(by: component.info) else { - log(.error, msg: "Until get argument. Not found extensions for \(component.info)") + var componentArguments: Arguments? + func getArgumentObject(parameter: MethodSignature.Parameter) -> Any? { + componentArguments = componentArguments ?? arguments?.getArguments(for: component) + + if componentArguments == nil { + log(.error, msg: "Get arguments for \(component.info) failed. Please specify arguments or remove dublicates for this type") return nil } - return extensions.getNextArg() + return componentArguments?.getArgument(for: parameter.parsedType.base.type) } func makeObject() -> Any? { @@ -310,7 +315,8 @@ class Resolver { _ = use(signature: signature, usingObject: initializedObject) } } - + + container.extensions.objectMaked?(uniqueKey, initializedObject) return initializedObject } @@ -347,9 +353,9 @@ class Resolver { if parameter.parsedType.useObject { makedObject = usingObject } else if parameter.parsedType.arg { - makedObject = getArgumentObject() + makedObject = getArgumentObject(parameter: parameter) } else { - makedObject = make(by: parameter.parsedType, with: parameter.name, from: component.framework, use: nil) + makedObject = make(by: parameter.parsedType, with: parameter.name, from: component.framework, use: nil, arguments: arguments) } if nil != makedObject || parameter.parsedType.optional { @@ -372,26 +378,32 @@ class Resolver { stack.removeLast() } - switch component.lifeTime { - case .single: - return makeObject(scope: Cache.single) - case .perRun(let referenceCounting): - switch referenceCounting { - case .weak: return makeObject(scope: Cache.weakPerRun) - case .strong: return makeObject(scope: Cache.strongPerRun) - } - case .perContainer(let referenceCounting): - switch referenceCounting { - case .weak: return makeObject(scope: cache.weakPerContainer) - case .strong: return makeObject(scope: cache.strongPerContainer) + func makeOrGetObject() -> Any? { + switch component.lifeTime { + case .single: + return makeObject(scope: Cache.single) + case .perRun(let referenceCounting): + switch referenceCounting { + case .weak: return makeObject(scope: Cache.weakPerRun) + case .strong: return makeObject(scope: Cache.strongPerRun) + } + case .perContainer(let referenceCounting): + switch referenceCounting { + case .weak: return makeObject(scope: cache.weakPerContainer) + case .strong: return makeObject(scope: cache.strongPerContainer) + } + case .objectGraph: + return makeObject(scope: cache.graph) + case .prototype: + return makeObject() + case .custom(let scope): + return makeObject(scope: scope) } - case .objectGraph: - return makeObject(scope: cache.graph) - case .prototype: - return makeObject() - case .custom(let scope): - return makeObject(scope: scope) } + + let obj = makeOrGetObject() + container.extensions.objectResolved?(uniqueKey, obj) + return obj } private unowned let container: DIContainer diff --git a/Sources/Core/Internal/SpecificType.swift b/Sources/Core/Internal/SpecificType.swift index b75b304a..fb3143d7 100644 --- a/Sources/Core/Internal/SpecificType.swift +++ b/Sources/Core/Internal/SpecificType.swift @@ -2,7 +2,8 @@ // SpecificType.swift // DITranquillity // -// Created by Ивлев Александр on 06/12/2018. +// Created by Alexander Ivlev on 06/12/2018. +// Copyright © 2018 Alexander Ivlev. All rights reserved. // protocol SpecificType { @@ -24,29 +25,29 @@ protocol SpecificType { static func make(by obj: Any?) -> Self - init(_ container: DIContainer, _ factory: @escaping () -> Any?) + init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) } extension SpecificType { - static var recursive: Bool { return true } + static var recursive: Bool { return true } - static var type: DIAType { return self } - static var tagType: DIAType { return self } - static var isSwiftType: Bool { return false } + static var type: DIAType { return self } + static var tagType: DIAType { return self } + static var isSwiftType: Bool { return false } - static var many: Bool { return false } - static var optional: Bool { return false } - static var delayed: Bool { return false } - static var inFramework: Bool { return false } + static var many: Bool { return false } + static var optional: Bool { return false } + static var delayed: Bool { return false } + static var inFramework: Bool { return false } - static var tag: Bool { return false } - static var arg: Bool { return false } + static var tag: Bool { return false } + static var arg: Bool { return false } - static var useObject: Bool { return false } + static var useObject: Bool { return false } - static func make(by obj: Any?) -> Self { return obj as! Self } + static func make(by obj: Any?) -> Self { return obj as! Self } - init(_ container: DIContainer, _ factory: @escaping () -> Any?) { - fatalError("Unsupport") - } + init(_ container: DIContainer, _ factory: @escaping (_ arguments: AnyArguments?) -> Any?) { + fatalError("Unsupport") + } } diff --git a/Sources/GraphAPI/DIContainer+makeGraph.swift b/Sources/GraphAPI/DIContainer+makeGraph.swift index 7ea4dca4..1ad72ca4 100644 --- a/Sources/GraphAPI/DIContainer+makeGraph.swift +++ b/Sources/GraphAPI/DIContainer+makeGraph.swift @@ -2,7 +2,7 @@ // DIContainer+getGraph.swift // DITranquillity // -// Created by Ивлев А.Е. on 30.06.2020. +// Created by Alexander Ivlev on 30.06.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIEdge.swift b/Sources/GraphAPI/DIEdge.swift index 8423b3c2..85fafdeb 100644 --- a/Sources/GraphAPI/DIEdge.swift +++ b/Sources/GraphAPI/DIEdge.swift @@ -2,7 +2,7 @@ // DIEdge.swift // DITranquillity // -// Created by Ивлев А.Е. on 06.07.2020. +// Created by Alexander Ivlev on 06.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIGraph+Cycle.swift b/Sources/GraphAPI/DIGraph+Cycle.swift index 73abebec..35653ee3 100644 --- a/Sources/GraphAPI/DIGraph+Cycle.swift +++ b/Sources/GraphAPI/DIGraph+Cycle.swift @@ -2,7 +2,7 @@ // DIGraph+Cycle.swift // DITranquillity // -// Created by Ивлев А.Е. on 06.07.2020. +// Created by Alexander Ivlev on 06.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIGraph+Validate.swift b/Sources/GraphAPI/DIGraph+Validate.swift index 53674757..5e59991a 100644 --- a/Sources/GraphAPI/DIGraph+Validate.swift +++ b/Sources/GraphAPI/DIGraph+Validate.swift @@ -2,7 +2,7 @@ // DIGraph+Validate.swift // DITranquillity // -// Created by Ивлев А.Е. on 02.07.2020. +// Created by Alexander Ivlev on 02.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIGraph+ValidationErrors.swift b/Sources/GraphAPI/DIGraph+ValidationErrors.swift index 6a52813a..e37c2bef 100644 --- a/Sources/GraphAPI/DIGraph+ValidationErrors.swift +++ b/Sources/GraphAPI/DIGraph+ValidationErrors.swift @@ -2,7 +2,7 @@ // DIGraph+ValidationErrors.swift // DITranquillity // -// Created by Ивлев А.Е. on 03.07.2020. +// Created by Alexander Ivlev on 03.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIGraph.swift b/Sources/GraphAPI/DIGraph.swift index d3a585ca..ac7dc513 100644 --- a/Sources/GraphAPI/DIGraph.swift +++ b/Sources/GraphAPI/DIGraph.swift @@ -2,7 +2,7 @@ // DIGraph.swift // DITranquillity // -// Created by Ивлев А.Е. on 30.06.2020. +// Created by Alexander Ivlev on 30.06.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/GraphAPI/DIVertex.swift b/Sources/GraphAPI/DIVertex.swift index c1be5a70..16fee812 100644 --- a/Sources/GraphAPI/DIVertex.swift +++ b/Sources/GraphAPI/DIVertex.swift @@ -2,7 +2,7 @@ // DIVertex.swift // DITranquillity // -// Created by Ивлев А.Е. on 06.07.2020. +// Created by Alexander Ivlev on 06.07.2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Sources/UI/Storyboard/ViewController+Children.swift b/Sources/UI/Storyboard/ViewController+Children.swift index 3f963ea2..cfba01e2 100644 --- a/Sources/UI/Storyboard/ViewController+Children.swift +++ b/Sources/UI/Storyboard/ViewController+Children.swift @@ -2,7 +2,7 @@ // ViewController+Children.swift // DITranquillity // -// Created by Ивлев Александр Евгеньевич on 31/08/2018. +// Created by Alexander Ivlev on 31/08/2018. // Copyright © 2018 Alexander Ivlev. All rights reserved. // diff --git a/Tests/DITranquillityTest/DITranquillityTests_Extensions.swift b/Tests/DITranquillityTest/DITranquillityTests_Extensions.swift index 520429e6..d6f7d907 100644 --- a/Tests/DITranquillityTest/DITranquillityTests_Extensions.swift +++ b/Tests/DITranquillityTest/DITranquillityTests_Extensions.swift @@ -2,7 +2,7 @@ // DITranquillityTests_Extensions.swift // DITranquillity // -// Created by Ивлев Александр Евгеньевич on 17/08/2018. +// Created by Alexander Ivlev on 17/08/2018. // Copyright © 2018 Alexander Ivlev. All rights reserved. // @@ -67,9 +67,7 @@ class DITranquillityTests_Extensions: XCTestCase { .injection{ $0.p4 = arg($1) } .injection(\.p5) { arg($0) } - container.extensions(for: Class.self)?.setArgs(111, 22.2, [1,2,3,4,5], ["H","e","l","l","o"]) - - let obj: Class = *container + let obj: Class = container.resolve(args: 111, 22.2, [1,2,3,4,5], ["H","e","l","l","o"]) XCTAssertEqual(obj.p1, 111) XCTAssertEqual(obj.p2, "injection") @@ -89,9 +87,8 @@ class DITranquillityTests_Extensions: XCTestCase { container.register(DepthClass.init) - container.extensions(for: Class.self)?.setArgs("injection", 22.2, [1,2,3,4,5], ["H","e","l","l","o"]) - - let obj: DepthClass = *container + let obj: DepthClass = container.resolve( + arguments: AnyArguments(for: Class.self, args: "injection", 22.2, [1,2,3,4,5], ["H","e","l","l","o"])) XCTAssertEqual(obj.c.p1, 111) XCTAssertEqual(obj.c.p2, "injection") @@ -105,9 +102,7 @@ class DITranquillityTests_Extensions: XCTestCase { container.register{ OptionalClass(p1: arg($0), p2: $1, p3: arg($2)) } - container.extensions(for: OptionalClass.self)?.setArgs(nil, 22.2) - - let obj: OptionalClass = *container + let obj: OptionalClass = container.resolve(args: nil, 22.2) XCTAssertNil(obj.p1) XCTAssertNil(obj.p2) @@ -126,39 +121,19 @@ class DITranquillityTests_Extensions: XCTestCase { XCTAssertNil(obj.p3) } - func test05_ExtensionsNoRegister() { + func test05_ProtocolArguments() { let container = DIContainer() - let ext = container.extensions(for: Class.self) - - XCTAssertNil(ext) - } - - func test06_ExtensionsProtocolOneRegister() { - let container = DIContainer() - - container.register{ Class(p1: $0, p2: arg($1), p3: arg($2)) } - .as(MyProtocol.self) - - let ext = container.extensions(for: MyProtocol.self) - - XCTAssertNotNil(ext) - } - - func test06_ExtensionsMoreRegister() { - let container = DIContainer() - - container.register{ OptionalClass(p1: arg($0), p2: $1, p3: arg($2)) } - .as(MyProtocol.self) - - container.register{ Class(p1: $0, p2: arg($1), p3: arg($2)) } + container.register{ Class(p1: arg($0), p2: arg($1), p3: arg($2)) } .as(MyProtocol.self) - let ext = container.extensions(for: MyProtocol.self) - - XCTAssertNil(ext) - } - + var arguments = AnyArguments() + arguments.addArgs(for: MyProtocol.self, args: 11, "test", 15.0) + let obj: Class = container.resolve(arguments: arguments) + XCTAssertEqual(obj.p1, 11) + XCTAssertEqual(obj.p2, "test") + XCTAssertEqual(obj.p3, 15.0) + } } diff --git a/Tests/DITranquillityTest/DITranquillityTests_Modular.swift b/Tests/DITranquillityTest/DITranquillityTests_Modular.swift index 2369d4b4..19ab0a29 100644 --- a/Tests/DITranquillityTest/DITranquillityTests_Modular.swift +++ b/Tests/DITranquillityTest/DITranquillityTests_Modular.swift @@ -2,7 +2,7 @@ // DITranquillityTests_Modular.swift // DITranquillityTests // -// Created by Ивлев А.Е. on 17/02/2020. +// Created by Alexander Ivlev on 17/02/2020. // Copyright © 2020 Alexander Ivlev. All rights reserved. // diff --git a/Tests/DITranquillityTest/DITranquillityTests_MoreParameters.swift b/Tests/DITranquillityTest/DITranquillityTests_MoreParameters.swift index 0a707b5d..c3600aee 100644 --- a/Tests/DITranquillityTest/DITranquillityTests_MoreParameters.swift +++ b/Tests/DITranquillityTest/DITranquillityTests_MoreParameters.swift @@ -2,7 +2,7 @@ // DITranquillityTests_MoreParameters.swift // DITranquillity-iOS // -// Created by Ивлев Александр Евгеньевич on 17/05/2018. +// Created by Alexander Ivlev on 17/05/2018. // Copyright © 2018 Alexander Ivlev. All rights reserved. // diff --git a/Tests/DITranquillityTest/DITranquillityTests_Parent.swift b/Tests/DITranquillityTest/DITranquillityTests_Parent.swift index fe440d2a..a274a6d0 100644 --- a/Tests/DITranquillityTest/DITranquillityTests_Parent.swift +++ b/Tests/DITranquillityTest/DITranquillityTests_Parent.swift @@ -2,7 +2,7 @@ // DITranquillityTests_Parent.swift // DITranquillityTests // -// Created by Ивлев Александр Евгеньевич on 26/09/2018. +// Created by Alexander Ivlev on 26/09/2018. // Copyright © 2018 Alexander Ivlev. All rights reserved. //