diff --git a/CHANGELOG.md b/CHANGELOG.md index cf90114..cd08f43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ __Sections__ - Support for multiple arguments. Code clean up. - Using parameter packs for multiple arguments - Tests are converted to the new Swift Testing framework +- Fix of async resolve of shared dependencies ## [1.0.4] diff --git a/DependencyInjection.xcodeproj/project.pbxproj b/DependencyInjection.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5589c8b --- /dev/null +++ b/DependencyInjection.xcodeproj/project.pbxproj @@ -0,0 +1,828 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 0F0EC10C69E47D85C55841E5 /* DependencyAutoregistering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86D18ABC36825D5E4659F187 /* DependencyAutoregistering.swift */; }; + 488514BB19BCD1235EC5BEDF /* Injected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D716BA60E15D9B99BDA81D6 /* Injected.swift */; }; + 4AADD60495AB1BDF90A77CA7 /* AsyncDependencyRegistering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0540BAF9226627466BCA29AB /* AsyncDependencyRegistering.swift */; }; + 59646DF77FBE0893B71FEBB6 /* AsyncContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006AB02F9AFCF0678724ACB9 /* AsyncContainer.swift */; }; + 5C4783670D99CC0316AEED4A /* DependencyResolving.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62440DB606CAA4E38D984CB3 /* DependencyResolving.swift */; }; + 655533DA195952C302B5AB2E /* RegistrationIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDE1CF0A78F03F4A27F775 /* RegistrationIdentifier.swift */; }; + 677FEF0962856B9EEF8C924C /* Registration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527CBA78FAF3168AA5D980F1 /* Registration.swift */; }; + 7072AF811C6B5FBDF4E75E64 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 322A71514D6BD32F1C3A1171 /* Container.swift */; }; + 7550578D5840A448EEA17F46 /* ResolutionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 744089AF193032D0720430FB /* ResolutionError.swift */; }; + 7B15A1A1BC0CB331CA53DF76 /* ModuleRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A218F3B8405E479560AA7EAA /* ModuleRegistration.swift */; }; + 996E7D36CF4F9FA5CE407CEB /* DependencyRegistering.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F26A8A6CCA0F65EB53F4B8 /* DependencyRegistering.swift */; }; + A9F38041C5E8D4B4A0E06E16 /* AsyncDependencyResolving.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27072096872F0240389424C8 /* AsyncDependencyResolving.swift */; }; + ACC3DF3ED2C63A2693EC8F63 /* DependencyScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6A8A7504841D604B2E85C78 /* DependencyScope.swift */; }; + D4868CF52C04FDF9B0839784 /* AsyncModuleRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC6EFDA31ADF86E697192161 /* AsyncModuleRegistration.swift */; }; + DD0B875517645D5AED1CC698 /* AsyncRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EFE9E8F1052ED64B98F7D /* AsyncRegistration.swift */; }; + F5A50CCD66C7D0BEFAD06854 /* LazyInjected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7178595BF3600203049C2562 /* LazyInjected.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + B8F515DE0266CCC8C80B3C89 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 006AB02F9AFCF0678724ACB9 /* AsyncContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncContainer.swift; sourceTree = ""; }; + 0540BAF9226627466BCA29AB /* AsyncDependencyRegistering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncDependencyRegistering.swift; sourceTree = ""; }; + 27072096872F0240389424C8 /* AsyncDependencyResolving.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncDependencyResolving.swift; sourceTree = ""; }; + 322A71514D6BD32F1C3A1171 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; + 3D716BA60E15D9B99BDA81D6 /* Injected.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Injected.swift; sourceTree = ""; }; + 527CBA78FAF3168AA5D980F1 /* Registration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Registration.swift; sourceTree = ""; }; + 62440DB606CAA4E38D984CB3 /* DependencyResolving.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependencyResolving.swift; sourceTree = ""; }; + 64BDE1CF0A78F03F4A27F775 /* RegistrationIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationIdentifier.swift; sourceTree = ""; }; + 7178595BF3600203049C2562 /* LazyInjected.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyInjected.swift; sourceTree = ""; }; + 744089AF193032D0720430FB /* ResolutionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResolutionError.swift; sourceTree = ""; }; + 7EBFBFA6FBFF226C37CA713F /* DependencyInjection-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "DependencyInjection-Info.plist"; sourceTree = ""; }; + 841EFE9E8F1052ED64B98F7D /* AsyncRegistration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncRegistration.swift; sourceTree = ""; }; + 86D18ABC36825D5E4659F187 /* DependencyAutoregistering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependencyAutoregistering.swift; sourceTree = ""; }; + A218F3B8405E479560AA7EAA /* ModuleRegistration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleRegistration.swift; sourceTree = ""; }; + A6A8A7504841D604B2E85C78 /* DependencyScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependencyScope.swift; sourceTree = ""; }; + B7F26A8A6CCA0F65EB53F4B8 /* DependencyRegistering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependencyRegistering.swift; sourceTree = ""; }; + CC6EFDA31ADF86E697192161 /* AsyncModuleRegistration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncModuleRegistration.swift; sourceTree = ""; }; + D8973C5E0C32FA7A06D80897 /* DependencyInjection.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DependencyInjection.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3DD8845A43EC7AAD06E546F6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 06113DA7F7696A1E15A9B597 /* Sync */ = { + isa = PBXGroup; + children = ( + 62440DB606CAA4E38D984CB3 /* DependencyResolving.swift */, + A218F3B8405E479560AA7EAA /* ModuleRegistration.swift */, + ); + path = Sync; + sourceTree = ""; + }; + 14A9C76ABD40223F48DAB7CB /* Registration */ = { + isa = PBXGroup; + children = ( + 3D0A77BAB3864DCE7FEAF380 /* Async */, + 1B4AD32692995E22CCAF24C2 /* Sync */, + ); + path = Registration; + sourceTree = ""; + }; + 1B4AD32692995E22CCAF24C2 /* Sync */ = { + isa = PBXGroup; + children = ( + 86D18ABC36825D5E4659F187 /* DependencyAutoregistering.swift */, + B7F26A8A6CCA0F65EB53F4B8 /* DependencyRegistering.swift */, + ); + path = Sync; + sourceTree = ""; + }; + 30AD42D71BABFB1FE473A4AC /* Protocols */ = { + isa = PBXGroup; + children = ( + 14A9C76ABD40223F48DAB7CB /* Registration */, + DE80C6B58BEB33BC885DEF9C /* Resolution */, + ); + path = Protocols; + sourceTree = ""; + }; + 375C34F992371F392135D0A3 /* Sync */ = { + isa = PBXGroup; + children = ( + 322A71514D6BD32F1C3A1171 /* Container.swift */, + ); + path = Sync; + sourceTree = ""; + }; + 3D0A77BAB3864DCE7FEAF380 /* Async */ = { + isa = PBXGroup; + children = ( + 0540BAF9226627466BCA29AB /* AsyncDependencyRegistering.swift */, + ); + path = Async; + sourceTree = ""; + }; + 41F34376FC297AD4F75303C5 /* Async */ = { + isa = PBXGroup; + children = ( + 27072096872F0240389424C8 /* AsyncDependencyResolving.swift */, + CC6EFDA31ADF86E697192161 /* AsyncModuleRegistration.swift */, + ); + path = Async; + sourceTree = ""; + }; + 610CC198FAB5EEEAF9B9CAA5 /* PropertyWrappers */ = { + isa = PBXGroup; + children = ( + 3D716BA60E15D9B99BDA81D6 /* Injected.swift */, + 7178595BF3600203049C2562 /* LazyInjected.swift */, + ); + path = PropertyWrappers; + sourceTree = ""; + }; + 7328925C0447DEF24AFCE757 = { + isa = PBXGroup; + children = ( + C6C8C5285D241145D3E3ECA7 /* Project */, + 9C53AFD18ED7AB4CF4F7AAA6 /* Products */, + ); + sourceTree = ""; + }; + 8BD81DA2F70967A73FC671D2 /* InfoPlists */ = { + isa = PBXGroup; + children = ( + 7EBFBFA6FBFF226C37CA713F /* DependencyInjection-Info.plist */, + ); + path = InfoPlists; + sourceTree = ""; + }; + 8ED94F0A0C528D10245A9AE1 /* Models */ = { + isa = PBXGroup; + children = ( + E4070327992386902B1054C7 /* Async */, + D278BC0783FBA32668E12BA0 /* Sync */, + A6A8A7504841D604B2E85C78 /* DependencyScope.swift */, + 64BDE1CF0A78F03F4A27F775 /* RegistrationIdentifier.swift */, + 744089AF193032D0720430FB /* ResolutionError.swift */, + ); + path = Models; + sourceTree = ""; + }; + 9C53AFD18ED7AB4CF4F7AAA6 /* Products */ = { + isa = PBXGroup; + children = ( + D8973C5E0C32FA7A06D80897 /* DependencyInjection.framework */, + ); + name = Products; + sourceTree = ""; + }; + C3DA8F2DBDF0D391C6EF142A /* Container */ = { + isa = PBXGroup; + children = ( + D0D51FC40B568488124C16BB /* Async */, + 375C34F992371F392135D0A3 /* Sync */, + ); + path = Container; + sourceTree = ""; + }; + C6C8C5285D241145D3E3ECA7 /* Project */ = { + isa = PBXGroup; + children = ( + E6C797B85EBA09B9CB5E9AD3 /* Derived */, + ED496E4164DCDDDE765249AA /* Sources */, + ); + name = Project; + sourceTree = ""; + }; + D0D51FC40B568488124C16BB /* Async */ = { + isa = PBXGroup; + children = ( + 006AB02F9AFCF0678724ACB9 /* AsyncContainer.swift */, + ); + path = Async; + sourceTree = ""; + }; + D278BC0783FBA32668E12BA0 /* Sync */ = { + isa = PBXGroup; + children = ( + 527CBA78FAF3168AA5D980F1 /* Registration.swift */, + ); + path = Sync; + sourceTree = ""; + }; + DE80C6B58BEB33BC885DEF9C /* Resolution */ = { + isa = PBXGroup; + children = ( + 41F34376FC297AD4F75303C5 /* Async */, + 06113DA7F7696A1E15A9B597 /* Sync */, + ); + path = Resolution; + sourceTree = ""; + }; + E4070327992386902B1054C7 /* Async */ = { + isa = PBXGroup; + children = ( + 841EFE9E8F1052ED64B98F7D /* AsyncRegistration.swift */, + ); + path = Async; + sourceTree = ""; + }; + E6C797B85EBA09B9CB5E9AD3 /* Derived */ = { + isa = PBXGroup; + children = ( + 8BD81DA2F70967A73FC671D2 /* InfoPlists */, + ); + path = Derived; + sourceTree = ""; + }; + ED496E4164DCDDDE765249AA /* Sources */ = { + isa = PBXGroup; + children = ( + C3DA8F2DBDF0D391C6EF142A /* Container */, + 8ED94F0A0C528D10245A9AE1 /* Models */, + 610CC198FAB5EEEAF9B9CAA5 /* PropertyWrappers */, + 30AD42D71BABFB1FE473A4AC /* Protocols */, + ); + path = Sources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 066B6D94E318585A3823B92C /* DependencyInjection */ = { + isa = PBXNativeTarget; + buildConfigurationList = E0142061E08F2E181A8D4D2A /* Build configuration list for PBXNativeTarget "DependencyInjection" */; + buildPhases = ( + 99314D14DB38963C89289A31 /* Sources */, + DA315482D92E0489CEBF5DCE /* Resources */, + B8F515DE0266CCC8C80B3C89 /* Embed Frameworks */, + 3DD8845A43EC7AAD06E546F6 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DependencyInjection; + packageProductDependencies = ( + ); + productName = DependencyInjection; + productReference = D8973C5E0C32FA7A06D80897 /* DependencyInjection.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 14C0EC1B68C144FE601BAFF5 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 9999; + TargetAttributes = { + }; + }; + buildConfigurationList = 2A8A546792FE3A4C3F2EBAAC /* Build configuration list for PBXProject "DependencyInjection" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = 7328925C0447DEF24AFCE757; + productRefGroup = 9C53AFD18ED7AB4CF4F7AAA6 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 066B6D94E318585A3823B92C /* DependencyInjection */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DA315482D92E0489CEBF5DCE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 99314D14DB38963C89289A31 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 59646DF77FBE0893B71FEBB6 /* AsyncContainer.swift in Sources */, + 7072AF811C6B5FBDF4E75E64 /* Container.swift in Sources */, + DD0B875517645D5AED1CC698 /* AsyncRegistration.swift in Sources */, + ACC3DF3ED2C63A2693EC8F63 /* DependencyScope.swift in Sources */, + 655533DA195952C302B5AB2E /* RegistrationIdentifier.swift in Sources */, + 7550578D5840A448EEA17F46 /* ResolutionError.swift in Sources */, + 677FEF0962856B9EEF8C924C /* Registration.swift in Sources */, + 488514BB19BCD1235EC5BEDF /* Injected.swift in Sources */, + F5A50CCD66C7D0BEFAD06854 /* LazyInjected.swift in Sources */, + 4AADD60495AB1BDF90A77CA7 /* AsyncDependencyRegistering.swift in Sources */, + 0F0EC10C69E47D85C55841E5 /* DependencyAutoregistering.swift in Sources */, + 996E7D36CF4F9FA5CE407CEB /* DependencyRegistering.swift in Sources */, + A9F38041C5E8D4B4A0E06E16 /* AsyncDependencyResolving.swift in Sources */, + D4868CF52C04FDF9B0839784 /* AsyncModuleRegistration.swift in Sources */, + 5C4783670D99CC0316AEED4A /* DependencyResolving.swift in Sources */, + 7B15A1A1BC0CB331CA53DF76 /* ModuleRegistration.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 0B4CDCE67DBEE3BDBD9D9B00 /* Production-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = "Production-Release"; + }; + 3E150CB2E5A9FCFD1C934365 /* Development-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = "Development-Release"; + }; + 4E66FC02FE60654E3FBE9945 /* Development-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE=1", + ); + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; + INFOPLIST_FILE = "Derived/InfoPlists/DependencyInjection-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-package-name", + DependencyInjection, + "$(inherited)", + "-enable-upcoming-feature \"StrictConcurrency\"", + ); + PRODUCT_BUNDLE_IDENTIFIER = DependencyInjection; + PRODUCT_NAME = DependencyInjection; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE APPLICATION_EXTENSION_API_ONLY"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_SUPPRESS_WARNINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + USE_HEADERMAP = NO; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Development-Release"; + }; + 75FE922437F06C18503B957F /* Production-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = "Production-Debug"; + }; + 950B087A5036CEA20657EC16 /* Development-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = "Development-Debug"; + }; + A384D36B5732E0952C75C348 /* Development-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE=1", + ); + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; + INFOPLIST_FILE = "Derived/InfoPlists/DependencyInjection-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-package-name", + DependencyInjection, + "$(inherited)", + "-enable-upcoming-feature \"StrictConcurrency\"", + ); + PRODUCT_BUNDLE_IDENTIFIER = DependencyInjection; + PRODUCT_NAME = DependencyInjection; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited) SWIFT_PACKAGE APPLICATION_EXTENSION_API_ONLY", + DEBUG, + ); + SWIFT_COMPILATION_MODE = singlefile; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SUPPRESS_WARNINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + USE_HEADERMAP = NO; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Development-Debug"; + }; + B6663F9B8A758FC62002180D /* Production-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE=1", + ); + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; + INFOPLIST_FILE = "Derived/InfoPlists/DependencyInjection-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-package-name", + DependencyInjection, + "$(inherited)", + "-enable-upcoming-feature \"StrictConcurrency\"", + ); + PRODUCT_BUNDLE_IDENTIFIER = DependencyInjection; + PRODUCT_NAME = DependencyInjection; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( + "$(inherited) SWIFT_PACKAGE APPLICATION_EXTENSION_API_ONLY", + DEBUG, + ); + SWIFT_COMPILATION_MODE = singlefile; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SUPPRESS_WARNINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + USE_HEADERMAP = NO; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Production-Debug"; + }; + FC0473BE3DA6642EE0888FE2 /* Production-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "SWIFT_PACKAGE=1", + ); + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; + INFOPLIST_FILE = "Derived/InfoPlists/DependencyInjection-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_SWIFT_FLAGS = ( + "$(inherited)", + "-package-name", + DependencyInjection, + "$(inherited)", + "-enable-upcoming-feature \"StrictConcurrency\"", + ); + PRODUCT_BUNDLE_IDENTIFIER = DependencyInjection; + PRODUCT_NAME = DependencyInjection; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE APPLICATION_EXTENSION_API_ONLY"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_SUPPRESS_WARNINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + USE_HEADERMAP = NO; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Production-Release"; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2A8A546792FE3A4C3F2EBAAC /* Build configuration list for PBXProject "DependencyInjection" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 950B087A5036CEA20657EC16 /* Development-Debug */, + 3E150CB2E5A9FCFD1C934365 /* Development-Release */, + 75FE922437F06C18503B957F /* Production-Debug */, + 0B4CDCE67DBEE3BDBD9D9B00 /* Production-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Development-Release"; + }; + E0142061E08F2E181A8D4D2A /* Build configuration list for PBXNativeTarget "DependencyInjection" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A384D36B5732E0952C75C348 /* Development-Debug */, + 4E66FC02FE60654E3FBE9945 /* Development-Release */, + B6663F9B8A758FC62002180D /* Production-Debug */, + FC0473BE3DA6642EE0888FE2 /* Production-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Development-Release"; + }; +/* End XCConfigurationList section */ + }; + rootObject = 14C0EC1B68C144FE601BAFF5 /* Project object */; +} diff --git a/DependencyInjection.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DependencyInjection.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/DependencyInjection.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Derived/InfoPlists/DependencyInjection-Info.plist b/Derived/InfoPlists/DependencyInjection-Info.plist new file mode 100644 index 0000000..ae6e1f4 --- /dev/null +++ b/Derived/InfoPlists/DependencyInjection-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright ©. All rights reserved. + + diff --git a/Sources/Container/Async/AsyncContainer.swift b/Sources/Container/Async/AsyncContainer.swift index 1716f7f..211ec7a 100644 --- a/Sources/Container/Async/AsyncContainer.swift +++ b/Sources/Container/Async/AsyncContainer.swift @@ -14,6 +14,7 @@ public actor AsyncContainer: AsyncDependencyResolving, AsyncDependencyRegisterin private var registrations = [RegistrationIdentifier: AsyncRegistration]() private var sharedInstances = [RegistrationIdentifier: any Sendable]() + private var sharedTasks = [RegistrationIdentifier: Task]() /// Create new instance of ``AsyncContainer`` public init() {} @@ -28,6 +29,7 @@ public actor AsyncContainer: AsyncDependencyResolving, AsyncDependencyRegisterin /// Remove already instantiated shared instances from the container public func releaseSharedInstances() { sharedInstances.removeAll() + sharedTasks.removeAll() } // MARK: Register dependency @@ -50,6 +52,7 @@ public actor AsyncContainer: AsyncDependencyResolving, AsyncDependencyRegisterin // With a new registration we should clean all shared instances // because the new registered factory most likely returns different objects and we have no way to tell sharedInstances[registration.identifier] = nil + sharedTasks[registration.identifier] = nil } // MARK: Register dependency with arguments @@ -132,12 +135,21 @@ private extension AsyncContainer { ) } - func getDependency(from registration: AsyncRegistration, with argument: (any Sendable)? = nil) async throws -> Dependency { + func getDependency(from registration: AsyncRegistration, with argument: (any Sendable)? = ()) async throws -> Dependency { switch registration.scope { case .shared: if let dependency = sharedInstances[registration.identifier] as? Dependency { return dependency } + + if let task = sharedTasks[registration.identifier] { + do { + return try await task.value as! Dependency + } catch { + sharedTasks[registration.identifier] = nil + throw error + } + } case .new: break } @@ -145,15 +157,32 @@ private extension AsyncContainer { // We use force cast here because we are sure that the type-casting always succeed // The reason why the `factory` closure returns ``Any`` is that we have to erase the generic type in order to store the registration // When the registration is created it can be initialized just with a `factory` that returns the matching type - let dependency = try await registration.asyncRegistrationFactory(self, argument) as! Dependency + let task = Task { + try await registration.asyncRegistrationFactory(self, argument) + } - switch registration.scope { - case .shared: - sharedInstances[registration.identifier] = dependency - case .new: - break + if case .shared = registration.scope { + sharedTasks[registration.identifier] = task + } + + do { + let dependency = try await task.value as! Dependency + + switch registration.scope { + case .shared: + sharedInstances[registration.identifier] = dependency + sharedTasks[registration.identifier] = nil + case .new: + break + } + + return dependency + } catch { + if case .shared = registration.scope { + sharedTasks[registration.identifier] = nil + } + throw error } - return dependency } } diff --git a/Sources/Container/Sync/Container.swift b/Sources/Container/Sync/Container.swift index 49f854b..f359f1c 100644 --- a/Sources/Container/Sync/Container.swift +++ b/Sources/Container/Sync/Container.swift @@ -128,7 +128,7 @@ private extension Container { ) } - func getDependency(from registration: Registration, with argument: Any? = nil) throws -> Dependency { + func getDependency(from registration: Registration, with argument: Any? = ()) throws -> Dependency { switch registration.scope { case .shared: if let dependency = sharedInstances[registration.identifier] as? Dependency { diff --git a/Tests/Container/Async/AsyncBaseTests.swift b/Tests/Container/Async/AsyncBaseTests.swift index 6123a1a..ffd3db2 100644 --- a/Tests/Container/Async/AsyncBaseTests.swift +++ b/Tests/Container/Async/AsyncBaseTests.swift @@ -82,4 +82,109 @@ struct AsyncBaseTests { } } } + + @Test("Concurrent resolve of shared dependency") + func concurrentResolveSharedDependency() async { + // Given + let subject = AsyncContainer() + await subject.register(in: .shared) { _ -> SimpleDependency in + SimpleDependency() + } + + // When + let resolvedDependencies = await withTaskGroup(of: SimpleDependency.self) { group in + for _ in 0..<50 { + group.addTask { + await subject.resolve() + } + } + + var dependencies: [SimpleDependency] = [] + for await dependency in group { + dependencies.append(dependency) + } + + return dependencies + } + + // Then + guard let firstDependency = resolvedDependencies.first else { + Issue.record("Expected to resolve at least one dependency") + return + } + + #expect(resolvedDependencies.allSatisfy { $0 === firstDependency }) + } + + @Test("Concurrent register and resolve different types") + func concurrentRegisterAndResolveDifferentTypes() async { + // Given + let subject = AsyncContainer() + + // When + let resolvedDependencies = await withTaskGroup(of: Any.self) { group in + group.addTask { + await subject.register(in: .shared) { _ -> SimpleDependency in + SimpleDependency() + } + + let dependency: SimpleDependency = await subject.resolve() + return dependency + } + + group.addTask { + await subject.register { _, argument -> DependencyWithValueTypeParameter in + DependencyWithValueTypeParameter(subDependency: argument) + } + + let argument = StructureDependency(property1: "concurrent") + let dependency: DependencyWithValueTypeParameter = await subject.resolve(arguments: argument) + return dependency + } + + group.addTask { + await subject.register { _, argument -> DependencyWithAsyncInitWithParameter in + await DependencyWithAsyncInitWithParameter(subDependency: argument) + } + + let argument = StructureDependency(property1: "async") + let dependency: DependencyWithAsyncInitWithParameter = await subject.resolve(arguments: argument) + return dependency + } + + var dependencies: [Any] = [] + for await dependency in group { + dependencies.append(dependency) + } + + return dependencies + } + + // Then + #expect(resolvedDependencies.count == 3) + + let hasSimpleDependency = resolvedDependencies.contains { $0 is SimpleDependency } + #expect(hasSimpleDependency) + + let hasValueTypeParameter = resolvedDependencies.contains { $0 is DependencyWithValueTypeParameter } + #expect(hasValueTypeParameter) + + let hasAsyncInitParameter = resolvedDependencies.contains { $0 is DependencyWithAsyncInitWithParameter } + #expect(hasAsyncInitParameter) + } + + @Test("Register explicit type with resolver-only factory") + func registerExplicitTypeWithResolverOnlyFactory() async throws { + // Given + let subject = AsyncContainer() + await subject.register(type: SimpleDependency.self) { _ in + SimpleDependency() + } + + // When + let resolvedDependency = try await subject.tryResolve(type: SimpleDependency.self) + + // Then + #expect(resolvedDependency is SimpleDependency) + } } diff --git a/Tests/Container/Sync/BaseTests.swift b/Tests/Container/Sync/BaseTests.swift index cc9ded9..7b00628 100644 --- a/Tests/Container/Sync/BaseTests.swift +++ b/Tests/Container/Sync/BaseTests.swift @@ -124,4 +124,19 @@ struct BaseTests { } } } + + @Test("Register explicit type with resolver-only factory") + func registerExplicitTypeWithResolverOnlyFactory() throws { + // Given + let subject = Container() + subject.register(type: SimpleDependency.self) { _ in + SimpleDependency() + } + + // When + let resolvedDependency: SimpleDependency = try subject.tryResolve(type: SimpleDependency.self) + + // Then + #expect(resolvedDependency is SimpleDependency) + } }