Repository: unitycontainer/container Branch: master Commit: 7c89f7cb33c9 Files: 312 Total size: 776.1 KB Directory structure: gitextract_ldynwt33/ ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ └── regression.yml ├── .gitignore ├── LICENSE ├── README.md ├── appveyor.yml ├── codecov.yml ├── package.props ├── package.sln ├── src/ │ ├── Builder/ │ │ ├── Context/ │ │ │ ├── BuilderContext.cs │ │ │ └── BuilderContextExpression.cs │ │ └── Stages/ │ │ ├── BuilderStage.cs │ │ ├── SelectionStage.cs │ │ └── UnityBuildStage.cs │ ├── Events/ │ │ ├── ChildContainerCreatedEventArgs.cs │ │ ├── NamedEventArgs.cs │ │ ├── RegisterEventArgs.cs │ │ └── RegisterInstanceEventArgs.cs │ ├── Exceptions/ │ │ ├── DependencyMissingException.cs │ │ ├── IllegalInjectionMethodException.Desktop.cs │ │ ├── IllegalInjectionMethodException.cs │ │ ├── InvalidRegistrationException.cs │ │ └── MakeGenericTypeFailedException.cs │ ├── Extension/ │ │ ├── ExtensionContext.cs │ │ ├── IUnityContainerExtensionConfigurator.cs │ │ └── UnityContainerExtension.cs │ ├── Extensions/ │ │ ├── DefaultLifetime.cs │ │ ├── Diagnostic.cs │ │ ├── ExtensionExtensions.cs │ │ ├── Legacy.cs │ │ └── Strategies.cs │ ├── Factories/ │ │ ├── DeferredFuncResolverFactory.cs │ │ ├── EnumerableResolver.cs │ │ └── GenericLazyResolverFactory.cs │ ├── Injection/ │ │ └── Validating.cs │ ├── Legacy/ │ │ ├── DynamicMethod/ │ │ │ └── DynamicBuildPlanGenerationContext.cs │ │ ├── IBuildPlanCreatorPolicy.cs │ │ ├── IBuildPlanPolicy.cs │ │ ├── IConstructorSelectorPolicy.cs │ │ ├── IMethodSelectorPolicy.cs │ │ ├── IPropertySelectorPolicy.cs │ │ ├── InjectionParameterValue.cs │ │ ├── NamedTypeBuildKey.cs │ │ ├── TypeBasedOverride.cs │ │ └── TypedInjectionValue.cs │ ├── Lifetime/ │ │ ├── ContainerLifetimeManager.cs │ │ ├── InternalPerResolveLifetimeManager.cs │ │ └── LifetimeContainer.cs │ ├── Policy/ │ │ ├── Converter.cs │ │ ├── IResolveDelegateFactory.cs │ │ └── ISelect.cs │ ├── Processors/ │ │ ├── Abstracts/ │ │ │ ├── MemberExpression.cs │ │ │ ├── MemberProcessor.cs │ │ │ └── MemberResolution.cs │ │ ├── Constructor/ │ │ │ ├── ConstructorDiagnostic.cs │ │ │ ├── ConstructorExpression.cs │ │ │ ├── ConstructorProcessor.cs │ │ │ └── ConstructorResolution.cs │ │ ├── Fields/ │ │ │ ├── FieldDiagnostic.cs │ │ │ └── FieldProcessor.cs │ │ ├── Methods/ │ │ │ ├── MethodDiagnostic.cs │ │ │ └── MethodProcessor.cs │ │ ├── Parameters/ │ │ │ ├── ParametersDiagnostic.cs │ │ │ └── ParametersProcessor.cs │ │ └── Properties/ │ │ ├── PropertyDiagnostic.cs │ │ └── PropertyProcessor.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── Registration/ │ │ ├── ContainerRegistration.cs │ │ └── InternalRegistration.cs │ ├── Storage/ │ │ ├── HashRegistry.cs │ │ ├── IRegistry.cs │ │ ├── IStagedStrategyChain.cs │ │ ├── LinkedNode.cs │ │ ├── LinkedRegistry.cs │ │ ├── PolicyList.cs │ │ ├── QuickSet.cs │ │ ├── RegistrationSet.cs │ │ ├── Registrations.cs │ │ └── StagedStrategyChain.cs │ ├── Strategies/ │ │ ├── ArrayResolveStrategy.cs │ │ ├── BuildKeyMappingStrategy.cs │ │ ├── BuildPlanStrategy.cs │ │ ├── BuilderStrategy.cs │ │ └── LifetimeStrategy.cs │ ├── Unity.Container.csproj │ ├── Unity.Container.csproj.DotSettings │ ├── UnityContainer.ContainerContext.cs │ ├── UnityContainer.Diagnostic.cs │ ├── UnityContainer.IUnityContainer.cs │ ├── UnityContainer.Implementation.cs │ ├── UnityContainer.Public.cs │ ├── UnityContainer.Registration.cs │ ├── UnityContainer.Resolution.cs │ ├── Utility/ │ │ ├── ContainerConstants.cs │ │ └── HashHelpers.cs │ └── package.snk └── tests/ ├── Performance/ │ ├── Abstracts/ │ │ ├── BasicBase.cs │ │ └── RegistrationBase.cs │ ├── Configuration/ │ │ └── BenchmarkConfiguration.cs │ ├── Data/ │ │ ├── MultiType.cs │ │ └── TestData.cs │ ├── Performance.csproj │ ├── Program.cs │ └── Tests/ │ ├── Registration/ │ │ └── Registration.cs │ └── Resolution/ │ ├── Compiled.cs │ ├── PreCompiled.cs │ ├── PreResolved.cs │ └── Resolved.cs ├── Unity.Diagnostic/ │ ├── BuildUp.cs │ ├── Constructor.cs │ ├── Cyclic.cs │ ├── Field.cs │ ├── Hierarchical.cs │ ├── Issues.cs │ ├── Method.cs │ ├── Overrides.cs │ ├── Property.cs │ ├── Registration.cs │ └── Unity.Specification.Tests.Diagnostic.csproj ├── Unity.Specification/ │ ├── BuildUp.cs │ ├── Constructor.cs │ ├── Container/ │ │ ├── Hierachy.cs │ │ ├── IsRegistered.cs │ │ └── Registrations.cs │ ├── Factory/ │ │ ├── Registration.cs │ │ └── Resolution.cs │ ├── Field.cs │ ├── Issues.cs │ ├── Lifetime.cs │ ├── Method.cs │ ├── Parameter.cs │ ├── Property.cs │ ├── Registration.cs │ ├── Resolution/ │ │ ├── Array.cs │ │ ├── Basics.cs │ │ ├── Deferred.cs │ │ ├── Enumerable.cs │ │ ├── Generic.cs │ │ ├── Lazy.cs │ │ ├── Mapping.cs │ │ └── Overrides.cs │ └── Unity.Specification.Tests.csproj └── Unity.Tests/ ├── ChildContainer/ │ ├── ChildContainerInterfaceChangeFixture.cs │ ├── ITestContainer.cs │ ├── TestContainer.cs │ ├── TestContainer1.cs │ ├── TestContainer2.cs │ └── TestContainer3.cs ├── CollectionSupport/ │ ├── CollectionSupportFixture.cs │ ├── ConfigurationTestClass.cs │ ├── ConfigurationTestClassGeneric.cs │ ├── ITestInterface.cs │ ├── TestClass.cs │ ├── TestClassDerived.cs │ ├── TestClassWithArrayDependency.cs │ ├── TestClassWithDependencyArrayConstructor.cs │ ├── TestClassWithDependencyArrayMethod.cs │ ├── TestClassWithDependencyArrayProperty.cs │ ├── TestClassWithDependencyEnumerableConstructor.cs │ ├── TestClassWithDependencyTypeConstructor.cs │ ├── TestClassWithDependencyTypeMethod.cs │ └── TestClassWithEnumerableDependency.cs ├── Container/ │ ├── ContainerBuildUpFixture.cs │ ├── ContainerControlledLifetimeThreadingFixture.cs │ ├── ContainerDefaultContentFixture.cs │ ├── SeparateContainerFixture.cs │ ├── UnityExtensionFixture.cs │ └── UnityHierarchyFixture.cs ├── ContainerRegistration/ │ ├── AnotherTypeImplementation.cs │ ├── GivenContainerIntrospectionCorrectUsageFixture.cs │ ├── ITypeAnotherInterface.cs │ ├── ITypeInterface.cs │ └── TypeImplementation.cs ├── Extensions/ │ ├── DefaultLifetimeExtensionTests.cs │ ├── DiagnosticExtensionTests.cs │ └── LegacyExtensionTests.cs ├── Generics/ │ ├── ClassWithConstMethodandProperty.cs │ ├── Foo.cs │ ├── FooRepository.cs │ ├── GenMockLogger.cs │ ├── GenSpecialLogger.cs │ ├── GenericA.cs │ ├── GenericB.cs │ ├── GenericC.cs │ ├── GenericChainingFixture.cs │ ├── GenericConstraintsFixture.cs │ ├── GenericD.cs │ ├── GenericList.cs │ ├── GenericParameterFixture.cs │ ├── GenericResolvedArrayParameterFixture.cs │ ├── GenericsFixture.cs │ ├── GenericsReflectionExperimentsFixture.cs │ ├── HaveAGenericType.cs │ ├── HaveManyGenericTypes.cs │ ├── HaveManyGenericTypesClosed.cs │ ├── IFoo.cs │ ├── IGenLogger.cs │ ├── IHaveAGenericType.cs │ ├── IHaveManyGenericTypes.cs │ ├── IHaveManyGenericTypesClosed.cs │ ├── IRepository.cs │ ├── MockRespository.cs │ ├── Refer.cs │ └── Refer1.cs ├── Injection/ │ ├── InjectedMembersFixture.cs │ ├── InjectingArraysFixture.cs │ ├── OptionalDependencyAPIConfigurationFixture.cs │ ├── OptionalDependencyAttributeFixture.cs │ ├── OptionalDependencyFixture.cs │ └── OptionalGenericParameterFixture.cs ├── Issues/ │ ├── CodeGenBugFixture.cs │ ├── CodeplexIssuesFixture.cs │ └── GitHub.cs ├── Lifetime/ │ ├── A.cs │ ├── AA.cs │ ├── ATTest.cs │ ├── B.cs │ ├── BB.cs │ ├── HierarchicalLifetimeFixture.cs │ ├── I1.cs │ ├── I2.cs │ ├── ITTest.cs │ ├── LifetimeFixture.cs │ ├── PerResolveLifetimeFixture.cs │ └── UnityTestClass.cs ├── ObjectBuilder/ │ ├── BuildPlanAndChildContainerFixture.cs │ ├── LifetimeContainerTest.cs │ ├── StagedStrategyChainTest.cs │ └── Utility/ │ ├── ActivatorCreationStrategy.cs │ ├── AssertActualExpectedException.cs │ └── AssertHelper.cs ├── Override/ │ ├── IForToUndergoeInject.cs │ ├── IForTypeToInject.cs │ ├── IInterfaceForTypesToInject.cs │ ├── IInterfaceForTypesToInjectForPropertyOverride.cs │ ├── ISubjectTypeToInject.cs │ ├── ISubjectTypeToInjectForPropertyOverride.cs │ ├── MultiThreadedPropertyOverrideFixture.cs │ ├── MySimpleType.cs │ ├── MySimpleTypeForPropertyOverride.cs │ ├── SubjectType1ToInject.cs │ ├── SubjectType1ToInjectForPropertyOverride.cs │ ├── SubjectType2ToInject.cs │ ├── SubjectType2ToInjectForPropertyOverride.cs │ ├── SubjectType3ToInject.cs │ ├── SubjectType3ToInjectForPropertyOverride.cs │ ├── TestTypeInConfig.cs │ ├── TypeBasedOverrideFixture.cs │ ├── TypeToInject1.cs │ ├── TypeToInject1ForTypeOverride.cs │ ├── TypeToInject2.cs │ ├── TypeToInject2ForTypeOverride.cs │ ├── TypeToInject3.cs │ ├── TypeToInject3ForTypeOverride.cs │ ├── TypeToInjectForPropertyOverride1.cs │ ├── TypeToInjectForPropertyOverride2.cs │ ├── TypeToInjectForPropertyOverride3.cs │ ├── TypeToToUndergoeTypeBasedInject2.cs │ ├── TypeToToUndergoeTypeBasedInject3.cs │ └── TypeToUndergoeTypeBasedInject1.cs ├── Storage/ │ └── RegistrationSetTests.cs ├── TestDoubles/ │ ├── DependencyAttribute.cs │ ├── InjectionConstructorAttribute.cs │ ├── InjectionMethodAttribute.cs │ ├── MockContainerExtension.cs │ ├── MockContainerExtensionWithNonDefaultConstructor.cs │ ├── SpyExtension.cs │ ├── SpyPolicy.cs │ └── SpyStrategy.cs ├── TestObjects/ │ ├── DisposableObject.cs │ ├── EmailService.cs │ ├── FileLogger.cs │ ├── IBase.cs │ ├── IService.cs │ ├── NullLogger.cs │ ├── ObjectWithAmbiguousConstructors.cs │ ├── ObjectWithAmbiguousMarkedConstructor.cs │ ├── ObjectWithExplicitInterface.cs │ ├── ObjectWithInjectionConstructor.cs │ ├── ObjectWithLotsOfDependencies.cs │ ├── ObjectWithMarkedConstructor.cs │ ├── ObjectWithMultipleConstructors.cs │ ├── ObjectWithOneDependency.cs │ ├── ObjectWithStaticAndInstanceProperties.cs │ ├── ObjectWithTwoConstructorDependencies.cs │ └── OptionalLogger.cs ├── TestSupport/ │ ├── AssertExtensions.cs │ ├── AssertHelper.cs │ ├── CollectionAssertExtensions.cs │ ├── EnumerableAssertionExtensions.cs │ ├── EnumerableExtensions.cs │ ├── ExtensibilityTestExtension.cs │ ├── Guard.cs │ ├── IAdditionalInterface.cs │ ├── ILogger.cs │ ├── MockContainerExtension.cs │ ├── MockDatabase.cs │ ├── MockLogger.cs │ ├── NegativeTypeConverter.cs │ ├── ObjectUsingLogger.cs │ ├── ObjectWithOneConstructorDependency.cs │ ├── ObjectWithTwoConstructorParameters.cs │ ├── ObjectWithTwoProperties.cs │ ├── Pair.cs │ ├── Sequence.cs │ ├── SessionLifetimeManager.cs │ ├── SpecialLogger.cs │ └── TypeReflectionExtensions.cs └── Unity.Tests.csproj ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ ############################################################################### # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto ############################################################################### # Prevent merging of README.md ############################################################################### README.md merge=ours .gitmodules merge=ours *.yml merge=ours ================================================ FILE: .github/FUNDING.yml ================================================ github: [ENikS] open_collective: unity-container ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve --- --- name: Bug report about: Create a report to help us improve --- ### Description A clear and concise description of what is wrong. ### To Reproduce Please provide UnitTest in the form of: ```C# [TestMethod] public void SomeDescriptiveName() { var container = new UnityContainer() .RegisterType(); ... var res = container.Resolve>(); Assert.SomeFailingVerification(...); } ``` **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project --- ### Description Briefly explain the feature you are proposing to implement ### Problem Is your feature request related to a problem? Please describe. ### Solution A clear and concise description of what you want to happen. ### Impact Possible impact of the change on existing users. ================================================ FILE: .github/workflows/regression.yml ================================================ # https://dotnet.microsoft.com/download/dotnet-core # https://dotnet.microsoft.com/download/dotnet-framework name: Regression Tests on: push: branches: [ master, develop ] paths: - 'src/*' - 'test/*' - '.github/workflows/*' pull_request: branches: [ master, develop ] jobs: build: runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v2 with: path: Container - name: Cache id: unity-container uses: actions/cache@v1 with: path: '${{ github.workspace }}\Container\src\bin\Release' key: ${{ github.sha }} - name: Build env: PackageVersion: '0.0.0' run: dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True Container\src # TODO: add net40 net: needs: [ Build ] strategy: matrix: framework: ['net48', 'net47', 'net46', 'net45'] runs-on: windows-latest env: TargetFramework: ${{ matrix.framework }} steps: - name: Checkout Container uses: actions/checkout@v2 with: path: Container - name: Checkout Tests uses: actions/checkout@v2 with: repository: 'unitycontainer/specification-tests' path: SpecificationTests - name: Cache id: unity-container uses: actions/cache@v1 with: path: '${{ github.workspace }}\Container\src\bin\Release' key: ${{ github.sha }} - name: Build run: | dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}\Container\tests\Unity.Tests\Unity.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}\Container\tests\Unity.Specification\Unity.Specification.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}\Container\tests\Unity.Diagnostic\Unity.Specification.Tests.Diagnostic.csproj - name: Test run: | dotnet test ${{ github.workspace }}\Container\tests\Unity.Tests dotnet test ${{ github.workspace }}\Container\tests\Unity.Specification dotnet test ${{ github.workspace }}\Container\tests\Unity.Diagnostic core-lts-2: needs: [ Build ] strategy: matrix: os: [windows-latest] runs-on: ${{ matrix.os }} env: TargetFramework: netcoreapp2.0 steps: - name: Checkout Container uses: actions/checkout@v2 with: path: Container - name: Checkout Tests uses: actions/checkout@v2 with: repository: 'unitycontainer/specification-tests' path: SpecificationTests - name: Install DotNet uses: actions/setup-dotnet@v1 with: dotnet-version: '2.1.806' - name: Cache id: unity-container uses: actions/cache@v1 with: path: '${{ github.workspace }}/Container/src/bin/Release' key: ${{ github.sha }} - name: Build run: | dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Tests/Unity.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Specification/Unity.Specification.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Diagnostic/Unity.Specification.Tests.Diagnostic.csproj - name: Test run: | dotnet test ${{ github.workspace }}/Container/tests/Unity.Tests dotnet test ${{ github.workspace }}/Container/tests/Unity.Specification dotnet test ${{ github.workspace }}/Container/tests/Unity.Diagnostic core-lts-3: needs: [ Build ] strategy: matrix: os: [windows-latest, ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} env: TargetFramework: netcoreapp3.0 steps: - name: Checkout Container uses: actions/checkout@v2 with: path: Container - name: Checkout Tests uses: actions/checkout@v2 with: repository: 'unitycontainer/specification-tests' path: SpecificationTests - name: Install DotNet uses: actions/setup-dotnet@v1 with: dotnet-version: '3.1.202' - name: Cache id: unity-container uses: actions/cache@v1 with: path: '${{ github.workspace }}/Container/src/bin/Release' key: ${{ github.sha }} - name: Build run: | dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Tests/Unity.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Specification/Unity.Specification.Tests.csproj dotnet msbuild -property:Configuration=Release -verbosity:m -restore:True ${{ github.workspace }}/Container/tests/Unity.Diagnostic/Unity.Specification.Tests.Diagnostic.csproj - name: Test run: | dotnet test ${{ github.workspace }}/Container/tests/Unity.Tests dotnet test ${{ github.workspace }}/Container/tests/Unity.Specification dotnet test ${{ github.workspace }}/Container/tests/Unity.Diagnostic ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.sln.docstates # Build results [Dd]ebug/ [Rr]elease/ x64/ [Bb]in/ [Oo]bj/ [Ll]ib/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # Visual Studio 2015 cache/options directory .vs/ # DNX project.lock.json artifacts/ *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.log *.svclog *.scc # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # Click-Once directory publish/ # Publish Web Output *.Publish.xml *.pubxml *.azurePubxml # NuGet Packages Directory ## TODO: If you have NuGet Package Restore enabled, uncomment the next line packages/ ## TODO: If the tool you use requires repositories.config, also uncomment the next line !packages/repositories.config # Windows Azure Build Output csx/ *.build.csdef # Windows Store app package directory AppPackages/ # Others sql/ *.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.[Pp]ublish.xml *.publishsettings # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files App_Data/*.mdf App_Data/*.ldf # ========================= # Windows detritus # ========================= # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Mac desktop service store files .DS_Store _NCrunch* project.lock.json testresults.xml testresults.xml ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2020 .NET Foundation and Contributors All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ [![Build status](https://ci.appveyor.com/api/projects/status/s7s905q6xd6b2503/branch/master?svg=true)](https://ci.appveyor.com/project/unitycontainer/container/branch/master) ![Regression Tests](https://github.com/unitycontainer/container/workflows/Regression%20Tests/badge.svg?branch=master) [![License](https://img.shields.io/badge/license-apache%202.0-60C060.svg)](https://github.com/IoC-Unity/Unity/blob/master/LICENSE) [![NuGet](https://img.shields.io/nuget/dt/Unity.Container.svg)](https://www.nuget.org/packages/Unity.Container) [![NuGet](https://img.shields.io/nuget/v/Unity.Container.svg)](https://www.nuget.org/packages/Unity.Container) ## Overview The Unity Container (Unity) is a lightweight, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages: * Simplified object creation, especially for hierarchical object structures and dependencies * Abstraction of requirements; this allows developers to specify dependencies at run time or in configuration and simplify management of crosscutting concerns * Increased flexibility by deferring component configuration to the container * Service location capability; this allows clients to store or cache the container * Instance and type interception * Registration by convention ## Code of Conduct This project has adopted the code of conduct defined by the [Contributor Covenant](https://www.contributor-covenant.org/) to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](https://www.dotnetfoundation.org/code-of-conduct) ## Contributing See the [Contributing guide](https://github.com/unitycontainer/unity/blob/master/CONTRIBUTING.md) for more information. ## .NET Foundation Unity Container is a [.NET Foundation](https://dotnetfoundation.org/projects/unitycontainer) project ================================================ FILE: appveyor.yml ================================================ image: Visual Studio 2019 configuration: Release platform: Any CPU install: - ps: $env:build_version = (Select-Xml -Path ".\package.props" -XPath "/Project/PropertyGroup/VersionBase" | Select-Object -ExpandProperty Node).InnerText - ps: Update-AppveyorBuild -Version "$env:build_version.$env:APPVEYOR_BUILD_NUMBER" assembly_info: patch: false assembly_informational_version: "{version} $(GIT_HASH)" dotnet_csproj: patch: false before_build: - cmd: dotnet restore -v=n build: project: package.sln parallel: true verbosity: minimal after_build: - choco install opencover.portable - choco install codecov test_script: - OpenCover.Console.exe -register:user -target:"C:\Program Files\dotnet\dotnet.exe" -targetargs:"test --framework net46 --verbosity q" after_test: - codecov -f "results.xml" artifacts: - path: '**\Unity.*.nupkg' name: 'Unity' ================================================ FILE: codecov.yml ================================================ #ignore: #- "tests/*" # Ignore tests #- "src/Utility/*" # Ignore utilities #- "**/*.Designer.cs" # Ignore generated code ================================================ FILE: package.props ================================================ 5.11.11 This package is compatible with .NET Standard 1.0 and 2.0, .NET Core 1.0 and 2.0, .NET 4.0, 4.5, 4.6, 4.7 5.11.* netstandard2.0;netstandard1.0;netcoreapp3.0;netcoreapp2.0;netcoreapp1.0;net48;net47;net46;net45;net40 ================================================ FILE: package.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27004.2002 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Container", "src\Unity.Container.csproj", "{EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{13CA431F-C840-429D-A83D-BFDEDCCA0F6F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Tests", "tests\Unity.Tests\Unity.Tests.csproj", "{25E09D23-F407-4A61-8446-E5FBD6F689B8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Debug|Any CPU.Build.0 = Debug|Any CPU {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Release|Any CPU.ActiveCfg = Release|Any CPU {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Release|Any CPU.Build.0 = Release|Any CPU {25E09D23-F407-4A61-8446-E5FBD6F689B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25E09D23-F407-4A61-8446-E5FBD6F689B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {25E09D23-F407-4A61-8446-E5FBD6F689B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {25E09D23-F407-4A61-8446-E5FBD6F689B8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {25E09D23-F407-4A61-8446-E5FBD6F689B8} = {13CA431F-C840-429D-A83D-BFDEDCCA0F6F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D864CD1-AEA6-4EDF-B8F8-071CE7F88251} EndGlobalSection EndGlobal ================================================ FILE: src/Builder/Context/BuilderContext.cs ================================================ using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using Unity.Exceptions; using Unity.Lifetime; using Unity.Policy; using Unity.Registration; using Unity.Resolution; using Unity.Strategies; namespace Unity.Builder { /// /// Represents the context in which a build-up or tear-down operation runs. /// [SecuritySafeCritical] [DebuggerDisplay("Resolving: {Type}, Name: {Name}")] public struct BuilderContext : IResolveContext { #region Fields public ResolverOverride[] Overrides; public IPolicyList List; public delegate object ExecutePlanDelegate(BuilderStrategy[] chain, ref BuilderContext context); public delegate object ResolvePlanDelegate(ref BuilderContext context, ResolveDelegate resolver); #endregion #region IResolveContext public IUnityContainer Container => Lifetime?.Container; public Type Type { get; set; } public string Name { get; set; } public object Resolve(Type type, string name) { // Process overrides if any if (null != Overrides) { NamedType namedType = new NamedType { Type = type, Name = name }; // Check if this parameter is overridden for (var index = Overrides.Length - 1; index >= 0; --index) { var resolverOverride = Overrides[index]; // If matches with current parameter if (resolverOverride is IResolve resolverPolicy && resolverOverride is IEquatable comparer && comparer.Equals(namedType)) { var context = this; return ResolvePlan(ref context, resolverPolicy.Resolve); } } } return Resolve(type, name, (InternalRegistration)((UnityContainer)Container).GetRegistration(type, name)); } #endregion #region IPolicyList public object Get(Type policyInterface) { return List.Get(RegistrationType, Name, policyInterface) ?? Registration.Get(policyInterface); } public object Get(Type type, string name, Type policyInterface) { return List.Get(type, name, policyInterface) ?? (type != RegistrationType || name != Name ? ((UnityContainer)Container).GetPolicy(type, name, policyInterface) : Registration.Get(policyInterface)); } public object Get(Type type, Type policyInterface) { return List.Get(type, UnityContainer.All, policyInterface) ?? ((UnityContainer)Container).GetPolicy(type, UnityContainer.All, policyInterface); } public void Set(Type policyInterface, object policy) { List.Set(RegistrationType, Name, policyInterface, policy); } public void Set(Type type, Type policyInterface, object policy) { List.Set(type, UnityContainer.All, policyInterface, policy); } public void Set(Type type, string name, Type policyInterface, object policy) { List.Set(type, name, policyInterface, policy); } public void Clear(Type type, string name, Type policyInterface) { List.Clear(type, name, policyInterface); } #endregion #region Registration public Type RegistrationType { get; set; } public IPolicySet Registration { get; set; } #endregion #region Public Properties public object Existing { get; set; } public ILifetimeContainer Lifetime; public SynchronizedLifetimeManager RequiresRecovery; public bool BuildComplete; public Type DeclaringType; #if !NET40 public IntPtr Parent; #endif public ExecutePlanDelegate ExecutePlan; public ResolvePlanDelegate ResolvePlan; #endregion #region Public Methods public object Resolve(Type type, string name, InternalRegistration registration) { unsafe { var thisContext = this; var containerRegistration = registration as ContainerRegistration; var container = registration.Get(typeof(LifetimeManager)) is ContainerControlledLifetimeManager manager ? ((UnityContainer)manager.Scope).LifetimeContainer : Lifetime; var context = new BuilderContext { Lifetime = container, Registration = registration, RegistrationType = type, Name = name, Type = null != containerRegistration ? containerRegistration.Type : type, ExecutePlan = ExecutePlan, ResolvePlan = ResolvePlan, List = List, Overrides = Overrides, DeclaringType = Type, #if !NET40 Parent = new IntPtr(Unsafe.AsPointer(ref thisContext)) #endif }; return ExecutePlan(registration.BuildChain, ref context); } } public object Resolve(ParameterInfo parameter, object value) { var context = this; // Process overrides if any if (null != Overrides) { // Check if this parameter is overridden for (var index = Overrides.Length - 1; index >= 0; --index) { var resolverOverride = Overrides[index]; // If matches with current parameter if (resolverOverride is IEquatable comparer && comparer.Equals(parameter)) { // Check if itself is a value if (resolverOverride is IResolve resolverPolicy) { return ResolvePlan(ref context, resolverPolicy.Resolve); } // Try to create value var resolveDelegate = resolverOverride.GetResolver(parameter.ParameterType); if (null != resolveDelegate) { return ResolvePlan(ref context, resolveDelegate); } } } } // Resolve from injectors switch (value) { case ParameterInfo info when ReferenceEquals(info, parameter): return Resolve(parameter.ParameterType, null); case ResolveDelegate resolver: return resolver(ref context); } return value; } public object Resolve(PropertyInfo property, object value) { var context = this; // Process overrides if any if (null != Overrides) { // Check for property overrides for (var index = Overrides.Length - 1; index >= 0; --index) { var resolverOverride = Overrides[index]; // Check if this parameter is overridden if (resolverOverride is IEquatable comparer && comparer.Equals(property)) { // Check if itself is a value if (resolverOverride is IResolve resolverPolicy) { return ResolvePlan(ref context, resolverPolicy.Resolve); } // Try to create value var resolveDelegate = resolverOverride.GetResolver(property.PropertyType); if (null != resolveDelegate) { return ResolvePlan(ref context, resolveDelegate); } } } } // Resolve from injectors switch (value) { case PropertyInfo info when ReferenceEquals(info, property): return Resolve(info.PropertyType, null); case DependencyAttribute dependencyAttribute: return Resolve(property.PropertyType, dependencyAttribute.Name); case OptionalDependencyAttribute optionalAttribute: try { return Resolve(property.PropertyType, optionalAttribute.Name); } catch (Exception ex) when (!(ex.InnerException is CircularDependencyException)) { return null; } case ResolveDelegate resolver: return resolver(ref context); } return value; } public object Resolve(FieldInfo field, object value) { var context = this; // Process overrides if any if (null != Overrides) { // Check for property overrides for (var index = Overrides.Length - 1; index >= 0; --index) { var resolverOverride = Overrides[index]; // Check if this parameter is overridden if (resolverOverride is IEquatable comparer && comparer.Equals(field)) { // Check if itself is a value if (resolverOverride is IResolve resolverPolicy) { return ResolvePlan(ref context, resolverPolicy.Resolve); } // Try to create value var resolveDelegate = resolverOverride.GetResolver(field.FieldType); if (null != resolveDelegate) { return ResolvePlan(ref context, resolveDelegate); } } } } // Resolve from injectors switch (value) { case FieldInfo info when ReferenceEquals(info, field): return Resolve(info.FieldType, null); case DependencyAttribute dependencyAttribute: return Resolve(field.FieldType, dependencyAttribute.Name); case OptionalDependencyAttribute optionalAttribute: try { return Resolve(field.FieldType, optionalAttribute.Name); } catch (Exception ex) when (!(ex.InnerException is CircularDependencyException)) { return null; } case ResolveDelegate resolver: return resolver(ref context); } return value; } #endregion } } ================================================ FILE: src/Builder/Context/BuilderContextExpression.cs ================================================ using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Resolution; namespace Unity.Builder { public class BuilderContextExpression : IResolveContextExpression { #region Fields public static readonly MethodInfo ResolvePropertyMethod = typeof(BuilderContext).GetTypeInfo() .GetDeclaredMethods(nameof(BuilderContext.Resolve)) .First(m => { var parameters = m.GetParameters(); return 0 < parameters.Length && typeof(PropertyInfo) == parameters[0].ParameterType; }); public static readonly MethodInfo ResolveFieldMethod = typeof(BuilderContext).GetTypeInfo() .GetDeclaredMethods(nameof(BuilderContext.Resolve)) .First(m => { var parameters = m.GetParameters(); return 0 < parameters.Length && typeof(FieldInfo) == parameters[0].ParameterType; }); public static readonly MethodInfo ResolveParameterMethod = typeof(BuilderContext).GetTypeInfo() .GetDeclaredMethods(nameof(BuilderContext.Resolve)) .First(m => { var parameters = m.GetParameters(); return 0 < parameters.Length && typeof(ParameterInfo) == parameters[0].ParameterType; }); public static readonly MethodInfo SetMethod = typeof(BuilderContext).GetTypeInfo() .GetDeclaredMethods(nameof(BuilderContext.Set)) .First(m => 2 == m.GetParameters().Length); #endregion #region Constructor static BuilderContextExpression() { var typeInfo = typeof(BuilderContext).GetTypeInfo(); Existing = Expression.MakeMemberAccess(Context, typeInfo.GetDeclaredProperty(nameof(BuilderContext.Existing))); } #endregion #region Public Properties public static readonly MemberExpression Existing; #endregion } } ================================================ FILE: src/Builder/Stages/BuilderStage.cs ================================================  namespace Unity.Builder { /// /// Enumeration to represent the object builder stages. /// /// /// The order of the values in the enumeration is the order in which the stages are run. /// public enum BuilderStage { /// /// Strategies in this stage run before creation. Typical work done in this stage might /// include strategies that use reflection to set policies into the context that other /// strategies would later use. /// PreCreation, /// /// Strategies in this stage create objects. Typically you will only have a single policy-driven /// creation strategy in this stage. /// Creation, /// /// Strategies in this stage work on created objects. /// Initialization, /// /// Strategies in this stage initialize fields. /// Fields, /// /// Strategies in this stage work initialize properties. /// Properties, /// /// Strategies in this stage do method calls. /// Methods, /// /// Strategies in this stage work on objects that are already initialized. Typical work done in /// this stage might include looking to see if the object implements some notification interface /// to discover when its initialization stage has been completed. /// PostInitialization } } ================================================ FILE: src/Builder/Stages/SelectionStage.cs ================================================ namespace Unity.Builder { public enum SelectionStage { Injected = 0, Custom = 1, Default = 2 } } ================================================ FILE: src/Builder/Stages/UnityBuildStage.cs ================================================  namespace Unity.Builder { /// /// The build stages we use in the Unity container /// strategy pipeline. /// public enum UnityBuildStage { /// /// First stage. By default, nothing happens here. /// Setup, /// /// Stage where Array or IEnumerable is resolved /// Enumerable, /// /// Third stage. lifetime managers are checked here, /// and if they're available the rest of the pipeline is skipped. /// Lifetime, /// /// Second stage. Type mapping occurs here. /// TypeMapping, /// /// Fourth stage. Reflection over constructors, properties, etc. is /// performed here. /// PreCreation, /// /// Fifth stage. Instance creation happens here. /// Creation, /// /// Sixth stage. Property sets and method injection happens here. /// Initialization, /// /// Seventh and final stage. By default, nothing happens here. /// PostInitialization } } ================================================ FILE: src/Events/ChildContainerCreatedEventArgs.cs ================================================  using System; using Unity.Extension; namespace Unity.Events { /// /// Event argument class for the event. /// public class ChildContainerCreatedEventArgs : EventArgs { /// /// Construct a new object with the /// given child container object. /// /// An for the newly created child /// container. public ChildContainerCreatedEventArgs(ExtensionContext childContext) { ChildContext = childContext; } /// /// The newly created child container. /// public IUnityContainer ChildContainer => ChildContext.Container; /// /// An extension context for the created child container. /// public ExtensionContext ChildContext { get; } } } ================================================ FILE: src/Events/NamedEventArgs.cs ================================================  using System; namespace Unity.Events { /// /// An EventArgs class that holds a string Name. /// public abstract class NamedEventArgs : EventArgs { private string _name; /// /// Create a new with a null name. /// protected NamedEventArgs() { } /// /// Create a new with the given name. /// /// Name to store. protected NamedEventArgs(string name) { _name = name; } /// /// The name. /// /// Name used for this EventArg object. public virtual string Name { get => _name; set => _name = value; } } } ================================================ FILE: src/Events/RegisterEventArgs.cs ================================================ using System; using Unity.Extension; using Unity.Lifetime; namespace Unity.Events { /// /// Event argument class for the event. /// public class RegisterEventArgs : NamedEventArgs { /// /// Create a new instance of . /// /// Type to map from. /// Type to map to. /// Name for the registration. /// to manage instances. public RegisterEventArgs(Type typeFrom, Type typeTo, string name, LifetimeManager lifetimeManager) : base(name) { TypeFrom = typeFrom; TypeTo = typeTo; LifetimeManager = lifetimeManager; } /// /// Type to map from. /// public Type TypeFrom { get; } /// /// Type to map to. /// public Type TypeTo { get; } /// /// to manage instances. /// public LifetimeManager LifetimeManager { get; } } } ================================================ FILE: src/Events/RegisterInstanceEventArgs.cs ================================================ using System; using Unity.Extension; using Unity.Lifetime; namespace Unity.Events { /// /// Event argument class for the event. /// public class RegisterInstanceEventArgs : NamedEventArgs { /// /// Create a default instance. /// public RegisterInstanceEventArgs() { } /// /// Create a instance initialized with the given arguments. /// /// Type of instance being registered. /// The instance object itself. /// Name to register under, null if default registration. /// object that handles how /// the instance will be owned. public RegisterInstanceEventArgs(Type registeredType, object instance, string name, LifetimeManager lifetimeManager) : base(name) { RegisteredType = registeredType; Instance = instance; LifetimeManager = lifetimeManager; } /// /// Type of instance being registered. /// /// /// Type of instance being registered. /// public Type RegisteredType { get; } /// /// Instance object being registered. /// /// Instance object being registered public object Instance { get; } /// /// that controls ownership of /// this instance. /// public LifetimeManager LifetimeManager { get; } } } ================================================ FILE: src/Exceptions/DependencyMissingException.cs ================================================ using System; using System.Globalization; namespace Unity.Exceptions { /// /// Represents that a dependency could not be resolved. /// public class DependencyMissingException : Exception { /// /// Initializes a new instance of the class with no extra information. /// public DependencyMissingException() { } /// /// Initializes a new instance of the class with the given message. /// /// Some random message. public DependencyMissingException(string message) : base(message) { } /// /// Initialize a new instance of the class with the given /// message and inner exception. /// /// Some random message /// Inner exception. public DependencyMissingException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the class with the build key of the object begin built. /// /// The build key of the object begin built. public DependencyMissingException(object buildKey) : base(string.Format(CultureInfo.CurrentCulture, Error.MissingDependency, buildKey)) { } } } ================================================ FILE: src/Exceptions/IllegalInjectionMethodException.Desktop.cs ================================================ using System; namespace Unity.Exceptions { /// /// The exception thrown when injection is attempted on a method /// that is an open generic or has out or ref params. /// [Serializable] public partial class IllegalInjectionMethodException { } } ================================================ FILE: src/Exceptions/IllegalInjectionMethodException.cs ================================================  using System; namespace Unity.Exceptions { /// /// The exception thrown when injection is attempted on a method /// that is an open generic or has out or ref params. /// public partial class IllegalInjectionMethodException : Exception { /// /// Construct a new with no /// message. /// public IllegalInjectionMethodException() { } /// /// Construct a with the given message /// /// Message to return. public IllegalInjectionMethodException(string message) : base(message) { } /// /// Construct a with the given message /// and inner exception. /// /// Message to return. /// Inner exception public IllegalInjectionMethodException(string message, Exception innerException) : base(message, innerException) { } } } ================================================ FILE: src/Exceptions/InvalidRegistrationException.cs ================================================ using System; namespace Unity.Exceptions { internal class InvalidRegistrationException : Exception { public InvalidRegistrationException() : base() { } public InvalidRegistrationException(string message, Exception exception) : base(message, exception) { } } } ================================================ FILE: src/Exceptions/MakeGenericTypeFailedException.cs ================================================ using System; namespace Unity.Exceptions { internal class MakeGenericTypeFailedException : Exception { public MakeGenericTypeFailedException(ArgumentException innerException) : base("MakeGenericType failed", innerException) { } } } ================================================ FILE: src/Extension/ExtensionContext.cs ================================================ using System; using Unity.Builder; using Unity.Events; using Unity.Injection; using Unity.Lifetime; using Unity.Policy; using Unity.Processors; using Unity.Storage; using Unity.Strategies; namespace Unity.Extension { /// /// The class provides the means for extension objects /// to manipulate the internal state of the . /// public abstract class ExtensionContext { #region Container /// /// The container that this context is associated with. /// /// The object. public abstract IUnityContainer Container { get; } /// /// The that this container uses. /// /// The is used to manage objects that the container is managing. public abstract ILifetimeContainer Lifetime { get; } #endregion #region Strategies /// /// The strategies this container uses. /// /// The that the container uses to build objects. public abstract IStagedStrategyChain Strategies { get; } /// /// The strategies this container uses to construct build plans. /// /// The that this container uses when creating /// build plans. public abstract IStagedStrategyChain BuildPlanStrategies { get; } #endregion #region Policy Lists /// /// The policies this container uses. /// /// The the that container uses to build objects. public abstract IPolicyList Policies { get; } #endregion #region Events /// /// This event is raised when the /// /// method, or one of its overloads, is called. /// public abstract event EventHandler Registering; /// /// This event is raised when the method, /// or one of its overloads, is called. /// public abstract event EventHandler RegisteringInstance; /// /// This event is raised when the method is called, providing /// the newly created child container to extensions to act on as they see fit. /// public abstract event EventHandler ChildContainerCreated; #endregion } } ================================================ FILE: src/Extension/IUnityContainerExtensionConfigurator.cs ================================================  namespace Unity.Extension { /// /// Base interface for all extension configuration interfaces. /// public interface IUnityContainerExtensionConfigurator { /// /// Retrieve the container instance that we are currently configuring. /// IUnityContainer Container { get; } } } ================================================ FILE: src/Extension/UnityContainerExtension.cs ================================================  using System; namespace Unity.Extension { /// /// Base class for all extension objects. /// public abstract class UnityContainerExtension : IUnityContainerExtensionConfigurator { private IUnityContainer _container; private ExtensionContext _context; /// /// The container calls this method when the extension is added. /// /// A instance that gives the /// extension access to the internals of the container. public void InitializeExtension(ExtensionContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _container = context.Container; _context = context; Initialize(); } /// /// The container this extension has been added to. /// /// The that this extension has been added to. public IUnityContainer Container => _container; /// /// The object used to manipulate /// the inner state of the container. /// protected ExtensionContext Context => _context; /// /// Initial the container with this extension's functionality. /// /// /// When overridden in a derived class, this method will modify the given /// by adding strategies, policies, etc. to /// install it's functions into the container. protected abstract void Initialize(); /// /// Removes the extension's functions from the container. /// /// /// /// This method is called when extensions are being removed from the container. It can be /// used to do things like disconnect event handlers or clean up member state. You do not /// need to remove strategies or policies here; the container will do that automatically. /// /// /// The default implementation of this method does nothing. /// public virtual void Remove() { // Do nothing by default, can be overridden to do whatever you want. } } } ================================================ FILE: src/Extensions/DefaultLifetime.cs ================================================ using System; using Unity.Extension; using Unity.Lifetime; namespace Unity { public class DefaultLifetime : UnityContainerExtension { protected override void Initialize() { } #region Public Members public ITypeLifetimeManager TypeDefaultLifetime { get => (ITypeLifetimeManager)((UnityContainer)Container).TypeLifetimeManager; set => ((UnityContainer)Container).TypeLifetimeManager = (LifetimeManager)value ?? throw new ArgumentNullException("Type Lifetime Manager can not be null"); } public IInstanceLifetimeManager InstanceDefaultLifetime { get => (IInstanceLifetimeManager)((UnityContainer)Container).InstanceLifetimeManager; set => ((UnityContainer)Container).InstanceLifetimeManager = (LifetimeManager)value ?? throw new ArgumentNullException("Instance Lifetime Manager can not be null"); } public IFactoryLifetimeManager FactoryDefaultLifetime { get => (IFactoryLifetimeManager)((UnityContainer)Container).FactoryLifetimeManager; set => ((UnityContainer)Container).FactoryLifetimeManager = (LifetimeManager)value ?? throw new ArgumentNullException("Factory Lifetime Manager can not be null"); } #endregion } } ================================================ FILE: src/Extensions/Diagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using Unity.Extension; using Unity.Factories; using Unity.Policy; namespace Unity { /// /// Diagnostic extension implements validating when calling , /// , and methods. When executed /// these methods provide extra layer of verification and validation as well /// as more detailed reporting of error conditions. /// /// /// /// Unity uses reflection to gather information about types, members, and parameters. /// It is quite obvious that it takes significant amount of time during execution. So, /// to optimize performance all these verifications where moved to the Diagnostic /// extension. It is recommended to include this extension only during /// development cycle and refrain from executing it in production /// environment. /// /// /// This extension can be registered in two ways: by adding an extension or by calling /// EnableDiagnostic() extension method on container. /// Adding extension to container will work in any build, where EnableDiagnostic() /// will only enable it in DEBUG mode. /// /// /// /// /// var container = new UnityContainer(); /// #if DEBUG /// container.AddExtension(new Diagnostic()); /// #endif /// /// /// var container = new UnityContainer(); /// container.EnableDiagnostic(); /// /// public class Diagnostic : UnityContainerExtension { protected override void Initialize() { ((UnityContainer)Container).SetDefaultPolicies = UnityContainer.SetDiagnosticPolicies; ((UnityContainer)Container).SetDefaultPolicies((UnityContainer)Container); EnumerableResolver.EnumerableMethod = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.DiagnosticResolver)); EnumerableResolver.EnumerableFactory = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.DiagnosticResolverFactory)); } } public static class DiagnosticExtensions { /// /// Enables diagnostic validations on the container built in DEBUG mode. /// /// /// This extension method adds extension to the /// container and enables extended validation for all container's operations. /// This method will only work if the calling code is built with DEBUG /// symbol defined. In other word in you building in Debug mode. Conditional /// methods can not return any values, so fluent notation can not be used with /// this method. /// /// /// This is how you could call this method to enable diagnostics: /// /// var container = new UnityContainer(); /// container.EnableDebugDiagnostic(); /// ... /// /// /// The Unity Container instance [Conditional("DEBUG")] public static void EnableDebugDiagnostic(this UnityContainer container) { if (null == container) throw new ArgumentNullException(nameof(container)); container.AddExtension(new Diagnostic()); } /// /// Enables diagnostic validations on the container. /// /// /// This extension method adds extension to the /// container and enables extended validation for all container's operations. /// This method works regardless of the build mode. In other word, it will /// always enable validation. This method could be used with fluent notation. /// /// /// This is how you could call this method to enable diagnostics: /// /// var container = new UnityContainer().EnableDebugDiagnostic(); /// ... /// /// /// The Unity Container instance /// public static UnityContainer EnableDiagnostic(this UnityContainer container) { if (null == container) throw new ArgumentNullException(nameof(container)); container.AddExtension(new Diagnostic()); return container; } } } ================================================ FILE: src/Extensions/ExtensionExtensions.cs ================================================ using System; using Unity.Extension; namespace Unity { /// /// Extension class that adds a set of convenience overloads to the /// interface. /// public static class ExtensionExtensions { #region Extension management and configuration /// /// Add an extension to the container. /// /// to add. /// The object that this method was called on (this in C#, Me in Visual Basic). public static IUnityContainer AddExtension(this IUnityContainer container, IUnityContainerExtensionConfigurator extension) { return ((UnityContainer)container ?? throw new ArgumentNullException(nameof(container))).AddExtension(extension); } /// /// Resolve access to a configuration interface exposed by an extension. /// /// Extensions can expose configuration interfaces as well as adding /// strategies and policies to the container. This method walks the list of /// added extensions and returns the first one that implements the requested type. /// /// of configuration interface required. /// The requested extension's configuration interface, or null if not found. public static object Configure(this IUnityContainer container, Type configurationInterface) { return ((UnityContainer)container ?? throw new ArgumentNullException(nameof(container))).Configure(configurationInterface); } /// /// Creates a new extension object and adds it to the container. /// /// Type of to add. The extension type /// will be resolved from within the supplied . /// Container to add the extension to. /// The object that this method was called on (this in C#, Me in Visual Basic). public static IUnityContainer AddNewExtension(this IUnityContainer container) where TExtension : UnityContainerExtension { TExtension newExtension = (container ?? throw new ArgumentNullException(nameof(container))).Resolve(); return container.AddExtension(newExtension); } /// /// Resolve access to a configuration interface exposed by an extension. /// /// Extensions can expose configuration interfaces as well as adding /// strategies and policies to the container. This method walks the list of /// added extensions and returns the first one that implements the requested type. /// /// The configuration interface required. /// Container to configure. /// The requested extension's configuration interface, or null if not found. public static TConfigurator Configure(this IUnityContainer container) where TConfigurator : IUnityContainerExtensionConfigurator { return (TConfigurator)(container ?? throw new ArgumentNullException(nameof(container))).Configure(typeof(TConfigurator)); } #endregion } } ================================================ FILE: src/Extensions/Legacy.cs ================================================ using System.Linq; using Unity.Builder; using Unity.Processors; using Unity.Storage; namespace Unity.Extension { public class Legacy : UnityContainerExtension { protected override void Initialize() { var strategies = (StagedStrategyChain)Context.BuildPlanStrategies; var processor = (ConstructorProcessor)strategies.First(s => s is ConstructorProcessor); processor.SelectMethod = processor.LegacySelector; } } } ================================================ FILE: src/Extensions/Strategies.cs ================================================ using Unity.Extension; using Unity.Policy; namespace Unity { /// /// This extension forces the container to only use activated strategies during resolution /// /// /// This extension forces compatibility with systems without support for runtime compilers. /// One of such systems is iOS. /// public class ForceActivation : UnityContainerExtension { protected override void Initialize() { var unity = (UnityContainer)Container; unity._buildStrategy = unity.ResolvingFactory; unity.Defaults.Set(typeof(ResolveDelegateFactory), unity._buildStrategy); } } /// /// This extension forces the container to only use compiled strategies during resolution /// public class ForceCompillation : UnityContainerExtension { protected override void Initialize() { var unity = (UnityContainer)Container; unity._buildStrategy = unity.CompilingFactory; unity.Defaults.Set(typeof(ResolveDelegateFactory), unity._buildStrategy); } } } ================================================ FILE: src/Factories/DeferredFuncResolverFactory.cs ================================================ using System; using System.Reflection; using Unity.Builder; using Unity.Policy; using Unity.Resolution; namespace Unity.Factories { internal class DeferredFuncResolverFactory { private static readonly MethodInfo DeferredResolveMethodInfo = typeof(DeferredFuncResolverFactory).GetTypeInfo() .GetDeclaredMethod(nameof(DeferredResolve)); public static ResolveDelegate DeferredResolveDelegateFactory(ref BuilderContext context) { var typeToBuild = context.Type.GetTypeInfo().GenericTypeArguments[0]; var factoryMethod = DeferredResolveMethodInfo.MakeGenericMethod(typeToBuild); return (ResolveDelegate)factoryMethod.CreateDelegate(typeof(ResolveDelegate)); } private static Func DeferredResolve(ref BuilderContext context) { var nameToBuild = context.Name; var container = context.Container; return () => (T)container.Resolve(nameToBuild); } } } ================================================ FILE: src/Factories/EnumerableResolver.cs ================================================ using System; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Policy; using Unity.Resolution; namespace Unity.Factories { public class EnumerableResolver { #region Fields internal static MethodInfo EnumerableMethod = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.Resolver)); internal static MethodInfo EnumerableFactory = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.ResolverFactory)); #endregion #region ResolveDelegateFactory public static ResolveDelegateFactory Factory = (ref BuilderContext context) => { #if NETSTANDARD1_0 || NETCOREAPP1_0 || NET40 var typeArgument = context.Type.GetTypeInfo().GenericTypeArguments.First(); if (typeArgument.GetTypeInfo().IsGenericType) #else var typeArgument = context.Type.GenericTypeArguments.First(); if (typeArgument.IsGenericType) #endif { return ((EnumerableFactoryDelegate) EnumerableFactory.MakeGenericMethod(typeArgument) .CreateDelegate(typeof(EnumerableFactoryDelegate)))(); } else { return (ResolveDelegate) EnumerableMethod.MakeGenericMethod(typeArgument) .CreateDelegate(typeof(ResolveDelegate)); } }; #endregion #region Implementation private static object Resolver(ref BuilderContext context) { return ((UnityContainer)context.Container).ResolveEnumerable(context.Resolve, context.Name); } private static ResolveDelegate ResolverFactory() { Type type = typeof(TElement).GetGenericTypeDefinition(); return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable(c.Resolve, type, c.Name); } internal static object DiagnosticResolver(ref BuilderContext context) { return ((UnityContainer)context.Container).ResolveEnumerable(context.Resolve, context.Name).ToArray(); } internal static ResolveDelegate DiagnosticResolverFactory() { Type type = typeof(TElement).GetGenericTypeDefinition(); return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable(c.Resolve, type, c.Name).ToArray(); } #endregion #region Nested Types private delegate ResolveDelegate EnumerableFactoryDelegate(); #endregion } } ================================================ FILE: src/Factories/GenericLazyResolverFactory.cs ================================================ using System; using System.Reflection; using Unity.Builder; using Unity.Lifetime; using Unity.Resolution; using Unity.Strategies; namespace Unity.Factories { /// /// An Resolver Delegate Factory implementation /// that constructs a build plan for creating objects. /// internal class GenericLazyResolverFactory { #region Fields private static readonly MethodInfo BuildResolveLazyMethod = typeof(GenericLazyResolverFactory).GetTypeInfo() .GetDeclaredMethod(nameof(BuildResolveLazy)); #endregion #region ResolveDelegateFactory public static ResolveDelegate GetResolver(ref BuilderContext context) { var itemType = context.Type.GetTypeInfo().GenericTypeArguments[0]; var lazyMethod = BuildResolveLazyMethod.MakeGenericMethod(itemType); return (ResolveDelegate)lazyMethod.CreateDelegate(typeof(ResolveDelegate)); } #endregion #region Implementation private static object BuildResolveLazy(ref BuilderContext context) { var container = context.Container; var name = context.Name; context.Existing = new Lazy(() => container.Resolve(name)); var lifetime = BuilderStrategy.GetPolicy(ref context); if (lifetime is PerResolveLifetimeManager) { var perBuildLifetime = new InternalPerResolveLifetimeManager(context.Existing); context.Set(typeof(LifetimeManager), perBuildLifetime); } return context.Existing; } #endregion } } ================================================ FILE: src/Injection/Validating.cs ================================================ using System; using System.Linq; using System.Reflection; namespace Unity.Injection { public static class Validating { public static Func ConstructorSelector = (Type type, InjectionMember member) => { ConstructorInfo selection = null; var ctor = (InjectionMember)member; if (ctor.IsInitialized) throw new InvalidOperationException("Sharing an InjectionConstructor between registrations is not supported"); // Select Constructor foreach (var info in ctor.DeclaredMembers(type)) { if (!ctor.Data.MatchMemberInfo(info)) continue; if (null != selection) { throw new ArgumentException( $"Constructor .ctor({ctor.Data.Signature()}) is ambiguous, it could be matched with more than one constructor on type {type?.Name}."); } selection = info; } // Validate if (null != selection) return selection; throw new ArgumentException( $"Injected constructor .ctor({ctor.Data.Signature()}) could not be matched with any public constructors on type {type?.Name}."); }; public static Func MethodSelector = (Type type, InjectionMember member) => { MethodInfo selection = null; var method = (InjectionMember)member; if (method.IsInitialized) throw new InvalidOperationException("Sharing an InjectionMethod between registrations is not supported"); // Select Method foreach (var info in type.GetDeclaredMethods()) { if (method.Name != info.Name || !method.Data.MatchMemberInfo(info)) continue; if (null != selection) { throw new ArgumentException( $"Method {method.Name}({method.Data.Signature()}) is ambiguous, it could be matched with more than one method on type {type?.Name}."); } selection = info; } // Validate if (null == selection) { throw new ArgumentException( $"Injected method {method.Name}({method.Data.Signature()}) could not be matched with any public methods on type {type?.Name}."); } if (selection.IsStatic) { throw new ArgumentException( $"Static method {method.Name} on type '{selection.DeclaringType.Name}' cannot be injected"); } if (selection.IsPrivate) throw new InvalidOperationException( $"Private method '{method.Name}' on type '{selection.DeclaringType.Name}' cannot be injected"); if (selection.IsFamily) throw new InvalidOperationException( $"Protected method '{method.Name}' on type '{selection.DeclaringType.Name}' cannot be injected"); if (selection.IsGenericMethodDefinition) { throw new ArgumentException( $"Open generic method {method.Name} on type '{selection.DeclaringType.Name}' cannot be injected"); } var parameters = selection.GetParameters(); if (parameters.Any(param => param.IsOut)) { throw new ArgumentException( $"Method {method.Name} on type '{selection.DeclaringType.Name}' cannot be injected. Methods with 'out' parameters are not injectable."); } if (parameters.Any(param => param.ParameterType.IsByRef)) { throw new ArgumentException( $"Method {method.Name} on type '{selection.DeclaringType.Name}' cannot be injected. Methods with 'ref' parameters are not injectable."); } return selection; }; public static Func FieldSelector = (Type type, InjectionMember member) => { FieldInfo selection = null; var field = (InjectionMember)member; if (field.IsInitialized) throw new InvalidOperationException( "Sharing an InjectionField between registrations is not supported"); // Select Field foreach (var info in type.GetDeclaredFields()) { if (info.Name != field.Name) continue; selection = info; break; } // Validate if (null == selection) { throw new ArgumentException( $"Injected field '{field.Name}' could not be matched with any public field on type '{type?.Name}'."); } if (selection.IsStatic) throw new InvalidOperationException( $"Static field '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (selection.IsInitOnly) throw new InvalidOperationException( $"Readonly field '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (selection.IsPrivate) throw new InvalidOperationException( $"Private field '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (selection.IsFamily) throw new InvalidOperationException( $"Protected field '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (!field.Data.Matches(selection.FieldType)) throw new ArgumentException( $"Injected data '{field.Data}' could not be matched with type of field '{selection.FieldType.Name}'."); return selection; }; public static Func PropertySelector = (Type type, InjectionMember member) => { PropertyInfo selection = null; var property = (InjectionMember)member; if (property.IsInitialized) throw new InvalidOperationException("Sharing an InjectionProperty between registrations is not supported"); // Select Property foreach (var info in type.GetDeclaredProperties()) { if (info.Name != property.Name) continue; selection = info; break; } // Validate if (null == selection) { throw new ArgumentException( $"Injected property '{property.Name}' could not be matched with any property on type '{type?.Name}'."); } if (!selection.CanWrite) throw new InvalidOperationException( $"Readonly property '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (0 != selection.GetIndexParameters().Length) throw new InvalidOperationException( $"Indexer '{selection.Name}' on type '{type?.Name}' cannot be injected"); var setter = selection.GetSetMethod(true); if (setter.IsStatic) throw new InvalidOperationException( $"Static property '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (setter.IsPrivate) throw new InvalidOperationException( $"Private property '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (setter.IsFamily) throw new InvalidOperationException( $"Protected property '{selection.Name}' on type '{type?.Name}' cannot be injected"); if (!property.Data.Matches(selection.PropertyType)) { throw new ArgumentException( $"Injected data '{property.Data}' could not be matched with type of property '{selection.PropertyType.Name}'."); } return selection; }; } } ================================================ FILE: src/Legacy/DynamicMethod/DynamicBuildPlanGenerationContext.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Policy; using Unity.Resolution; namespace Unity.ObjectBuilder.BuildPlan.DynamicMethod { /// /// /// public class DynamicBuildPlanGenerationContext { private readonly Queue _buildPlanExpressions; /// /// /// /// public DynamicBuildPlanGenerationContext(Type typeToBuild) { TypeToBuild = typeToBuild; _buildPlanExpressions = new Queue(); } /// /// The type that is to be built with the dynamic build plan. /// public Type TypeToBuild { get; } /// /// /// /// public void AddToBuildPlan(Expression expression) { _buildPlanExpressions.Enqueue(expression); } internal ResolveDelegate GetBuildMethod() { var block = Expression.Block( _buildPlanExpressions.Concat(new[] { BuilderContextExpression.Existing })); var lambda = Expression.Lambda>(block, BuilderContextExpression.Context); var planDelegate = lambda.Compile(); return (ref BuilderContext context) => { try { context.Existing = planDelegate(ref context); } catch (TargetInvocationException e) { if (e.InnerException != null) throw e.InnerException; throw; } return context.Existing; }; } } } ================================================ FILE: src/Legacy/IBuildPlanCreatorPolicy.cs ================================================ using System; using Unity.Builder; namespace Unity.Policy { [Obsolete("This interface has been replaced with Unity.Policy.ResolveDelegateFactory delegate", true)] public interface IBuildPlanCreatorPolicy { /// /// Create a build plan using the given context and build key. /// /// Current build context. /// /// /// The build plan. IBuildPlanPolicy CreatePlan(ref BuilderContext context, Type type, string name); } } ================================================ FILE: src/Legacy/IBuildPlanPolicy.cs ================================================ using System; using Unity.Builder; namespace Unity.Policy { [Obsolete("IBuildPlanPolicy has been deprecated, please use ResolveDelegateFactory instead", true)] public interface IBuildPlanPolicy { void BuildUp(ref BuilderContext context); } } ================================================ FILE: src/Legacy/IConstructorSelectorPolicy.cs ================================================ using System; using System.Reflection; namespace Unity.Policy { [Obsolete("IConstructorSelectorPolicy has been deprecated, please use ISelect instead", true)] public interface IConstructorSelectorPolicy : ISelect { } } ================================================ FILE: src/Legacy/IMethodSelectorPolicy.cs ================================================ using System; using System.Collections.Generic; using System.Reflection; using Unity.Builder; namespace Unity.Policy { [Obsolete("IMethodSelectorPolicy has been deprecated, please use ISelectMembers instead", true)] public interface IMethodSelectorPolicy { IEnumerable SelectMethods(ref BuilderContext context); } } ================================================ FILE: src/Legacy/IPropertySelectorPolicy.cs ================================================ using System; using System.Collections.Generic; using System.Reflection; using Unity.Builder; namespace Unity.Policy { [Obsolete("IPropertySelectorPolicy has been deprecated, please use IPropertySelectorPolicy instead", true)] public interface IPropertySelectorPolicy : ISelect { IEnumerable SelectProperties(ref BuilderContext context); } } ================================================ FILE: src/Legacy/InjectionParameterValue.cs ================================================ namespace Unity.Injection { /// /// Base type for objects that are used to configure parameters for /// constructor or method injection, or for getting the value to /// be injected into a property. /// public abstract class Injection_ParameterValue { } } ================================================ FILE: src/Legacy/NamedTypeBuildKey.cs ================================================ using System; using System.Globalization; using Unity.Policy; namespace Unity.Builder { /// /// Build key used to combine a type object with a string name. Used by /// ObjectBuilder to indicate exactly what is being built. /// public class NamedTypeBuildKey { private readonly int _hash; /// /// Create a new instance with the given /// type and name. /// /// to build. /// Key to use to look up type mappings and singletons. public NamedTypeBuildKey(Type type, string name) { Type = type; Name = !string.IsNullOrEmpty(name) ? name : null; _hash = (Type?.GetHashCode() ?? 0 + 37) ^ (Name?.GetHashCode() ?? 0 + 17); } /// /// Create a new instance for the default /// buildup of the given type. /// /// to build. public NamedTypeBuildKey(Type type) : this(type, null) { } /// /// This helper method creates a new instance. It is /// initialized for the default key for the given type. /// /// Type to build. /// A new instance. public static NamedTypeBuildKey Make() { return new NamedTypeBuildKey(typeof(T)); } /// /// This helper method creates a new instance for /// the given type and key. /// /// Type to build /// Key to use to look up type mappings and singletons. /// A new instance initialized with the given type and name. public static NamedTypeBuildKey Make(string name) { return new NamedTypeBuildKey(typeof(T), name); } /// /// Return the stored in this build key. /// /// The type to build. public Type Type { get; } /// /// Returns the name stored in this build key. /// /// The name to use when building. public string Name { get; } /// /// Compare two instances. /// /// Two instances compare equal /// if they contain the same name and the same type. Also, comparing /// against a different type will also return false. /// Object to compare to. /// True if the two keys are equal, false if not. public override bool Equals(object obj) { return obj is NamedTypeBuildKey namedType && Type == namedType.Type && Name == namedType.Name; } /// /// Calculate a hash code for this instance. /// /// A hash code. public override int GetHashCode() { return _hash; } /// /// Compare two instances for equality. /// /// Two instances compare equal /// if they contain the same name and the same type. /// First of the two keys to compare. /// Second of the two keys to compare. /// True if the values of the keys are the same, else false. public static bool operator ==(NamedTypeBuildKey left, NamedTypeBuildKey right) { return left?._hash == right?._hash && left?.Type == right?.Type; } /// /// Compare two instances for inequality. /// /// Two instances compare equal /// if they contain the same name and the same type. If either field differs /// the keys are not equal. /// First of the two keys to compare. /// Second of the two keys to compare. /// false if the values of the keys are the same, else true. public static bool operator !=(NamedTypeBuildKey left, NamedTypeBuildKey right) { return !(left == right); } /// /// Formats the build key as a string (primarily for debugging). /// /// A readable string representation of the build key. public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "Build Key[{0}, {1}]", Type, Name ?? "null"); } } /// /// A generic version of so that /// you can new up a key using generic syntax. /// /// Type for the key. public class NamedTypeBuildKey : NamedTypeBuildKey { /// /// Construct a new that /// specifies the given type. /// public NamedTypeBuildKey() : base(typeof(T), null) { } /// /// Construct a new that /// specifies the given type and name. /// /// Name for the key. public NamedTypeBuildKey(string name) : base(typeof(T), name) { } } } ================================================ FILE: src/Legacy/TypeBasedOverride.cs ================================================ using System; using System.Reflection; using Unity.Policy; namespace Unity.Resolution { /// /// An implementation of that /// acts as a decorator over another . /// This checks to see if the current type being built is the /// right one before checking the inner . /// [Obsolete("This type has been deprecated as degrading performance. Use DependencyOverride instead.", false)] public class TypeBasedOverride : ResolverOverride, IEquatable, IEquatable { #region Fields private readonly ResolverOverride _innerOverride; #endregion #region Constructors /// /// Create an instance of /// /// Type to check for. /// Inner override to check after type matches. public TypeBasedOverride(Type targetType, ResolverOverride innerOverride) : base(targetType, null, null) { _innerOverride = (innerOverride ?? throw new ArgumentNullException(nameof(innerOverride))) .OnType(targetType ?? throw new ArgumentNullException(nameof(targetType))); } #endregion #region ResolverOverride public override ResolveDelegate GetResolver(Type type) { return _innerOverride.GetResolver(type); } #endregion #region IEquatable public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(object obj) { return _innerOverride.Equals(obj); } public bool Equals(PropertyInfo other) { return _innerOverride is IEquatable info && info.Equals(other); } public bool Equals(ParameterInfo other) { return _innerOverride is IEquatable info && info.Equals(other); } #endregion } /// /// A convenience version of that lets you /// specify the type to construct via generics syntax. /// /// Type to check for. [Obsolete("This type has been deprecated as degrading performance. Use DependencyOverride instead.", false)] public class TypeBasedOverride : TypeBasedOverride { /// /// Create an instance of . /// /// Inner override to check after type matches. public TypeBasedOverride(ResolverOverride innerOverride) : base(typeof(T), innerOverride) { } } } ================================================ FILE: src/Legacy/TypedInjectionValue.cs ================================================ using System; using System.Reflection; namespace Unity.Injection { /// /// A base class for implementing classes /// that deal in explicit types. /// public abstract class Typed_InjectionValue : Injection_ParameterValue { } } ================================================ FILE: src/Lifetime/ContainerLifetimeManager.cs ================================================ namespace Unity.Lifetime { /// /// Internal container lifetime manager. /// This manager distinguishes internal registration from user mode registration. /// /// /// Works like the ExternallyControlledLifetimeManager, but uses /// regular instead of weak references /// internal class ContainerLifetimeManager : LifetimeManager, IInstanceLifetimeManager { public override object GetValue(ILifetimeContainer container = null) { return container.Container; } protected override LifetimeManager OnCreateLifetimeManager() { return new ContainerLifetimeManager(); } public override bool InUse { get => false; set => base.InUse = false; } } } ================================================ FILE: src/Lifetime/InternalPerResolveLifetimeManager.cs ================================================  namespace Unity.Lifetime { /// /// This is a custom lifetime manager that acts like , /// but also provides a signal to the default build plan, marking the type so that /// instances are reused across the build up object graph. /// internal class InternalPerResolveLifetimeManager : PerResolveLifetimeManager { /// /// Construct a new object that stores the /// give value. This value will be returned by /// but is not stored in the lifetime manager, nor is the value disposed. /// This WithLifetime manager is intended only for internal use, which is why the /// normal method is not used here. /// /// InjectionParameterValue to store. public InternalPerResolveLifetimeManager(object value) { base.value = value; InUse = true; } } } ================================================ FILE: src/Lifetime/LifetimeContainer.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Unity.Lifetime { /// /// Represents a lifetime container. /// /// /// A lifetime container tracks the lifetime of an object, and implements /// IDisposable. When the container is disposed, any objects in the /// container which implement IDisposable are also disposed. /// public class LifetimeContainer : ILifetimeContainer { private readonly List _items = new List(); public LifetimeContainer(IUnityContainer owner = null) { Container = owner; } /// /// The IUnityContainer this container is associated with. /// /// The object. public IUnityContainer Container { get; } /// /// Gets the number of references in the lifetime container /// /// /// The number of references in the lifetime container /// public int Count { get { lock (_items) { return _items.Count; } } } /// /// Adds an object to the lifetime container. /// /// The item to be added to the lifetime container. public void Add(object item) { lock (_items) { _items.Add(item); } } /// /// Determine if a given object is in the lifetime container. /// /// /// The item to locate in the lifetime container. /// /// /// Returns true if the object is contained in the lifetime /// container; returns false otherwise. /// public bool Contains(object item) { lock (_items) { return _items.Contains(item); } } /// /// Releases the resources used by the . /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases the resources used by the . /// /// /// true to release managed and unmanaged resources; false to release only unmanaged resources. /// protected virtual void Dispose(bool disposing) { if (!disposing) return; IDisposable[] disposables; lock (_items) { disposables = _items.OfType() .Distinct() .Reverse() .ToArray(); _items.Clear(); } var exceptions = new List(); foreach (var disposable in disposables) { try { disposable.Dispose(); } catch (Exception e) { exceptions.Add(e); } } if (exceptions.Count == 1) { throw exceptions.First(); } else if (exceptions.Count > 1) { throw new AggregateException(exceptions); } } /// /// Returns an enumerator that iterates through the lifetime container. /// /// /// An object that can be used to iterate through the life time container. /// public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } /// /// Returns an enumerator that iterates through the lifetime container. /// /// /// An object that can be used to iterate through the life time container. /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Removes an item from the lifetime container. The item is /// not disposed. /// /// The item to be removed. public void Remove(object item) { lock (_items) { if (!_items.Contains(item)) { return; } _items.Remove(item); } } } } ================================================ FILE: src/Policy/Converter.cs ================================================ using System; using System.Collections.Generic; using System.Text; namespace Unity.Policy { public delegate TOutput Converter(TInput input); } ================================================ FILE: src/Policy/IResolveDelegateFactory.cs ================================================ using Unity.Builder; using Unity.Resolution; namespace Unity.Policy { public delegate ResolveDelegate ResolveDelegateFactory(ref BuilderContext context); public interface IResolveDelegateFactory { ResolveDelegate GetResolver(ref BuilderContext context); } } ================================================ FILE: src/Policy/ISelect.cs ================================================ using System; using System.Collections.Generic; using System.Reflection; namespace Unity.Policy { public interface ISelect where TMemberInfo : MemberInfo { IEnumerable Select(Type type, IPolicySet registration); } } ================================================ FILE: src/Processors/Abstracts/MemberExpression.cs ================================================ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Unity.Injection; namespace Unity.Processors { public abstract partial class MemberProcessor where TMemberInfo : MemberInfo { #region Selection Processing protected virtual IEnumerable ExpressionsFromSelection(Type type, IEnumerable members) { HashSet memberSet = new HashSet(); foreach (var member in members) { switch (member) { // TMemberInfo case TMemberInfo info: if (!memberSet.Add(info)) continue; object value = DependencyAttribute.Instance; foreach (var node in AttributeFactories) { var attribute = GetCustomAttribute(info, node.Type); if (null == attribute) continue; value = null == node.Factory ? (object)attribute : node.Factory(attribute, info, null); break; } yield return GetResolverExpression(info, value); break; // Injection Member case InjectionMember injectionMember: var selection = injectionMember.MemberInfo(type); if (!memberSet.Add(selection)) continue; yield return GetResolverExpression(selection, injectionMember.Data); break; // Unknown default: throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type"); } } } #endregion #region Implementation protected abstract Expression GetResolverExpression(TMemberInfo info, object resolver); #endregion } } ================================================ FILE: src/Processors/Abstracts/MemberProcessor.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Injection; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Processors { public abstract class MemberProcessor { #region Fields protected static readonly MethodInfo StringFormat = typeof(string).GetTypeInfo() .DeclaredMethods .First(m => { var parameters = m.GetParameters(); return m.Name == nameof(string.Format) && m.GetParameters().Length == 2 && typeof(object) == parameters[1].ParameterType; }); protected static readonly Expression InvalidRegistrationExpression = Expression.New(typeof(InvalidRegistrationException)); protected static readonly Expression NewGuid = Expression.Call(typeof(Guid).GetTypeInfo().GetDeclaredMethod(nameof(Guid.NewGuid))); protected static readonly PropertyInfo DataProperty = typeof(Exception).GetTypeInfo().GetDeclaredProperty(nameof(Exception.Data)); protected static readonly MethodInfo AddMethod = typeof(IDictionary).GetTypeInfo().GetDeclaredMethod(nameof(IDictionary.Add)); #endregion #region Public Methods /// /// /// /// /// Call hierarchy: /// /// + /// + /// + /// + /// /// /// /// public abstract IEnumerable GetExpressions(Type type, IPolicySet registration); /// /// /// /// /// Call hierarchy: /// /// + /// + /// + /// + /// /// /// /// /// public abstract ResolveDelegate GetResolver(Type type, IPolicySet registration, ResolveDelegate seed); #endregion } public abstract partial class MemberProcessor : MemberProcessor, ISelect where TMemberInfo : MemberInfo { #region Fields private readonly IPolicySet _policySet; protected AttributeFactoryNode[] AttributeFactories; #endregion #region Constructors protected MemberProcessor(IPolicySet policySet) { // Add Unity attribute factories AttributeFactories = new[] { new AttributeFactoryNode(typeof(DependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, DependencyResolverFactory), new AttributeFactoryNode(typeof(OptionalDependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, OptionalDependencyResolverFactory), }; _policySet = policySet; } protected MemberProcessor(IPolicySet policySet, Type attribute) { // Add Unity attribute factories AttributeFactories = new[] { new AttributeFactoryNode(attribute, (a)=>(a as DependencyResolutionAttribute)?.Name, null), new AttributeFactoryNode(typeof(DependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, DependencyResolverFactory), new AttributeFactoryNode(typeof(OptionalDependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, OptionalDependencyResolverFactory), }; _policySet = policySet; } #endregion #region Public Methods public void Add(Type type, Func getName, Func> resolutionFactory) { for (var i = 0; i < AttributeFactories.Length; i++) { if (AttributeFactories[i].Type != type) continue; AttributeFactories[i].Factory = resolutionFactory; return; } var factories = new AttributeFactoryNode[AttributeFactories.Length + 1]; Array.Copy(AttributeFactories, factories, AttributeFactories.Length); factories[AttributeFactories.Length] = new AttributeFactoryNode(type, getName, resolutionFactory); AttributeFactories = factories; } #endregion #region MemberProcessor /// public override IEnumerable GetExpressions(Type type, IPolicySet registration) { var selector = GetPolicy>(registration); var members = selector.Select(type, registration); return ExpressionsFromSelection(type, members); } /// public override ResolveDelegate GetResolver(Type type, IPolicySet registration, ResolveDelegate seed) { var selector = GetPolicy>(registration); var members = selector.Select(type, registration); var resolvers = ResolversFromSelection(type, members).Distinct().ToArray(); return (ref BuilderContext c) => { if (null == (c.Existing = seed(ref c))) return null; foreach (var resolver in resolvers) resolver(ref c); return c.Existing; }; } #endregion #region ISelect public virtual IEnumerable Select(Type type, IPolicySet registration) { // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember) yield return injectionMember; } } // Select Attributed members IEnumerable members = DeclaredMembers(type); if (null == members) yield break; foreach (var member in members) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!member.IsDefined(AttributeFactories[i].Type, true)) continue; #else if (!member.IsDefined(AttributeFactories[i].Type)) continue; #endif yield return member; break; } } } #endregion #region Implementation protected abstract Type MemberType(TMemberInfo info); protected abstract IEnumerable DeclaredMembers(Type type); protected object PreProcessResolver(TMemberInfo info, object resolver) { switch (resolver) { case IResolve policy: return (ResolveDelegate)policy.Resolve; case IResolverFactory factory: return factory.GetResolver(MemberType(info)); case Type type: return typeof(Type) == MemberType(info) ? type : (object)info; } return resolver; } protected Attribute GetCustomAttribute(TMemberInfo info, Type type) { #if NETSTANDARD1_0 || NETCOREAPP1_0 return info.GetCustomAttributes() .Where(a => a.GetType() .GetTypeInfo() .IsAssignableFrom(type.GetTypeInfo())) .FirstOrDefault(); #elif NET40 return info.GetCustomAttributes(true) .Cast() .Where(a => a.GetType() .GetTypeInfo() .IsAssignableFrom(type.GetTypeInfo())) .FirstOrDefault(); #else return info.GetCustomAttribute(type); #endif } public TPolicyInterface GetPolicy(IPolicySet registration) { return (TPolicyInterface)(registration.Get(typeof(TPolicyInterface)) ?? _policySet.Get(typeof(TPolicyInterface))); } #endregion #region Attribute Resolver Factories protected virtual ResolveDelegate DependencyResolverFactory(Attribute attribute, object info, object value = null) { var type = MemberType((TMemberInfo)info); return (ref BuilderContext context) => context.Resolve(type, ((DependencyResolutionAttribute)attribute).Name); } protected virtual ResolveDelegate OptionalDependencyResolverFactory(Attribute attribute, object info, object value = null) { var type = MemberType((TMemberInfo)info); return (ref BuilderContext context) => { try { return context.Resolve(type, ((DependencyResolutionAttribute)attribute).Name); } catch (Exception ex) when (!(ex.InnerException is CircularDependencyException)) { return value; } }; } #endregion #region Nested Types public struct AttributeFactoryNode { public readonly Type Type; public Func> Factory; public Func Name; public AttributeFactoryNode(Type type, Func getName, Func> factory) { Type = type; Name = getName; Factory = factory; } } #endregion } } ================================================ FILE: src/Processors/Abstracts/MemberResolution.cs ================================================ using System; using System.Collections.Generic; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Resolution; namespace Unity.Processors { public abstract partial class MemberProcessor where TMemberInfo : MemberInfo { #region Selection Processing protected virtual IEnumerable> ResolversFromSelection(Type type, IEnumerable members) { HashSet memberSet = new HashSet(); foreach (var member in members) { switch (member) { // MemberInfo case TMemberInfo info: if (!memberSet.Add(info)) continue; object value = DependencyAttribute.Instance; foreach (var node in AttributeFactories) { var attribute = GetCustomAttribute(info, node.Type); if (null == attribute) continue; value = null == node.Factory ? (object)attribute : node.Factory(attribute, info, null); break; } yield return GetResolverDelegate(info, value); break; // Injection Member case InjectionMember injectionMember: var selection = injectionMember.MemberInfo(type); if (!memberSet.Add(selection)) continue; yield return GetResolverDelegate(selection, injectionMember.Data); break; // Unknown default: throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type"); } } } #endregion #region Implementation protected abstract ResolveDelegate GetResolverDelegate(TMemberInfo info, object resolver); #endregion } } ================================================ FILE: src/Processors/Constructor/ConstructorDiagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Lifetime; using Unity.Exceptions; using Unity.Policy; using Unity.Resolution; using Unity.Registration; using Unity.Injection; using System.Text.RegularExpressions; namespace Unity.Processors { public class ConstructorDiagnostic : ConstructorProcessor { #region Fields const string CannotConstructAbstractClass = "The current type, {0}, is an abstract class and cannot be constructed. Are you missing a type mapping?"; const string CannotConstructDelegate = "The current type, {0}, is delegate and cannot be constructed. Unity only supports resolving Func<T> and Func<IEnumerable<T>> by default."; const string CannotConstructInterface = "The current type, {0}, is an interface and cannot be constructed. Are you missing a type mapping?"; const string TypeIsNotConstructable = "The type {0} cannot be constructed. You must configure the container to supply this value."; private static readonly Expression[] CannotConstructInterfaceExpr = new [] { Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw( Expression.New(InvalidOperationExceptionCtor, Expression.Call( StringFormat, Expression.Constant(CannotConstructInterface), BuilderContextExpression.Type), InvalidRegistrationExpression)))}; private static readonly Expression[] CannotConstructAbstractClassExpr = new [] { Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw( Expression.New(InvalidOperationExceptionCtor, Expression.Call( StringFormat, Expression.Constant(CannotConstructAbstractClass), BuilderContextExpression.Type), InvalidRegistrationExpression)))}; private static readonly Expression[] CannotConstructDelegateExpr = new [] { Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw( Expression.New(InvalidOperationExceptionCtor, Expression.Call( StringFormat, Expression.Constant(CannotConstructDelegate), BuilderContextExpression.Type), InvalidRegistrationExpression)))}; private static readonly Expression[] TypeIsNotConstructableExpr = new [] { Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw( Expression.New(InvalidOperationExceptionCtor, Expression.Call( StringFormat, Expression.Constant(TypeIsNotConstructable), BuilderContextExpression.Type), InvalidRegistrationExpression)))}; #endregion #region Constructors public ConstructorDiagnostic(IPolicySet policySet, UnityContainer container) : base(policySet, container) { } #endregion #region Selection public override IEnumerable Select(Type type, IPolicySet registration) { var members = new List(); // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember) { members.Add(injectionMember); } } } switch (members.Count) { case 1: return members.ToArray(); case 0: break; default: return new[] { new InvalidOperationException($"Multiple Injection Constructors are registered for Type {type.FullName}", new InvalidRegistrationException()) }; } // Enumerate to array var constructors = DeclaredMembers(type).ToArray(); if (1 >= constructors.Length) return constructors; var selection = new HashSet(); // Select Attributed constructors foreach (var constructor in constructors) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!constructor.IsDefined(AttributeFactories[i].Type, true)) #else if (!constructor.IsDefined(AttributeFactories[i].Type)) #endif continue; selection.Add(constructor); } } switch (selection.Count) { case 1: return selection.ToArray(); case 0: break; default: return new[] { new InvalidOperationException($"Multiple Constructors are annotated for injection on Type {type.FullName}", new InvalidRegistrationException()) }; } // Select default return new[] { SelectMethod(type, constructors) }; } protected override object SmartSelector(Type type, ConstructorInfo[] constructors) { Array.Sort(constructors, (a, b) => { var qtd = b.GetParameters().Length.CompareTo(a.GetParameters().Length); if (qtd == 0) { #if NETSTANDARD1_0 || NETCOREAPP1_0 return b.GetParameters().Sum(p => p.ParameterType.GetTypeInfo().IsInterface ? 1 : 0) .CompareTo(a.GetParameters().Sum(p => p.ParameterType.GetTypeInfo().IsInterface ? 1 : 0)); #else return b.GetParameters().Sum(p => p.ParameterType.IsInterface ? 1 : 0) .CompareTo(a.GetParameters().Sum(p => p.ParameterType.IsInterface ? 1 : 0)); #endif } return qtd; }); int parametersCount = 0; ConstructorInfo bestCtor = null; foreach (var ctorInfo in constructors) { var parameters = ctorInfo.GetParameters(); if (null != bestCtor && parametersCount > parameters.Length) return bestCtor; parametersCount = parameters.Length; #if NET40 if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p))) #else if (parameters.All(p => p.HasDefaultValue || CanResolve(p))) #endif { if (bestCtor == null) { bestCtor = ctorInfo; } else { var message = $"Ambiguous constructor: Failed to choose between {type.Name}{Regex.Match(bestCtor.ToString(), @"\((.*?)\)")} and {type.Name}{Regex.Match(ctorInfo.ToString(), @"\((.*?)\)")}"; return new InvalidOperationException(message, new InvalidRegistrationException()); } } } if (bestCtor == null) { return new InvalidOperationException( $"Failed to select a constructor for {type.FullName}", new InvalidRegistrationException()); } return bestCtor; } #endregion #region Expression Overrides public override IEnumerable GetExpressions(Type type, IPolicySet registration) { #if NETSTANDARD1_0 || NETCOREAPP1_0 var typeInfo = type.GetTypeInfo(); #else var typeInfo = type; #endif // Validate if Type could be created if (typeInfo.IsInterface) return CannotConstructInterfaceExpr; if (typeInfo.IsAbstract) return CannotConstructAbstractClassExpr; if (typeInfo.IsSubclassOf(typeof(Delegate))) return CannotConstructDelegateExpr; if (type == typeof(string)) return TypeIsNotConstructableExpr; // Build expression as usual return base.GetExpressions(type, registration); } protected override Expression GetResolverExpression(ConstructorInfo info, object resolvers) { var ex = Expression.Variable(typeof(Exception)); var exData = Expression.MakeMemberAccess(ex, DataProperty); var variable = Expression.Variable(info.DeclaringType ?? throw new ArgumentNullException(nameof(info))); var parameters = info.GetParameters(); // Check if has Out or ByRef parameters var tryBlock = parameters.Any(pi => pi.ParameterType.IsByRef) // Report error ? (Expression)Expression.Throw(Expression.New(InvalidOperationExceptionCtor, Expression.Constant(CreateErrorMessage(Error.SelectedConstructorHasRefParameters, info.DeclaringType, info)), InvalidRegistrationExpression)) // Create new instance : Expression.Block(new[] { variable }, new Expression[] { Expression.Assign(variable, Expression.New(info, CreateDiagnosticParameterExpressions(info.GetParameters(), resolvers))), Expression.Assign(BuilderContextExpression.Existing, Expression.Convert(variable, typeof(object))) }); // Add location to dictionary and re-throw var catchBlock = Expression.Block(tryBlock.Type, Expression.Call(exData, AddMethod, Expression.Convert(NewGuid, typeof(object)), Expression.Constant(info, typeof(object))), Expression.Rethrow(tryBlock.Type)); // Create return Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.TryCatch(tryBlock, Expression.Catch(ex, catchBlock))); // Report error string CreateErrorMessage(string format, Type type, MethodBase constructor) { var parameterDescriptions = constructor.GetParameters() .Select(parameter => $"{parameter.ParameterType.FullName} {parameter.Name}"); return string.Format(format, type.FullName, string.Join(", ", parameterDescriptions)); } } #endregion #region Resolver Overrides public override ResolveDelegate GetResolver(Type type, IPolicySet registration, ResolveDelegate seed) { #if NETSTANDARD1_0 || NETCOREAPP1_0 var typeInfo = type.GetTypeInfo(); #else var typeInfo = type; #endif // Validate if Type could be created if (typeInfo.IsInterface) { return (ref BuilderContext c) => { if (null == c.Existing) throw new InvalidOperationException(string.Format(CannotConstructInterface, c.Type), new InvalidRegistrationException()); return c.Existing; }; } if (typeInfo.IsAbstract) { return (ref BuilderContext c) => { if (null == c.Existing) throw new InvalidOperationException(string.Format(CannotConstructAbstractClass, c.Type), new InvalidRegistrationException()); return c.Existing; }; } if (typeInfo.IsSubclassOf(typeof(Delegate))) { return (ref BuilderContext c) => { if (null == c.Existing) throw new InvalidOperationException(string.Format(CannotConstructDelegate, c.Type), new InvalidRegistrationException()); return c.Existing; }; } if (type == typeof(string)) { return (ref BuilderContext c) => { if (null == c.Existing) throw new InvalidOperationException(string.Format(TypeIsNotConstructable, c.Type), new InvalidRegistrationException()); return c.Existing; }; } return base.GetResolver(type, registration, seed); } protected override ResolveDelegate GetResolverDelegate(ConstructorInfo info, object resolvers) { var parameterResolvers = CreateDiagnosticParameterResolvers(info.GetParameters(), resolvers).ToArray(); return (ref BuilderContext c) => { if (null == c.Existing) { try { var dependencies = new object[parameterResolvers.Length]; for (var i = 0; i < dependencies.Length; i++) dependencies[i] = parameterResolvers[i](ref c); c.Existing = info.Invoke(dependencies); } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), info); throw; } } return c.Existing; }; } protected override ResolveDelegate GetPerResolveDelegate(ConstructorInfo info, object resolvers) { var parameterResolvers = CreateDiagnosticParameterResolvers(info.GetParameters(), resolvers).ToArray(); // PerResolve lifetime return (ref BuilderContext c) => { if (null == c.Existing) { try { var dependencies = new object[parameterResolvers.Length]; for (var i = 0; i < dependencies.Length; i++) dependencies[i] = parameterResolvers[i](ref c); c.Existing = info.Invoke(dependencies); } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), info); throw; } c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing)); } return c.Existing; }; } #endregion } } ================================================ FILE: src/Processors/Constructor/ConstructorExpression.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Injection; using Unity.Lifetime; using Unity.Policy; namespace Unity.Processors { public partial class ConstructorProcessor { #region Fields protected static readonly ConstructorInfo InvalidOperationExceptionCtor = typeof(InvalidOperationException) .GetTypeInfo() .DeclaredConstructors .First(c => { var parameters = c.GetParameters(); return 2 == parameters.Length && typeof(string) == parameters[0].ParameterType && typeof(Exception) == parameters[1].ParameterType; }); private static readonly ConstructorInfo PerResolveInfo = typeof(InternalPerResolveLifetimeManager) .GetTypeInfo().DeclaredConstructors.First(); protected static readonly Expression SetPerBuildSingletonExpr = Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.SetMethod, Expression.Constant(typeof(LifetimeManager), typeof(Type)), Expression.New(PerResolveInfo, BuilderContextExpression.Existing)); protected static readonly Expression[] NoConstructorExpr = new [] { Expression.IfThen(Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw( Expression.New(InvalidOperationExceptionCtor, Expression.Call(StringFormat, Expression.Constant("No public constructor is available for type {0}."), BuilderContextExpression.Type), InvalidRegistrationExpression)))}; #endregion #region Overrides public override IEnumerable GetExpressions(Type type, IPolicySet registration) { // Select ConstructorInfo var selector = GetPolicy>(registration); var selection = selector.Select(type, registration) .FirstOrDefault(); // Select constructor for the Type object[] resolvers = null; ConstructorInfo info = null; IEnumerable parametersExpr; switch (selection) { case ConstructorInfo memberInfo: info = memberInfo; parametersExpr = CreateParameterExpressions(info.GetParameters()); break; case MethodBase injectionMember: info = injectionMember.MemberInfo(type); resolvers = injectionMember.Data; parametersExpr = CreateParameterExpressions(info.GetParameters(), resolvers); break; case Exception exception: return new[] {Expression.IfThen( Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Throw(Expression.Constant(exception)))}; default: return NoConstructorExpr; } // Get lifetime manager var lifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager)); return lifetimeManager is PerResolveLifetimeManager ? new[] { GetResolverExpression(info, resolvers), SetPerBuildSingletonExpr } : new Expression[] { GetResolverExpression(info, resolvers) }; } protected override Expression GetResolverExpression(ConstructorInfo info, object resolvers) { try { var variable = Expression.Variable(info.DeclaringType); var parametersExpr = CreateParameterExpressions(info.GetParameters(), resolvers); return Expression.IfThen( Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing), Expression.Block(new[] { variable }, new Expression[] { Expression.Assign(variable, Expression.New(info, parametersExpr)), Expression.Assign(BuilderContextExpression.Existing, Expression.Convert(variable, typeof(object))) })); } catch (ArgumentException ex) { throw new InvalidRegistrationException("Invalid Argument", ex); } } #endregion } } ================================================ FILE: src/Processors/Constructor/ConstructorProcessor.cs ================================================ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using Unity.Exceptions; using Unity.Injection; using Unity.Policy; using Unity.Registration; namespace Unity.Processors { public partial class ConstructorProcessor : ParametersProcessor { #region Constructors public ConstructorProcessor(IPolicySet policySet, UnityContainer container) : base(policySet, typeof(InjectionConstructorAttribute), container) { SelectMethod = SmartSelector; } #endregion #region Public Properties public Func SelectMethod { get; set; } #endregion #region Overrides public override IEnumerable Select(Type type, IPolicySet registration) { // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember) { return new[] { injectionMember }; } } } // Enumerate to array var constructors = DeclaredMembers(type).ToArray(); if (1 >= constructors.Length) return constructors; // Select Attributed constructors foreach (var constructor in constructors) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!constructor.IsDefined(AttributeFactories[i].Type, true)) #else if (!constructor.IsDefined(AttributeFactories[i].Type)) #endif continue; return new[] { constructor }; } } // Select default return new[] { SelectMethod(type, constructors) }; } protected override IEnumerable DeclaredMembers(Type type) { return type.GetTypeInfo() .DeclaredConstructors .Where(ctor => !ctor.IsFamily && !ctor.IsPrivate && !ctor.IsStatic); } #endregion #region Implementation /// /// Selects default constructor /// /// to be built /// All public constructors this type implements /// public object LegacySelector(Type type, ConstructorInfo[] members) { Array.Sort(members, (x, y) => x?.GetParameters().Length ?? 0 - y?.GetParameters().Length ?? 0); switch (members.Length) { case 0: return null; case 1: return members[0]; default: var paramLength = members[0].GetParameters().Length; if (members[1].GetParameters().Length == paramLength) { return new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, "The type {0} has multiple constructors of length {1}. Unable to disambiguate.", type.GetTypeInfo().Name, paramLength), new InvalidRegistrationException()); } #if NETSTANDARD1_0 || NETCOREAPP1_0 var typeInfo = type.GetTypeInfo(); #else var typeInfo = type; #endif // Validate if Type could be created if (typeInfo.IsInterface) { return new InvalidOperationException($"The type {type.GetTypeInfo().Name} is an interface. Unable to create an interface.", new InvalidRegistrationException()); } if (typeInfo.IsAbstract) { return new InvalidOperationException($"The type {type.GetTypeInfo().Name} is an abstract class. Unable to create an abstract.", new InvalidRegistrationException()); } if (typeInfo.IsSubclassOf(typeof(Delegate))) { return new InvalidOperationException($"The type {type.GetTypeInfo().Name} is a delegate. Unable to create a delegate.", new InvalidRegistrationException()); } if (type == typeof(string)) { return new InvalidOperationException($"Unable to create a string", new InvalidRegistrationException()); } return members[0]; } } protected virtual object SmartSelector(Type type, ConstructorInfo[] constructors) { Array.Sort(constructors, (a, b) => { var qtd = b.GetParameters().Length.CompareTo(a.GetParameters().Length); if (qtd == 0) { #if NETSTANDARD1_0 || NETCOREAPP1_0 return b.GetParameters().Sum(p => p.ParameterType.GetTypeInfo().IsInterface ? 1 : 0) .CompareTo(a.GetParameters().Sum(p => p.ParameterType.GetTypeInfo().IsInterface ? 1 : 0)); #else return b.GetParameters().Sum(p => p.ParameterType.IsInterface ? 1 : 0) .CompareTo(a.GetParameters().Sum(p => p.ParameterType.IsInterface ? 1 : 0)); #endif } return qtd; }); foreach (var ctorInfo in constructors) { var parameters = ctorInfo.GetParameters(); #if NET40 if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p))) #else if (parameters.All(p => p.HasDefaultValue || CanResolve(p))) #endif { return ctorInfo; } } return new InvalidOperationException( $"Failed to select a constructor for {type.FullName}", new InvalidRegistrationException()); } #endregion } } ================================================ FILE: src/Processors/Constructor/ConstructorResolution.cs ================================================ using System; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Injection; using Unity.Lifetime; using Unity.Policy; using Unity.Resolution; namespace Unity.Processors { public partial class ConstructorProcessor { #region Overrides public override ResolveDelegate GetResolver(Type type, IPolicySet registration, ResolveDelegate seed) { // Select ConstructorInfo var selector = GetPolicy>(registration); var selection = selector.Select(type, registration) .FirstOrDefault(); // Select constructor for the Type ConstructorInfo info; object[] resolvers = null; switch (selection) { case ConstructorInfo memberInfo: info = memberInfo; break; case MethodBase injectionMember: info = injectionMember.MemberInfo(type); resolvers = injectionMember.Data; break; case Exception exception: return (ref BuilderContext c) => { if (null == c.Existing) throw exception; return c.Existing; }; default: return (ref BuilderContext c) => { if (null == c.Existing) throw new InvalidOperationException($"No public constructor is available for type {c.Type}.", new InvalidRegistrationException()); return c.Existing; }; } // Get lifetime manager var lifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager)); return lifetimeManager is PerResolveLifetimeManager ? GetPerResolveDelegate(info, resolvers) : GetResolverDelegate(info, resolvers); } protected override ResolveDelegate GetResolverDelegate(ConstructorInfo info, object resolvers) { var parameterResolvers = CreateParameterResolvers(info.GetParameters(), resolvers).ToArray(); return (ref BuilderContext c) => { if (null == c.Existing) { var dependencies = new object[parameterResolvers.Length]; for (var i = 0; i < dependencies.Length; i++) dependencies[i] = parameterResolvers[i](ref c); c.Existing = info.Invoke(dependencies); } return c.Existing; }; } #endregion #region Implementation protected virtual ResolveDelegate GetPerResolveDelegate(ConstructorInfo info, object resolvers) { var parameterResolvers = CreateParameterResolvers(info.GetParameters(), resolvers).ToArray(); // PerResolve lifetime return (ref BuilderContext c) => { if (null == c.Existing) { var dependencies = new object[parameterResolvers.Length]; for (var i = 0; i < dependencies.Length; i++) dependencies[i] = parameterResolvers[i](ref c); c.Existing = info.Invoke(dependencies); c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing)); } return c.Existing; }; } #endregion } } ================================================ FILE: src/Processors/Fields/FieldDiagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Processors { public class FieldDiagnostic : FieldProcessor { #region Constructors public FieldDiagnostic(IPolicySet policySet) : base(policySet) { } #endregion #region Overrides public override IEnumerable Select(Type type, IPolicySet registration) { HashSet memberSet = new HashSet(); // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember && memberSet.Add(injectionMember)) yield return injectionMember; } } // Select Attributed members foreach (var member in type.GetDeclaredFields()) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!member.IsDefined(AttributeFactories[i].Type, true) || #else if (!member.IsDefined(AttributeFactories[i].Type) || #endif !memberSet.Add(member)) continue; if (member.IsStatic) throw new InvalidOperationException( $"Static field '{member.Name}' on type '{type?.Name}' is marked for injection. Static fields cannot be injected"); if (member.IsInitOnly) throw new InvalidOperationException( $"Readonly field '{member.Name}' on type '{type?.Name}' is marked for injection. Readonly fields cannot be injected"); if (member.IsPrivate) throw new InvalidOperationException( $"Private field '{member.Name}' on type '{type?.Name}' is marked for injection. Private fields cannot be injected"); if (member.IsFamily) throw new InvalidOperationException( $"Protected field '{member.Name}' on type '{type?.Name}' is marked for injection. Protected fields cannot be injected"); yield return member; break; } } } protected override Expression GetResolverExpression(FieldInfo field, object resolver) { var ex = Expression.Variable(typeof(Exception)); var exData = Expression.MakeMemberAccess(ex, DataProperty); var block = Expression.Block(field.FieldType, Expression.Call(exData, AddMethod, Expression.Convert(NewGuid, typeof(object)), Expression.Constant(field, typeof(object))), Expression.Rethrow(field.FieldType)); return Expression.TryCatch(base.GetResolverExpression(field, resolver), Expression.Catch(ex, block)); } protected override ResolveDelegate GetResolverDelegate(FieldInfo info, object resolver) { var value = PreProcessResolver(info, resolver); return (ref BuilderContext context) => { try { info.SetValue(context.Existing, context.Resolve(info, value)); return context.Existing; } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), info); throw; } }; } #endregion } } ================================================ FILE: src/Processors/Fields/FieldProcessor.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Policy; using Unity.Resolution; namespace Unity.Processors { public class FieldProcessor : MemberProcessor { #region Constructors public FieldProcessor(IPolicySet policySet) : base(policySet) { } #endregion #region Overrides protected override IEnumerable DeclaredMembers(Type type) { return type.GetDeclaredFields() .Where(member => !member.IsFamily && !member.IsPrivate && !member.IsInitOnly && !member.IsStatic); } protected override Type MemberType(FieldInfo info) => info.FieldType; #endregion #region Expression protected override Expression GetResolverExpression(FieldInfo info, object resolver) { return Expression.Assign( Expression.Field(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info), Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolveFieldMethod, Expression.Constant(info, typeof(FieldInfo)), Expression.Constant(PreProcessResolver(info, resolver), typeof(object))), info.FieldType)); } #endregion #region Resolution protected override ResolveDelegate GetResolverDelegate(FieldInfo info, object resolver) { var value = PreProcessResolver(info, resolver); return (ref BuilderContext context) => { info.SetValue(context.Existing, context.Resolve(info, value)); return context.Existing; }; } #endregion } } ================================================ FILE: src/Processors/Methods/MethodDiagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Processors { public class MethodDiagnostic : MethodProcessor { #region Constructors public MethodDiagnostic(IPolicySet policySet, UnityContainer container) : base(policySet, container) { } #endregion #region Overrides public override IEnumerable Select(Type type, IPolicySet registration) { HashSet memberSet = new HashSet(); // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember && memberSet.Add(injectionMember)) yield return injectionMember; } } // Select Attributed members foreach (var member in type.GetDeclaredMethods()) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!member.IsDefined(AttributeFactories[i].Type, true) || #else if (!member.IsDefined(AttributeFactories[i].Type) || #endif !memberSet.Add(member)) continue; // Validate if (member.IsStatic) { throw new ArgumentException( $"Static method {member.Name} on type '{member.DeclaringType.Name}' is marked for injection. Static methods cannot be injected"); } if (member.IsPrivate) throw new InvalidOperationException( $"Private method '{member.Name}' on type '{member.DeclaringType.Name}' is marked for injection. Private methods cannot be injected"); if (member.IsFamily) throw new InvalidOperationException( $"Protected method '{member.Name}' on type '{member.DeclaringType.Name}' is marked for injection. Protected methods cannot be injected"); if (member.IsGenericMethodDefinition) { throw new ArgumentException( $"Open generic method {member.Name} on type '{member.DeclaringType.Name}' is marked for injection. Open generic methods cannot be injected."); } var parameters = member.GetParameters(); if (parameters.Any(param => param.IsOut)) { throw new ArgumentException( $"Method {member.Name} on type '{member.DeclaringType.Name}' is marked for injection. Methods with 'out' parameters cannot be injected."); } if (parameters.Any(param => param.ParameterType.IsByRef)) { throw new ArgumentException( $"Method {member.Name} on type '{member.DeclaringType.Name}' is marked for injection. Methods with 'ref' parameters cannot be injected."); } yield return member; break; } } } protected override Expression GetResolverExpression(MethodInfo info, object resolvers) { var ex = Expression.Variable(typeof(Exception)); var exData = Expression.MakeMemberAccess(ex, DataProperty); var block = Expression.Block(typeof(void), Expression.Call(exData, AddMethod, Expression.Convert(NewGuid, typeof(object)), Expression.Constant(info, typeof(object))), Expression.Rethrow(typeof(void))); return Expression.TryCatch( Expression.Call( Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info, CreateDiagnosticParameterExpressions(info.GetParameters(), resolvers)), Expression.Catch(ex, block)); } protected override ResolveDelegate GetResolverDelegate(MethodInfo info, object resolvers) { var parameterResolvers = CreateDiagnosticParameterResolvers(info.GetParameters(), resolvers).ToArray(); return (ref BuilderContext c) => { try { if (null == c.Existing) return c.Existing; var parameters = new object[parameterResolvers.Length]; for (var i = 0; i < parameters.Length; i++) parameters[i] = parameterResolvers[i](ref c); info.Invoke(c.Existing, parameters); } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), info); throw; } return c.Existing; }; } #endregion } } ================================================ FILE: src/Processors/Methods/MethodProcessor.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Policy; using Unity.Resolution; namespace Unity.Processors { public class MethodProcessor : ParametersProcessor { #region Constructors public MethodProcessor(IPolicySet policySet, UnityContainer container) : base(policySet, typeof(InjectionMethodAttribute), container) { } #endregion #region Selection protected override IEnumerable DeclaredMembers(Type type) { return type.GetDeclaredMethods() .Where(member => !member.IsFamily && !member.IsPrivate && !member.IsStatic); } #endregion #region Expression protected override Expression GetResolverExpression(MethodInfo info, object resolvers) { try { return Expression.Call( Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info, CreateParameterExpressions(info.GetParameters(), resolvers)); } catch (ArgumentException ex) { throw new InvalidRegistrationException("Invalid Argument", ex); } } #endregion #region Resolution protected override ResolveDelegate GetResolverDelegate(MethodInfo info, object resolvers) { var parameterResolvers = CreateParameterResolvers(info.GetParameters(), resolvers).ToArray(); return (ref BuilderContext c) => { if (null == c.Existing) return c.Existing; var parameters = new object[parameterResolvers.Length]; for (var i = 0; i < parameters.Length; i++) parameters[i] = parameterResolvers[i](ref c); info.Invoke(c.Existing, parameters); return c.Existing; }; } #endregion } } ================================================ FILE: src/Processors/Parameters/ParametersDiagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Resolution; namespace Unity.Processors { public abstract partial class ParametersProcessor { #region Diagnostic Parameter Factories protected virtual IEnumerable CreateDiagnosticParameterExpressions(ParameterInfo[] parameters, object injectors = null) { object[] resolvers = null != injectors && injectors is object[] array && 0 != array.Length ? array : null; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var resolver = null == resolvers ? FromAttribute(parameter) : PreProcessResolver(parameter, resolvers[i]); // Check if has default value #if NET40 Expression defaultValueExpr = null; if (parameter.DefaultValue is DBNull) #else var defaultValueExpr = parameter.HasDefaultValue ? Expression.Constant(parameter.DefaultValue, parameter.ParameterType) : null; if (!parameter.HasDefaultValue) #endif { var ex = Expression.Variable(typeof(Exception)); var exData = Expression.MakeMemberAccess(ex, DataProperty); var block = Expression.Block(parameter.ParameterType, Expression.Call(exData, AddMethod, Expression.Convert(NewGuid, typeof(object)), Expression.Constant(parameter, typeof(object))), Expression.Rethrow(parameter.ParameterType)); var tryBlock = Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolveParameterMethod, Expression.Constant(parameter, typeof(ParameterInfo)), Expression.Constant(resolver, typeof(object))), parameter.ParameterType); yield return Expression.TryCatch(tryBlock, Expression.Catch(ex, block)); } else { var variable = Expression.Variable(parameter.ParameterType); var resolve = Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolveParameterMethod, Expression.Constant(parameter, typeof(ParameterInfo)), Expression.Constant(resolver, typeof(object))), parameter.ParameterType); yield return Expression.Block(new[] { variable }, new Expression[] { Expression.TryCatch( Expression.Assign(variable, resolve), Expression.Catch(typeof(Exception), Expression.Assign(variable, defaultValueExpr))), variable }); } } } protected virtual IEnumerable> CreateDiagnosticParameterResolvers(ParameterInfo[] parameters, object injectors = null) { object[] resolvers = null != injectors && injectors is object[] array && 0 != array.Length ? array : null; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var resolver = null == resolvers ? FromAttribute(parameter) : PreProcessResolver(parameter, resolvers[i]); // TODO: Add diagnostic for parameters // Check if has default value #if NET40 if (parameter.DefaultValue is DBNull) #else if (!parameter.HasDefaultValue) #endif { // Plain vanilla case yield return (ref BuilderContext context) => { try { return context.Resolve(parameter, resolver); } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), parameter); throw; } }; } else { // Check if has default value #if NET40 var defaultValue = !(parameter.DefaultValue is DBNull) ? parameter.DefaultValue : null; #else var defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null; #endif yield return (ref BuilderContext context) => { try { return context.Resolve(parameter, resolver); } catch { return defaultValue; } }; } } } #endregion } } ================================================ FILE: src/Processors/Parameters/ParametersProcessor.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Policy; using Unity.Resolution; namespace Unity.Processors { public abstract partial class ParametersProcessor : MemberProcessor where TMemberInfo : MethodBase { #region Fields protected readonly UnityContainer Container; private static readonly TypeInfo DelegateType = typeof(Delegate).GetTypeInfo(); #endregion #region Constructors protected ParametersProcessor(IPolicySet policySet, Type attribute, UnityContainer container) : base(policySet, attribute) { Container = container; } #endregion #region Overrides protected override Type MemberType(TMemberInfo info) => info.DeclaringType; #endregion #region Expression protected virtual IEnumerable CreateParameterExpressions(ParameterInfo[] parameters, object injectors = null) { object[] resolvers = null != injectors && injectors is object[] array && 0 != array.Length ? array : null; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var resolver = null == resolvers ? FromAttribute(parameter) : PreProcessResolver(parameter, resolvers[i]); // Check if has default value #if NET40 var defaultValueExpr = parameter.DefaultValue is DBNull ? Expression.Constant(parameter.DefaultValue, parameter.ParameterType) : null; if (parameter.DefaultValue is DBNull) #else var defaultValueExpr = parameter.HasDefaultValue ? Expression.Constant(parameter.DefaultValue, parameter.ParameterType) : null; if (!parameter.HasDefaultValue) #endif { // Plain vanilla case yield return Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolveParameterMethod, Expression.Constant(parameter, typeof(ParameterInfo)), Expression.Constant(resolver, typeof(object))), parameter.ParameterType); } else { var variable = Expression.Variable(parameter.ParameterType); var resolve = Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolveParameterMethod, Expression.Constant(parameter, typeof(ParameterInfo)), Expression.Constant(resolver, typeof(object))), parameter.ParameterType); yield return Expression.Block(new[] { variable }, new Expression[] { Expression.TryCatch( Expression.Assign(variable, resolve), Expression.Catch(typeof(Exception), Expression.Assign(variable, defaultValueExpr))), variable }); } } } #endregion #region Resolution protected virtual IEnumerable> CreateParameterResolvers(ParameterInfo[] parameters, object injectors = null) { object[] resolvers = null != injectors && injectors is object[] array && 0 != array.Length ? array : null; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var resolver = null == resolvers ? FromAttribute(parameter) : PreProcessResolver(parameter, resolvers[i]); #if NET40 if (parameter.DefaultValue is DBNull) #else if (!parameter.HasDefaultValue) #endif { // Plain vanilla case yield return (ref BuilderContext context) => context.Resolve(parameter, resolver); } else { // Check if has default value #if NET40 var defaultValue = !(parameter.DefaultValue is DBNull) ? parameter.DefaultValue : null; #else var defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null; #endif yield return (ref BuilderContext context) => { try { return context.Resolve(parameter, resolver); } catch { return defaultValue; } }; } } } #endregion #region Implementation private object PreProcessResolver(ParameterInfo parameter, object resolver) { switch (resolver) { case IResolve policy: return (ResolveDelegate)policy.Resolve; case IResolverFactory factory: return factory.GetResolver(parameter); case Type type: return typeof(Type) == parameter.ParameterType ? type : type == parameter.ParameterType ? FromAttribute(parameter) : FromType(type); } return resolver; } private object FromType(Type type) { return (ResolveDelegate)((ref BuilderContext context) => context.Resolve(type, null)); } private object FromAttribute(ParameterInfo info) { #if NET40 var defaultValue = !(info.DefaultValue is DBNull) ? info.DefaultValue : null; #else var defaultValue = info.HasDefaultValue ? info.DefaultValue : null; #endif foreach (var node in AttributeFactories) { if (null == node.Factory) continue; var attribute = info.GetCustomAttribute(node.Type); if (null == attribute) continue; // If found match, use provided factory to create expression return node.Factory(attribute, info, defaultValue); } return info; } protected bool CanResolve(ParameterInfo info) { foreach (var node in AttributeFactories) { if (null == node.Factory) continue; var attribute = info.GetCustomAttribute(node.Type); if (null == attribute) continue; // If found match, use provided factory to create expression return CanResolve(info.ParameterType, node.Name(attribute)); } return CanResolve(info.ParameterType, null); } protected bool CanResolve(Type type, string name) { #if NETSTANDARD1_0 || NETCOREAPP1_0 var info = type.GetTypeInfo(); #else var info = type; #endif if (info.IsClass) { // Array could be either registered or Type can be resolved if (type.IsArray) { return Container._isExplicitlyRegistered(type, name) || CanResolve(type.GetElementType(), name); } // Type must be registered if: // - String // - Enumeration // - Primitive // - Abstract // - Interface // - No accessible constructor if (DelegateType.IsAssignableFrom(info) || typeof(string) == type || info.IsEnum || info.IsPrimitive || info.IsAbstract #if NETSTANDARD1_0 || NETCOREAPP1_0 || !info.DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate)) #else || !type.GetTypeInfo().DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate)) #endif return Container._isExplicitlyRegistered(type, name); return true; } // Can resolve if IEnumerable or factory is registered if (info.IsGenericType) { var genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(IEnumerable<>) || Container._isExplicitlyRegistered(genericType, name)) { return true; } } // Check if Type is registered return Container._isExplicitlyRegistered(type, name); } #endregion #region Attribute Factories protected override ResolveDelegate DependencyResolverFactory(Attribute attribute, object info, object value = null) { return (ref BuilderContext context) => context.Resolve(((ParameterInfo)info).ParameterType, ((DependencyResolutionAttribute)attribute).Name); } protected override ResolveDelegate OptionalDependencyResolverFactory(Attribute attribute, object info, object value = null) { return (ref BuilderContext context) => { try { return context.Resolve(((ParameterInfo)info).ParameterType, ((DependencyResolutionAttribute)attribute).Name); } catch (Exception ex) when (!(ex.InnerException is CircularDependencyException)) { return value; } }; } #endregion } } ================================================ FILE: src/Processors/Properties/PropertyDiagnostic.cs ================================================ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Processors { public class PropertyDiagnostic : PropertyProcessor { #region Constructors public PropertyDiagnostic(IPolicySet policySet) : base(policySet) { } #endregion #region Overrides public override IEnumerable Select(Type type, IPolicySet registration) { HashSet memberSet = new HashSet(); // Select Injected Members if (null != ((InternalRegistration)registration).InjectionMembers) { foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers) { if (injectionMember is InjectionMember && memberSet.Add(injectionMember)) yield return injectionMember; } } // Select Attributed members foreach (var member in type.GetDeclaredProperties()) { for (var i = 0; i < AttributeFactories.Length; i++) { #if NET40 if (!member.IsDefined(AttributeFactories[i].Type, true) || #else if (!member.IsDefined(AttributeFactories[i].Type) || #endif !memberSet.Add(member)) continue; if (!member.CanWrite) throw new InvalidOperationException( $"Readonly property '{member.Name}' on type '{type?.Name}' is marked for injection. Readonly properties cannot be injected"); if (0 != member.GetIndexParameters().Length) throw new InvalidOperationException( $"Indexer '{member.Name}' on type '{type?.Name}' is marked for injection. Indexers cannot be injected"); var setter = member.GetSetMethod(true); if (setter.IsStatic) throw new InvalidOperationException( $"Static property '{member.Name}' on type '{type?.Name}' is marked for injection. Static properties cannot be injected"); if (setter.IsPrivate) throw new InvalidOperationException( $"Private property '{member.Name}' on type '{type?.Name}' is marked for injection. Private properties cannot be injected"); if (setter.IsFamily) throw new InvalidOperationException( $"Protected property '{member.Name}' on type '{type?.Name}' is marked for injection. Protected properties cannot be injected"); yield return member; break; } } } protected override Expression GetResolverExpression(PropertyInfo property, object resolver) { var ex = Expression.Variable(typeof(Exception)); var exData = Expression.MakeMemberAccess(ex, DataProperty); var block = Expression.Block(property.PropertyType, Expression.Call(exData, AddMethod, Expression.Convert(NewGuid, typeof(object)), Expression.Constant(property, typeof(object))), Expression.Rethrow(property.PropertyType)); return Expression.TryCatch(base.GetResolverExpression(property, resolver), Expression.Catch(ex, block)); } protected override ResolveDelegate GetResolverDelegate(PropertyInfo info, object resolver) { var value = PreProcessResolver(info, resolver); return (ref BuilderContext context) => { try { #if NET40 info.SetValue(context.Existing, context.Resolve(info, value), null); #else info.SetValue(context.Existing, context.Resolve(info, value)); #endif return context.Existing; } catch (Exception ex) { ex.Data.Add(Guid.NewGuid(), info); throw; } }; } #endregion } } ================================================ FILE: src/Processors/Properties/PropertyProcessor.cs ================================================ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Unity.Builder; using Unity.Policy; using Unity.Resolution; namespace Unity.Processors { public class PropertyProcessor : MemberProcessor { #region Constructors public PropertyProcessor(IPolicySet policySet) : base(policySet) { } #endregion #region Overrides protected override Type MemberType(PropertyInfo info) => info.PropertyType; protected override IEnumerable DeclaredMembers(Type type) { foreach (var member in type.GetDeclaredProperties()) { if (!member.CanWrite || 0 != member.GetIndexParameters().Length) continue; var setter = member.GetSetMethod(true); if (setter.IsPrivate || setter.IsFamily) continue; yield return member; } } #endregion #region Expression protected override Expression GetResolverExpression(PropertyInfo info, object resolver) { return Expression.Assign( Expression.Property(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info), Expression.Convert( Expression.Call(BuilderContextExpression.Context, BuilderContextExpression.ResolvePropertyMethod, Expression.Constant(info, typeof(PropertyInfo)), Expression.Constant(PreProcessResolver(info, resolver), typeof(object))), info.PropertyType)); } #endregion #region Resolution protected override ResolveDelegate GetResolverDelegate(PropertyInfo info, object resolver) { var value = PreProcessResolver(info, resolver); return (ref BuilderContext context) => { #if NET40 info.SetValue(context.Existing, context.Resolve(info, value), null); #else info.SetValue(context.Existing, context.Resolve(info, value)); #endif return context.Existing; }; } #endregion } } ================================================ FILE: src/Properties/AssemblyInfo.cs ================================================ using System; using System.Runtime.CompilerServices; using System.Security; [assembly: CLSCompliant(true)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Unity.Microsoft.DependencyInjection, PublicKey=" + "002400000480000094000000060200000024000052534131000400000100010037b16015885a7a" + "c3c63f3c10b23972ec0dfd6db643eaef45ea2297bdfdc53b1945017fc76fd038dc6e7bf9190024" + "d5435fa49630fdfd143e3149a1506b895fbcce017df1d4f0eac6f05f6d257be45c7be9a8aa8d3d" + "4164892dc75e7c379a22da0d986db393fbd09e4ba42398c80a305361553ef90eb3484d9cf12df9" + "0fc0e6e3")] ================================================ FILE: src/Registration/ContainerRegistration.cs ================================================ using System; using System.Diagnostics; using Unity.Injection; using Unity.Lifetime; using Unity.Storage; namespace Unity.Registration { [DebuggerDisplay("ContainerRegistration: MappedTo={Type?.Name ?? string.Empty}, {LifetimeManager?.GetType()?.Name}")] public class ContainerRegistration : InternalRegistration { #region Constructors public ContainerRegistration(LinkedNode validators, Type mappedTo, LifetimeManager lifetimeManager, InjectionMember[] injectionMembers = null) { Type = mappedTo; Key = typeof(LifetimeManager); Value = lifetimeManager; LifetimeManager.InUse = true; InjectionMembers = injectionMembers; Next = validators; } #endregion #region IContainerRegistration /// /// The type that this registration is mapped to. If no type mapping was done, the /// property and this one will have the same value. /// public virtual Type Type { get; } /// /// The lifetime manager for this registration. /// /// /// This property will be null if this registration is for an open generic. public virtual LifetimeManager LifetimeManager => (LifetimeManager)Value; #endregion } } ================================================ FILE: src/Registration/InternalRegistration.cs ================================================ using System; using System.Diagnostics; using Unity.Injection; using Unity.Policy; using Unity.Storage; using Unity.Strategies; namespace Unity.Registration { [DebuggerDisplay("InternalRegistration")] public class InternalRegistration : LinkedNode, IPolicySet { #region Constructors public InternalRegistration() { } public InternalRegistration(Type policyInterface, object policy) { Key = policyInterface; Value = policy; } #endregion #region Public Members public virtual BuilderStrategy[] BuildChain { get; set; } public InjectionMember[] InjectionMembers { get; set; } public bool BuildRequired { get; set; } public Converter Map { get; set; } #endregion #region IPolicySet public virtual object Get(Type policyInterface) { for (var node = (LinkedNode)this; node != null; node = node.Next) { if (node.Key == policyInterface) return node.Value; } return null; } public virtual void Set(Type policyInterface, object policy) { if (null == Value && null == Key) { Key = policyInterface; Value = policy; } else { for (var node = (LinkedNode)this; node != null; node = node.Next) { if (node.Key == policyInterface) { // Found it node.Value = policy; return; } } // If not found, insert after the current object Next = new LinkedNode { Key = policyInterface, Value = policy, Next = Next }; } } public virtual void Clear(Type policyInterface) { LinkedNode node; LinkedNode last = null; for (node = this; node != null; node = node.Next) { if (node.Key == policyInterface) { if (null == last) { Key = node.Next?.Key; Value = node.Next?.Value; Next = node.Next?.Next; } else { last.Key = node.Next?.Key; last.Value = node.Next?.Value; last.Next = node.Next?.Next; } } last = node; } } #endregion } } ================================================ FILE: src/Storage/HashRegistry.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Security; using Unity.Policy; using Unity.Utility; namespace Unity.Storage { [SecuritySafeCritical] [DebuggerDisplay("HashRegistry ({Count}) ")] internal class HashRegistry : IRegistry { #region Constants private const float LoadFactor = 0.72f; #endregion #region Fields public readonly int[] Buckets; public readonly Entry[] Entries; public int Count; #endregion #region Constructors public HashRegistry(int capacity) { var size = HashHelpers.GetPrime(capacity); Buckets = new int[size]; Entries = new Entry[size]; #if !NET40 unsafe { fixed (int* bucketsPtr = Buckets) { int* ptr = bucketsPtr; var end = bucketsPtr + Buckets.Length; while (ptr < end) *ptr++ = -1; } } #else for(int i = 0; i < Buckets.Length; i++) Buckets[i] = -1; #endif } public HashRegistry(int capacity, LinkedNode head) : this(capacity) { for (var node = head; node != null; node = node.Next) { this[node.Key] = node.Value; } } public HashRegistry(HashRegistry dictionary) : this(HashHelpers.GetPrime(dictionary.Entries.Length * 2)) { Array.Copy(dictionary.Entries, 0, Entries, 0, dictionary.Count); for (var i = 0; i < dictionary.Count; i++) { var hashCode = Entries[i].HashCode; if (hashCode < 0) continue; var bucket = hashCode % Buckets.Length; Entries[i].Next = Buckets[bucket]; Buckets[bucket] = i; } Count = dictionary.Count; dictionary.Count = 0; } #endregion #region IRegistry public IPolicySet this[string key] { get { IPolicySet match = null; var hashCode = null == key ? 0 : key.GetHashCode() & 0x7FFFFFFF; for (var i = Buckets[hashCode % Buckets.Length]; i >= 0; i = Entries[i].Next) { ref var entry = ref Entries[i]; if (entry.HashCode == hashCode && Equals(entry.Key, key)) return entry.Value; // Cover all match if (ReferenceEquals(entry.Key, UnityContainer.All)) match = entry.Value; } return match; } set { var hashCode = null == key ? 0 : key.GetHashCode() & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { if (Entries[i].HashCode == hashCode && Equals(Entries[i].Key, key)) { Entries[i].Value = value; return; } } Entries[Count].HashCode = hashCode; Entries[Count].Next = Buckets[targetBucket]; Entries[Count].Key = key; Entries[Count].Value = value; Buckets[targetBucket] = Count; Count++; } } public bool RequireToGrow => (Entries.Length - Count) < 100 && (float)Count / Entries.Length > LoadFactor; public IEnumerable Keys { get { for (var i = 0; i < Count; i++) { yield return Entries[i].Key; } } } public IEnumerable Values { get { for (var i = 0; i < Count; i++) { yield return Entries[i].Value; } } } public IPolicySet GetOrAdd(string key, Func factory) { var hashCode = (key?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { ref var candidate = ref Entries[i]; if (candidate.HashCode != hashCode || !Equals(candidate.Key, key)) continue; return candidate.Value; } var value = factory(); ref var entry = ref Entries[Count]; entry.HashCode = hashCode; entry.Next = Buckets[targetBucket]; entry.Key = key; entry.Value = value; Buckets[targetBucket] = Count++; return value; } public IPolicySet SetOrReplace(string key, IPolicySet value) { var hashCode = (key?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { ref var candidate = ref Entries[i]; if (candidate.HashCode != hashCode || !Equals(candidate.Key, key)) continue; var old = candidate.Value; candidate.Value = value; return old; } ref var entry = ref Entries[Count]; entry.HashCode = hashCode; entry.Next = Buckets[targetBucket]; entry.Key = key; entry.Value = value; Buckets[targetBucket] = Count++; return null; } #endregion #region Nested Types [DebuggerDisplay("Key='{Key}' Value='{Value}' Hash='{HashCode}'")] public struct Entry { public int HashCode; public int Next; public string Key; public IPolicySet Value; } #endregion } } ================================================ FILE: src/Storage/IRegistry.cs ================================================ using System; using System.Collections.Generic; namespace Unity.Storage { public interface IRegistry { TValue this[TKey index] { get; set; } bool RequireToGrow { get; } IEnumerable Keys { get; } IEnumerable Values { get; } TValue GetOrAdd(TKey key, Func factory); TValue SetOrReplace(TKey key, TValue value); } } ================================================ FILE: src/Storage/IStagedStrategyChain.cs ================================================ using System; namespace Unity.Storage { /// /// This interface defines a standard method to create multi staged strategy chain. /// /// The of strategy /// The stage enum public interface IStagedStrategyChain { /// /// Adds a strategy to the chain at a particular stage. /// /// The strategy to add to the chain. /// The stage to add the strategy. void Add(TStrategyType strategy, TStageEnum stage); /// /// Signals that chain has been changed /// event EventHandler Invalidated; } public static class StagedStrategyChainExtensions { /// /// Add a new strategy for the . /// /// The of strategy /// The stage enum /// The chain this strategy is added to. /// The stage to add the strategy to. public static void AddNew(this IStagedStrategyChain chain, TStageEnum stage) where TStrategy : new() { chain.Add(new TStrategy(), stage); } } } ================================================ FILE: src/Storage/LinkedNode.cs ================================================ using System.Diagnostics; namespace Unity.Storage { [DebuggerDisplay("Node: Key={Key}, Value={Value}")] public class LinkedNode { public TKey Key; public TValue Value; public LinkedNode Next; } } ================================================ FILE: src/Storage/LinkedRegistry.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using Unity.Policy; namespace Unity.Storage { [DebuggerDisplay("LinkedRegistry ({_count}) ")] internal class LinkedRegistry : LinkedNode, IRegistry { #region Fields private int _count; public const int ListToHashCutoverPoint = 8; #endregion #region Constructors public LinkedRegistry(string key, IPolicySet value) { _count = 1; Key = key; Value = value; } public LinkedRegistry(HashRegistry registry) { // TODO: Implement this throw new NotImplementedException(); } #endregion public void Append(string name, IPolicySet value) { LinkedNode node; LinkedNode last = null; for (node = this; node != null; node = node.Next) { if (name == node.Key) { node.Key = Guid.NewGuid().ToString(); } last = node; } // Not found, so add a new one last.Next = new LinkedNode { Key = name, Value = value }; _count++; } #region IRegistry public IPolicySet this[string key] { get { IPolicySet match = null; for (var node = (LinkedNode)this; node != null; node = node.Next) { // Exact match if (Equals(node.Key, key)) return node.Value; // Cover all match if (ReferenceEquals(node.Key, UnityContainer.All)) match = node.Value; } return match; } set { LinkedNode node; LinkedNode last = null; for (node = this; node != null; node = node.Next) { if (Equals(node.Key, key)) { // Found it node.Value = value; return; } last = node; } // Not found, so add a new one last.Next = new LinkedNode { Key = key, Value = value }; _count++; } } public bool RequireToGrow => ListToHashCutoverPoint < _count; public IEnumerable Keys { get { for (LinkedNode node = this; node != null; node = node.Next) { yield return node.Key; } } } public IEnumerable Values { get { for (LinkedNode node = this; node != null; node = node.Next) { yield return node.Value; } } } public IPolicySet GetOrAdd(string name, Func factory) { LinkedNode node; LinkedNode last = null; for (node = this; node != null; node = node.Next) { if (Equals(node.Key, name)) { if (null == node.Value) node.Value = factory(); return node.Value; } last = node; } // Not found, so add a new one last.Next = new LinkedNode { Key = name, Value = factory() }; _count++; return last.Next.Value; } public IPolicySet SetOrReplace(string name, IPolicySet value) { LinkedNode node; LinkedNode last = null; for (node = this; node != null; node = node.Next) { if (Equals(node.Key, name)) { var old = node.Value; node.Value = value; return old; } last = node; } // Not found, so add a new one last.Next = new LinkedNode { Key = name, Value = value }; _count++; return null; } #endregion } } ================================================ FILE: src/Storage/PolicyList.cs ================================================ using System; using System.Collections.Generic; using Unity.Policy; namespace Unity.Storage { /// /// A custom collection wrapper over objects. /// public class PolicyList : IPolicyList { #region Fields private readonly object _sync = new object(); private readonly IPolicyList _innerPolicyList; private IDictionary _policies = null; #endregion #region Constructors /// /// Initialize a new instance of a class. /// public PolicyList() : this(null) { } /// /// Initialize a new instance of a class with another policy list. /// /// An inner policy list to search. public PolicyList(IPolicyList innerPolicyList) { _innerPolicyList = innerPolicyList; } #endregion #region IPolicyList /// /// Gets the number of items in the locator. /// /// /// The number of items in the locator. /// public int Count => _policies?.Count ?? 0; public void Clear(Type type, string name, Type policyInterface) { _policies?.Remove(new PolicyKey(type, name, policyInterface)); } /// /// Removes a default policy. /// /// The type the policy was registered as. public void ClearDefault(Type policyInterface) { Clear(null, null, policyInterface); } public object Get(Type type, string name, Type policyInterface) { object policy = null; if (_policies?.TryGetValue(new PolicyKey(type, name, policyInterface), out policy) ?? false) { return policy; } return _innerPolicyList?.Get(type, name, policyInterface); } public object Get(Type type, Type policyInterface) { object policy = null; if (_policies?.TryGetValue(new PolicyKey(type, UnityContainer.All, policyInterface), out policy) ?? false) { return policy; } return _innerPolicyList?.Get(type, UnityContainer.All, policyInterface); } public void Set(Type type, Type policyInterface, object policy) { if (null == _policies) _policies = new Dictionary(PolicyKeyEqualityComparer.Default); _policies[new PolicyKey(type, UnityContainer.All, policyInterface)] = policy; } public void Set(Type type, string name, Type policyInterface, object policy) { if (null == _policies) _policies = new Dictionary(PolicyKeyEqualityComparer.Default); _policies[new PolicyKey(type, name, policyInterface)] = policy; } #endregion #region Nested Types private struct PolicyKey { #region Fields private readonly int _hash; private readonly Type _type; private readonly string _name; private readonly Type _policy; #endregion public PolicyKey(Type type, string name, Type policyType) { _policy = policyType; _type = type; _name = !string.IsNullOrEmpty(name) ? name : null; _hash = (policyType?.GetHashCode() ?? 0) * 37 + (ReferenceEquals(UnityContainer.All, name) ? type?.GetHashCode() ?? 0 : ((type?.GetHashCode() ?? 0 + 37) ^ (name?.GetHashCode() ?? 0 + 17))); } public override bool Equals(object obj) { if (obj is PolicyKey key) { return this == key; } return false; } public override int GetHashCode() { return _hash; } public static bool operator ==(PolicyKey left, PolicyKey right) { return left._policy == right._policy && left._type == right._type && Equals(left._name, right._name); } public static bool operator !=(PolicyKey left, PolicyKey right) { return !(left == right); } } private class PolicyKeyEqualityComparer : IEqualityComparer { public static readonly PolicyKeyEqualityComparer Default = new PolicyKeyEqualityComparer(); public bool Equals(PolicyKey x, PolicyKey y) { return x == y; } public int GetHashCode(PolicyKey obj) { return obj.GetHashCode(); } } #endregion } } ================================================ FILE: src/Storage/QuickSet.cs ================================================ using System; using System.Security; namespace Unity.Storage { [SecuritySafeCritical] public class QuickSet { #region Fields private int _prime; private int[] Buckets; private Entry[] Entries; public int Count { get; private set; } #endregion #region Constructors public QuickSet() { var size = Primes[_prime]; Buckets = new int[size]; Entries = new Entry[size]; #if !NET40 unsafe { fixed (int* bucketsPtr = Buckets) { int* ptr = bucketsPtr; var end = bucketsPtr + Buckets.Length; while (ptr < end) *ptr++ = -1; } } #else for(int i = 0; i < Buckets.Length; i++) Buckets[i] = -1; #endif } #endregion #region Public Methods public bool Add(int hashCode, TValue value) { var collisions = 0; var targetBucket = (hashCode & UnityContainer.HashMask) % Buckets.Length; // Check for the existing for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { ref var candidate = ref Entries[i]; if (candidate.HashCode != hashCode || !Equals(candidate.Value, value)) { collisions++; continue; } // Already exists return false; } // Expand if required if (Count >= Entries.Length || 3 < collisions) { Expand(); targetBucket = (hashCode & UnityContainer.HashMask) % Buckets.Length; } // Add registration ref var entry = ref Entries[Count]; entry.HashCode = hashCode; entry.Value = value; entry.Next = Buckets[targetBucket]; Buckets[targetBucket] = Count++; return true; } #endregion #region Entry Type private struct Entry { public int HashCode; public TValue Value; public int Next; } #endregion #region Implementation private void Expand() { var entries = Entries; _prime += 1; var size = Primes[_prime]; Buckets = new int[size]; Entries = new Entry[size]; #if !NET40 unsafe { fixed (int* bucketsPtr = Buckets) { int* ptr = bucketsPtr; var end = bucketsPtr + Buckets.Length; while (ptr < end) *ptr++ = -1; } } #else for(int i = 0; i < Buckets.Length; i++) Buckets[i] = -1; #endif Array.Copy(entries, 0, Entries, 0, Count); for (var i = 0; i < Count; i++) { var hashCode = Entries[i].HashCode & UnityContainer.HashMask; if (hashCode < 0) continue; var bucket = hashCode % Buckets.Length; Entries[i].Next = Buckets[bucket]; Buckets[bucket] = i; } } public static readonly int[] Primes = { 11, 37, 71, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369}; #endregion } } ================================================ FILE: src/Storage/RegistrationSet.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Unity.Lifetime; using Unity.Registration; using Unity.Utility; namespace Unity.Storage { [DebuggerDisplay("IEnumerable ({Count}) ")] [DebuggerTypeProxy(typeof(RegistrationSetDebugProxy))] public class RegistrationSet : IEnumerable { #region Fields [DebuggerBrowsable(DebuggerBrowsableState.Never)] private const int InitialCapacity = 71; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int[] _buckets; private Entry[] _entries; #endregion #region Constructors public RegistrationSet() { _buckets = new int[InitialCapacity]; _entries = new Entry[InitialCapacity]; } #endregion #region Public Members public ref Entry this[int index] { get => ref _entries[index]; } public int Count { get; private set; } public void Add(Type type, string name, InternalRegistration registration) { var hashCode = (37 ^ (name?.GetHashCode() ?? 0 + 17)) & 0x7FFFFFFF; var bucket = hashCode % _buckets.Length; var collisionCount = 0; for (int i = _buckets[bucket]; --i >= 0; i = _entries[i].Next) { ref var entry = ref _entries[i]; if (entry.HashCode == hashCode && entry.Name == name) { entry.RegisteredType = type; entry.Name = name; entry.Registration = registration; return; } collisionCount++; } if (Count == _entries.Length || 6 < collisionCount) { IncreaseCapacity(); bucket = hashCode % _buckets.Length; } ref var newEntry = ref _entries[Count++]; newEntry.HashCode = hashCode; newEntry.RegisteredType = type; newEntry.Name = name; newEntry.Registration = registration; newEntry.Next = _buckets[bucket]; _buckets[bucket] = Count; } #endregion #region Implementation private void IncreaseCapacity() { int newSize = HashHelpers.ExpandPrime(Count * 2); var newSlots = new Entry[newSize]; Array.Copy(_entries, newSlots, Count); var newBuckets = new int[newSize]; for (var i = 0; i < Count; i++) { var bucket = newSlots[i].HashCode % newSize; newSlots[i].Next = newBuckets[bucket]; newBuckets[bucket] = i + 1; } _entries = newSlots; _buckets = newBuckets; } public IEnumerator GetEnumerator() { for (var i = 0; i < Count; i++) { yield return _entries[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region Nested Types [DebuggerDisplay("RegisteredType={RegisteredType?.Name}, Name={Name}, MappedTo={RegisteredType == MappedToType ? string.Empty : MappedToType?.Name ?? string.Empty}, {LifetimeManager?.GetType()?.Name}")] [DebuggerTypeProxy(typeof(EntryDebugProxy))] public struct Entry : IContainerRegistration { [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal int Next; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal int HashCode; internal InternalRegistration Registration; public Type RegisteredType { get; internal set; } public string Name { get; internal set; } public Type MappedToType => Registration is ContainerRegistration registration ? registration.Type : null; public LifetimeManager LifetimeManager => Registration is ContainerRegistration registration ? registration.LifetimeManager : null; } private class EntryDebugProxy { private readonly Entry _entry; public EntryDebugProxy(Entry entry) { _entry = entry; } public Type RegisteredType => _entry.RegisteredType; public string Name => _entry.Name; public Type MappedToType => _entry.MappedToType; public LifetimeManager LifetimeManager => _entry.LifetimeManager; } private class RegistrationSetDebugProxy { public RegistrationSetDebugProxy(RegistrationSet set) { Registrations = set._entries .Cast() .Take(set.Count) .ToArray(); } public IContainerRegistration[] Registrations { get; } } #endregion } } ================================================ FILE: src/Storage/Registrations.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Security; using Unity.Policy; using Unity.Utility; namespace Unity.Storage { [SecuritySafeCritical] [DebuggerDisplay("Registrations ({Count}) ")] internal class Registrations : IRegistry> { #region Constants private const float LoadFactor = 0.72f; #endregion #region Fields public readonly int[] Buckets; public readonly Entry[] Entries; public int Count; #endregion #region Constructors public Registrations(int capacity) { var size = HashHelpers.GetPrime(capacity); Buckets = new int[size]; Entries = new Entry[size]; #if !NET40 unsafe { fixed (int* bucketsPtr = Buckets) { int* ptr = bucketsPtr; var end = bucketsPtr + Buckets.Length; while (ptr < end) *ptr++ = -1; } } #else for(int i = 0; i < Buckets.Length; i++) Buckets[i] = -1; #endif } public Registrations(int capacity, LinkedNode> head) : this(capacity) { for (var node = head; node != null; node = node.Next) { this[node.Key] = node.Value; } } public Registrations(Registrations dictionary) : this(HashHelpers.GetPrime(dictionary.Entries.Length * 2)) { Array.Copy(dictionary.Entries, 0, Entries, 0, dictionary.Count); for (var i = 0; i < dictionary.Count; i++) { var hashCode = Entries[i].HashCode; if (hashCode < 0) continue; var bucket = hashCode % Buckets.Length; Entries[i].Next = Buckets[bucket]; Buckets[bucket] = i; } Count = dictionary.Count; dictionary.Count = 0; } #endregion #region IRegistry public IRegistry this[Type key] { get { var hashCode = null == key ? 0 : key.GetHashCode() & 0x7FFFFFFF; for (var i = Buckets[hashCode % Buckets.Length]; i >= 0; i = Entries[i].Next) { if (Entries[i].HashCode == hashCode && Equals(Entries[i].Key, key)) return Entries[i].Value; } return default(IRegistry); } set { var hashCode = null == key ? 0 : key.GetHashCode() & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { if (Entries[i].HashCode == hashCode && Equals(Entries[i].Key, key)) { Entries[i].Value = value; return; } } Entries[Count].HashCode = hashCode; Entries[Count].Next = Buckets[targetBucket]; Entries[Count].Key = key; Entries[Count].Value = value; Buckets[targetBucket] = Count; Count++; } } public bool RequireToGrow => (Entries.Length - Count) < 100 && (float)Count / Entries.Length > LoadFactor; public IEnumerable Keys { get { for (var i = 0; i < Count; i++) { yield return Entries[i].Key; } } } public IEnumerable> Values { get { for (var i = 0; i < Count; i++) { yield return Entries[i].Value; } } } public IRegistry GetOrAdd(Type key, Func> factory) { var hashCode = (key?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { ref var candidate = ref Entries[i]; if (candidate.HashCode != hashCode || !Equals(candidate.Key, key)) continue; return candidate.Value; } var value = factory(); ref var entry = ref Entries[Count]; entry.HashCode = hashCode; entry.Next = Buckets[targetBucket]; entry.Key = key; entry.Value = value; Buckets[targetBucket] = Count++; return value; } public IRegistry SetOrReplace(Type key, IRegistry value) { var hashCode = (key?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % Buckets.Length; for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next) { ref var candidate = ref Entries[i]; if (candidate.HashCode != hashCode || !Equals(candidate.Key, key)) continue; var old = candidate.Value; candidate.Value = value; return old; } ref var entry = ref Entries[Count]; entry.HashCode = hashCode; entry.Next = Buckets[targetBucket]; entry.Key = key; entry.Value = value; Buckets[targetBucket] = Count++; return default(IRegistry); } #endregion #region Nested Types [DebuggerDisplay("Type='{Key}' Registrations='{Value}' Hash='{HashCode}'")] public struct Entry { public int HashCode; public int Next; public Type Key; public IRegistry Value; } #endregion } } ================================================ FILE: src/Storage/StagedStrategyChain.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Unity.Storage { /// /// Represents a chain of responsibility for builder strategies partitioned by stages. /// /// The stage enumeration to partition the strategies. /// public class StagedStrategyChain : IStagedStrategyChain, IEnumerable { #region Fields private static readonly int _size = typeof(TStageEnum).GetTypeInfo().DeclaredFields.Count(f => f.IsPublic && f.IsStatic); private readonly object _lockObject = new object(); private readonly StagedStrategyChain _innerChain; private readonly IList[] _stages = new IList[_size]; private TStrategyType[] _cache; #endregion #region Constructors /// /// Initialize a new instance of the class. /// public StagedStrategyChain() : this(null) { } /// /// Initialize a new instance of the class with an inner strategy chain to use when building. /// /// The inner strategy chain to use first when finding strategies in the build operation. public StagedStrategyChain(StagedStrategyChain innerChain) { if (null != innerChain) { _innerChain = innerChain; _innerChain.Invalidated += OnParentInvalidated; } for (var i = 0; i < _stages.Length; ++i) { _stages[i] = new List(); } } #endregion #region Implementation private void OnParentInvalidated(object sender, EventArgs e) { lock (_lockObject) { _cache = null; } } private IEnumerable Enumerate(int i) { return (_innerChain?.Enumerate(i) ?? Enumerable.Empty()).Concat(_stages[i]); } #endregion #region IStagedStrategyChain /// /// Signals that chain has been changed /// public event EventHandler Invalidated; /// /// Adds a strategy to the chain at a particular stage. /// /// The strategy to add to the chain. /// The stage to add the strategy. public void Add(TStrategyType strategy, TStageEnum stage) { lock (_lockObject) { _stages[Convert.ToInt32(stage)].Add(strategy); _cache = null; Invalidated?.Invoke(this, new EventArgs()); } } #endregion #region IEnumerable public TStrategyType[] ToArray() { var cache = _cache; if (null != cache) return cache; lock (_lockObject) { if (null == _cache) { _cache = Enumerable.Range(0, _stages.Length) .SelectMany(Enumerate) .ToArray(); } cache = _cache; } return cache; } public IEnumerator GetEnumerator() { var cache = _cache; if (null == cache) { lock (_lockObject) { if (null == _cache) { _cache = Enumerable.Range(0, _stages.Length) .SelectMany(Enumerate) .ToArray(); } cache = _cache; } } foreach (var strategyType in cache) { yield return strategyType; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } } ================================================ FILE: src/Strategies/ArrayResolveStrategy.cs ================================================ using System; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Strategies { /// /// This strategy is responsible for building Array /// public class ArrayResolveStrategy : BuilderStrategy { #region Fields private readonly MethodInfo _resolveMethod; private readonly MethodInfo _resolveGenericMethod; #endregion #region Constructors public ArrayResolveStrategy(MethodInfo method, MethodInfo generic) { _resolveMethod = method; _resolveGenericMethod = generic; } #endregion #region Registration and Analysis public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers) { if (registration is ContainerRegistration containerRegistration) { if (type != containerRegistration.Type || #pragma warning disable CS0618 // TODO: InjectionFactory null != injectionMembers && injectionMembers.Any(i => i is InjectionFactory)) #pragma warning restore CS0618 return false; } return null != type && type.IsArray && type.GetArrayRank() == 1; } #endregion #region Build public override void PreBuildUp(ref BuilderContext context) { var plan = context.Registration.Get>(); if (plan == null) { var typeArgument = context.RegistrationType.GetElementType(); var type = ((UnityContainer)context.Container).GetFinalType(typeArgument); if (type != typeArgument) { var method = (ResolveArrayDelegate)_resolveGenericMethod .MakeGenericMethod(typeArgument) .CreateDelegate(typeof(ResolveArrayDelegate)); plan = (ref BuilderContext c) => method(ref c, type); } else { plan = (ResolveDelegate)_resolveMethod .MakeGenericMethod(typeArgument) .CreateDelegate(typeof(ResolveDelegate)); } context.Registration.Set(typeof(ResolveDelegate), plan); } context.Existing = plan(ref context); context.BuildComplete = true; } #endregion #region Nested Types private delegate object ResolveArrayDelegate(ref BuilderContext context, Type type); #endregion } } ================================================ FILE: src/Strategies/BuildKeyMappingStrategy.cs ================================================ using System; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Injection; using Unity.Registration; namespace Unity.Strategies { /// /// Represents a strategy for mapping build keys in the build up operation. /// public class BuildKeyMappingStrategy : BuilderStrategy { #region Registration and Analysis public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers) { if (!(registration is ContainerRegistration containerRegistration)) return null != registration.Map; // Validate input if (null == containerRegistration.Type || type == containerRegistration.Type) return false; // Set mapping policy #if NETSTANDARD1_0 || NETCOREAPP1_0 if (type.GetTypeInfo().IsGenericTypeDefinition && containerRegistration.Type.GetTypeInfo().IsGenericTypeDefinition && null == containerRegistration.Map) #else if (type.IsGenericTypeDefinition && containerRegistration.Type.IsGenericTypeDefinition && null == containerRegistration.Map) #endif { containerRegistration.Map = (Type t) => { #if NETSTANDARD1_0 || NETCOREAPP1_0 || NET40 var targetTypeInfo = t.GetTypeInfo(); #else var targetTypeInfo = t; #endif if (targetTypeInfo.IsGenericTypeDefinition) { // No need to perform a mapping - the source type is an open generic return containerRegistration.Type; } if (targetTypeInfo.GenericTypeArguments.Length != containerRegistration.Type.GetTypeInfo().GenericTypeParameters.Length) throw new ArgumentException("Invalid number of generic arguments in types: {registration.MappedToType} and {t}"); try { return containerRegistration.Type.MakeGenericType(targetTypeInfo.GenericTypeArguments); } catch (ArgumentException ae) { throw new MakeGenericTypeFailedException(ae); } }; } return true; } #endregion #region Build /// /// Called during the chain of responsibility for a build operation. Looks for the /// and if found maps the build key for the current operation. /// /// The context for the operation. public override void PreBuildUp(ref BuilderContext context) { var map = ((InternalRegistration)context.Registration).Map; if (null != map) context.Type = map(context.Type); if (!((InternalRegistration)context.Registration).BuildRequired && ((UnityContainer)context.Container).RegistrationExists(context.Type, context.Name)) { context.Existing = context.Resolve(context.Type, context.Name); context.BuildComplete = true; } } #endregion } } ================================================ FILE: src/Strategies/BuildPlanStrategy.cs ================================================ using System; using System.Globalization; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Exceptions; using Unity.Injection; using Unity.Lifetime; using Unity.Policy; using Unity.Registration; using Unity.Resolution; namespace Unity.Strategies { /// /// A that will look for a build plan /// in the current context. If it exists, it invokes it, otherwise /// it creates one and stores it for later, and invokes it. /// public class BuildPlanStrategy : BuilderStrategy { #region Registration and Analysis public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers) { // Require Re-Resolve if no injectors specified registration.BuildRequired = (injectionMembers?.Any(m => m.BuildRequired) ?? false) || registration is ContainerRegistration cr && cr.LifetimeManager is PerResolveLifetimeManager; return true; } #endregion #region BuilderStrategy /// /// Called during the chain of responsibility for a build operation. /// /// The context for the operation. public override void PreBuildUp(ref BuilderContext context) { // Get resolver if already created var resolver = context.Registration.Get>() ?? (ResolveDelegate) GetGeneric(ref context, typeof(ResolveDelegate)); if (null == resolver) { // Check if can create at all #if NETCOREAPP1_0 || NETSTANDARD1_0 if (!(context.Registration is ContainerRegistration) && context.RegistrationType.GetTypeInfo().IsGenericTypeDefinition) #else if (!(context.Registration is ContainerRegistration) && context.RegistrationType.IsGenericTypeDefinition) #endif { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "The type {0} is an open generic type. An open generic type cannot be resolved.", context.RegistrationType.FullName), new InvalidRegistrationException()); } else if (context.Type.IsArray && context.Type.GetArrayRank() > 1) { var message = $"Invalid array {context.Type}. Only arrays of rank 1 are supported"; throw new ArgumentException(message, new InvalidRegistrationException()); } // Get resolver factory var factory = context.Registration.Get() ?? (ResolveDelegateFactory)( context.Get(context.Type, UnityContainer.All, typeof(ResolveDelegateFactory)) ?? GetGeneric(ref context, typeof(ResolveDelegateFactory)) ?? context.Get(null, null, typeof(ResolveDelegateFactory))); // Create plan if (null != factory) { resolver = factory(ref context); context.Registration.Set(typeof(ResolveDelegate), resolver); context.Existing = resolver(ref context); } else throw new ResolutionFailedException(context.Type, context.Name, $"Failed to find Resolve Delegate Factory for Type {context.Type}"); } else { // Plan has been already created, just build the object context.Existing = resolver(ref context); } } #endregion #region Implementation protected static TPolicyInterface Get_Policy(ref BuilderContext context, Type type, string name) { return (TPolicyInterface)(GetGeneric(ref context, typeof(TPolicyInterface), type, name) ?? context.Get(null, null, typeof(TPolicyInterface))); // Nothing! Get Default } protected static object GetGeneric(ref BuilderContext context, Type policyInterface) { if (context.Registration is ContainerRegistration registration && null != context.Type) { // Check if generic #if NETCOREAPP1_0 || NETSTANDARD1_0 if (context.Type.GetTypeInfo().IsGenericType) #else if (context.Type.IsGenericType) #endif { var newType = context.Type.GetGenericTypeDefinition(); return context.Get(newType, context.Name, policyInterface) ?? context.Get(newType, UnityContainer.All, policyInterface); } } else { // Check if generic #if NETCOREAPP1_0 || NETSTANDARD1_0 if (context.RegistrationType.GetTypeInfo().IsGenericType) #else if (context.RegistrationType.IsGenericType) #endif { var newType = context.RegistrationType.GetGenericTypeDefinition(); return context.Get(newType, context.Name, policyInterface) ?? context.Get(newType, UnityContainer.All, policyInterface); } } return null; } protected static object GetGeneric(ref BuilderContext context, Type policyInterface, Type type, string name) { // Check if generic #if NETCOREAPP1_0 || NETSTANDARD1_0 if (type.GetTypeInfo().IsGenericType) #else if (type.IsGenericType) #endif { var newType = type.GetGenericTypeDefinition(); return context.Get(newType, name, policyInterface) ?? context.Get(newType, UnityContainer.All, policyInterface); } return null; } #endregion } } ================================================ FILE: src/Strategies/BuilderStrategy.cs ================================================ using System; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Registration; namespace Unity.Strategies { /// /// Represents a strategy in the chain of responsibility. /// Strategies are required to support both BuildUp and TearDown. /// public abstract class BuilderStrategy { #region Build /// /// Called during the chain of responsibility for a build operation. The /// PreBuildUp method is called when the chain is being executed in the /// forward direction. /// /// Context of the build operation. /// Returns intermediate value or policy public virtual void PreBuildUp(ref BuilderContext context) { } /// /// Called during the chain of responsibility for a build operation. The /// PostBuildUp method is called when the chain has finished the PreBuildUp /// phase and executes in reverse order from the PreBuildUp calls. /// /// Context of the build operation. public virtual void PostBuildUp(ref BuilderContext context) { } #endregion #region Registration and Analysis /// /// Analyze registered type /// /// Reference to hosting container /// /// Reference to registration /// /// Returns true if this strategy will participate in building of registered type public virtual bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers) { return true; } /// /// Analyzes registered type /// /// Reference to hosting container /// Reference to registration /// Returns true if this strategy will participate in building of registered type public virtual bool RequiredToResolveInstance(IUnityContainer container, InternalRegistration registration) { return false; } #endregion #region Implementation public static TPolicyInterface GetPolicy(ref BuilderContext context) { return (TPolicyInterface) (context.Get(context.RegistrationType, context.Name, typeof(TPolicyInterface)) ?? ( #if NETCOREAPP1_0 || NETSTANDARD1_0 context.RegistrationType.GetTypeInfo().IsGenericType #else context.RegistrationType.IsGenericType #endif ? context.Get(context.RegistrationType.GetGenericTypeDefinition(), context.Name, typeof(TPolicyInterface)) ?? context.Get(null, null, typeof(TPolicyInterface)) : context.Get(null, null, typeof(TPolicyInterface)))); } #endregion } } ================================================ FILE: src/Strategies/LifetimeStrategy.cs ================================================ using System; using System.Reflection; using Unity.Builder; using Unity.Injection; using Unity.Lifetime; using Unity.Registration; namespace Unity.Strategies { /// /// An implementation that uses /// a to figure out if an object /// has already been created and to update or remove that /// object from some backing store. /// public class LifetimeStrategy : BuilderStrategy { #region Fields private readonly object _genericLifetimeManagerLock = new object(); #endregion #region Build public override void PreBuildUp(ref BuilderContext context) { LifetimeManager policy = null; if (context.Registration is ContainerRegistration registration) policy = registration.LifetimeManager; if (null == policy || policy is PerResolveLifetimeManager) policy = (LifetimeManager)context.Get(typeof(LifetimeManager)); if (null == policy) { #if NETSTANDARD1_0 || NETCOREAPP1_0 if (!context.RegistrationType.GetTypeInfo().IsGenericType) return; #else if (!context.RegistrationType.IsGenericType) return; #endif var manager = (LifetimeManager)context.Get(context.Type.GetGenericTypeDefinition(), context.Name, typeof(LifetimeManager)); if (null == manager) return; lock (_genericLifetimeManagerLock) { // check whether the policy for closed-generic has been added since first checked policy = (LifetimeManager)context.Registration.Get(typeof(LifetimeManager)); if (null == policy) { policy = manager.CreateLifetimePolicy(); context.Registration.Set(typeof(LifetimeManager), policy); if (policy is IDisposable) { var scope = policy is ContainerControlledLifetimeManager container ? ((UnityContainer)container.Scope)?.LifetimeContainer ?? context.Lifetime : context.Lifetime; scope.Add(policy); } } } } if (policy is SynchronizedLifetimeManager recoveryPolicy) context.RequiresRecovery = recoveryPolicy; var existing = policy.GetValue(context.Lifetime); if (LifetimeManager.NoValue != existing) { context.Existing = existing; context.BuildComplete = true; } } public override void PostBuildUp(ref BuilderContext context) { LifetimeManager policy = null; if (context.Registration is ContainerRegistration registration) policy = registration.LifetimeManager; if (null == policy || policy is PerResolveLifetimeManager) policy = (LifetimeManager)context.Get(typeof(LifetimeManager)); if (LifetimeManager.NoValue != context.Existing) policy?.SetValue(context.Existing, context.Lifetime); } #endregion #region Registration and Analysis public override bool RequiredToBuildType(IUnityContainer container, Type type, InternalRegistration registration, params InjectionMember[] injectionMembers) { var policy = registration.Get(typeof(LifetimeManager)); if (null != policy) { return policy is TransientLifetimeManager ? false : true; } // Dynamic registration #if NETSTANDARD1_0 || NETCOREAPP1_0 if (!(registration is ContainerRegistration) && null != type && type.GetTypeInfo().IsGenericType) return true; #else if (!(registration is ContainerRegistration) && null != type && type.IsGenericType) return true; #endif return false; } public override bool RequiredToResolveInstance(IUnityContainer container, InternalRegistration registration) => true; #endregion } } ================================================ FILE: src/Unity.Container.csproj ================================================  $(VersionBase) $(VersionBase).0 $(VersionBase).0 $(FileVersion) Unity.Container Unity Core Engine Copyright © .NET Foundation and Contributors. All Rights Reserved https://github.com/unitycontainer/unity https://github.com/unitycontainer/unity https://github.com/unitycontainer/unity/blob/master/LICENSE https://avatars1.githubusercontent.com/u/12849707 git Unity Open Source Project Unity Open Source Project true package.snk false Unity Unity Container unitycontainer Microsoft.Practices.Unity IoC latest true ..\..\Abstractions\src\Unity.Abstractions.csproj true Portable false Full true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb all runtime; build; native; contentfiles; analyzers ================================================ FILE: src/Unity.Container.csproj.DotSettings ================================================  True True True True True True True True True True True True True True ================================================ FILE: src/UnityContainer.ContainerContext.cs ================================================ using System; using Unity.Builder; using Unity.Events; using Unity.Extension; using Unity.Lifetime; using Unity.Policy; using Unity.Processors; using Unity.Storage; using Unity.Strategies; namespace Unity { public partial class UnityContainer { /// /// Abstraction layer between container and extensions /// /// /// Implemented as a nested class to gain access to /// container that would otherwise be inaccessible. /// private class ContainerContext : ExtensionContext, IPolicyList { #region Fields private readonly object syncRoot = new object(); private readonly UnityContainer _container; #endregion #region Constructors public ContainerContext(UnityContainer container) { _container = container ?? throw new ArgumentNullException(nameof(container)); Policies = this; } #endregion #region ExtensionContext public override IUnityContainer Container => _container; public override IStagedStrategyChain Strategies { get { return _container._strategies; } } public override IStagedStrategyChain BuildPlanStrategies { get { return _container._processors; } } public override IPolicyList Policies { get; } public override ILifetimeContainer Lifetime => _container.LifetimeContainer; public override event EventHandler Registering { add => _container.Registering += value; remove => _container.Registering -= value; } public override event EventHandler RegisteringInstance { add => _container.RegisteringInstance += value; remove => _container.RegisteringInstance -= value; } public override event EventHandler ChildContainerCreated { add => _container.ChildContainerCreated += value; remove => _container.ChildContainerCreated -= value; } #endregion #region IPolicyList public virtual void ClearAll() { } public virtual object Get(Type type, Type policyInterface) => _container.GetPolicy(type, All, policyInterface); public virtual object Get(Type type, string name, Type policyInterface) => _container.GetPolicy(type, name, policyInterface); public virtual void Set(Type type, Type policyInterface, object policy) => _container.SetPolicy(type, All, policyInterface, policy); public virtual void Set(Type type, string name, Type policyInterface, object policy) => _container.SetPolicy(type, name, policyInterface, policy); public virtual void Clear(Type type, string name, Type policyInterface) { } #endregion } } } ================================================ FILE: src/UnityContainer.Diagnostic.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using Unity.Policy; using Unity.Registration; namespace Unity { [DebuggerDisplay("{" + nameof(DebugName) + "()}")] [DebuggerTypeProxy(typeof(UnityContainerDebugProxy))] public partial class UnityContainer { #region Fields internal ResolveDelegateFactory _buildStrategy = OptimizingFactory; #endregion #region Error Message private static Func CreateMessage = (Exception ex) => { return $"Resolution failed with error: {ex.Message}\n\nFor more detailed information run Unity in debug mode: new UnityContainer().AddExtension(new Diagnostic())"; }; private static string CreateDiagnosticMessage(Exception ex) { const string line = "_____________________________________________________"; var builder = new StringBuilder(); builder.AppendLine(ex.Message); builder.AppendLine(line); builder.AppendLine("Exception occurred while:"); foreach (DictionaryEntry item in ex.Data) builder.AppendLine(DataToString(item.Value)); return builder.ToString(); } private static string DataToString(object value) { switch (value) { case ParameterInfo parameter: return $" for parameter: {parameter.Name}"; case ConstructorInfo constructor: var ctorSignature = string.Join(", ", constructor.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}")); return $" on constructor: {constructor.DeclaringType.Name}({ctorSignature})"; case MethodInfo method: var methodSignature = string.Join(", ", method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}")); return $" on method: {method.Name}({methodSignature})"; case PropertyInfo property: return $" for property: {property.Name}"; case FieldInfo field: return $" for field: {field.Name}"; case Type type: return $"\n• while resolving: {type.Name}"; case Tuple tuple: return $"\n• while resolving: {tuple.Item1.Name} registered with name: {tuple.Item2}"; case Tuple tuple: return $" mapped to: {tuple.Item1?.Name}"; } return value.ToString(); } #endregion #region Debug Support private string DebugName() { var types = (_registrations?.Keys ?? Enumerable.Empty()) .SelectMany(t => _registrations[t].Values) .OfType() .Count(); if (null == _parent) return $"Container[{types}]"; return _parent.DebugName() + $".Child[{types}]"; } internal class UnityContainerDebugProxy { private readonly IUnityContainer _container; public UnityContainerDebugProxy(IUnityContainer container) { _container = container; Id = container.GetHashCode().ToString(); } public string Id { get; } public IEnumerable Registrations => _container.Registrations; } #endregion } } ================================================ FILE: src/UnityContainer.IUnityContainer.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using Unity.Builder; using Unity.Events; using Unity.Injection; using Unity.Lifetime; using Unity.Registration; using Unity.Resolution; using Unity.Storage; namespace Unity { public partial class UnityContainer : IUnityContainer { #region Fields const string LifetimeManagerInUse = "The lifetime manager is already registered. WithLifetime managers cannot be reused, please create a new one."; private Action TypeValidator; #endregion #region Type Registration /// IUnityContainer IUnityContainer.RegisterType(Type typeFrom, Type typeTo, string name, ITypeLifetimeManager lifetimeManager, InjectionMember[] injectionMembers) { var mappedToType = typeTo; var registeredType = typeFrom ?? typeTo; if (null == registeredType) throw new ArgumentNullException(nameof(typeTo)); // Validate if they are assignable TypeValidator?.Invoke(typeFrom, typeTo); try { LifetimeManager manager = (null != lifetimeManager) ? (LifetimeManager)lifetimeManager : TypeLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) throw new InvalidOperationException(LifetimeManagerInUse); // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; var registration = new ContainerRegistration(_validators, typeTo, manager, injectionMembers); if (manager is ContainerControlledLifetimeManager lifeteime) lifeteime.Scope = container; // Add or replace existing var previous = container.Register(registeredType, name, registration); if (previous is ContainerRegistration old && old.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // If Disposable add to container's lifetime if (manager is IDisposable disposableManager) container.LifetimeContainer.Add(disposableManager); // Add Injection Members if (null != injectionMembers && injectionMembers.Length > 0) { foreach (var member in injectionMembers) { member.AddPolicies( registeredType, mappedToType, name, ref registration); } } // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToBuildType(this, registeredType, registration, injectionMembers)) .ToArray(); // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(registeredType, mappedToType, name, manager)); } catch (Exception ex) { var builder = new StringBuilder(); builder.AppendLine(ex.Message); builder.AppendLine(); var parts = new List(); var generics = null == typeFrom ? typeTo?.Name : $"{typeFrom?.Name},{typeTo?.Name}"; if (null != name) parts.Add($" '{name}'"); if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) parts.Add(lifetimeManager.ToString()); if (null != injectionMembers && 0 != injectionMembers.Length) parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString()))); builder.AppendLine($" Error in: RegisterType<{generics}>({string.Join(", ", parts)})"); throw new InvalidOperationException(builder.ToString(), ex); } return this; } #endregion #region Instance Registration /// IUnityContainer IUnityContainer.RegisterInstance(Type type, string name, object instance, IInstanceLifetimeManager lifetimeManager) { var mappedToType = instance?.GetType(); var typeFrom = type ?? mappedToType; LifetimeManager manager = (null != lifetimeManager) ? (LifetimeManager)lifetimeManager : InstanceLifetimeManager.CreateLifetimePolicy(); try { // Validate input if (null == typeFrom) throw new InvalidOperationException($"At least one of Type arguments '{nameof(type)}' or '{nameof(instance)}' must be not 'null'"); if (manager.InUse) throw new InvalidOperationException(LifetimeManagerInUse); manager.SetValue(instance, LifetimeContainer); // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; var registration = new ContainerRegistration(null, mappedToType, manager); if (manager is ContainerControlledLifetimeManager lifeteime) lifeteime.Scope = container; // Add or replace existing var previous = container.Register(typeFrom, name, registration); if (previous is ContainerRegistration old && old.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // If Disposable add to container's lifetime if (manager is IDisposable disposableManager) container.LifetimeContainer.Add(disposableManager); // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToResolveInstance(this, registration)) .ToArray(); // Raise event container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(typeFrom, instance, name, manager)); } catch (Exception ex) { var parts = new List(); if (null != name) parts.Add($" '{name}'"); if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) parts.Add(lifetimeManager.ToString()); var message = $"Error in RegisterInstance<{typeFrom?.Name}>({string.Join(", ", parts)})"; throw new InvalidOperationException(message, ex); } return this; } #endregion #region Factory Registration /// public IUnityContainer RegisterFactory(Type type, string name, Func factory, IFactoryLifetimeManager lifetimeManager) { LifetimeManager manager = (null != lifetimeManager) ? (LifetimeManager)lifetimeManager : FactoryLifetimeManager.CreateLifetimePolicy(); // Validate input if (null == type) throw new ArgumentNullException(nameof(type)); if (null == factory) throw new ArgumentNullException(nameof(factory)); if (manager.InUse) throw new InvalidOperationException(LifetimeManagerInUse); // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; #pragma warning disable CS0618 // TODO: InjectionFactory var injectionFactory = new InjectionFactory(factory); #pragma warning restore CS0618 var injectionMembers = new InjectionMember[] { injectionFactory }; var registration = new ContainerRegistration(_validators, type, manager, injectionMembers); if (manager is ContainerControlledLifetimeManager lifeteime) lifeteime.Scope = container; // Add or replace existing var previous = container.Register(type, name, registration); if (previous is ContainerRegistration old && old.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // If Disposable add to container's lifetime if (manager is IDisposable managerDisposable) container.LifetimeContainer.Add(managerDisposable); // Add Injection Members injectionFactory.AddPolicies( type, type, name, ref registration); // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToBuildType(this, type, registration, injectionMembers)) .ToArray(); // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, manager)); return this; } #endregion #region Registrations /// bool IUnityContainer.IsRegistered(Type type, string name) => ReferenceEquals(All, name) ? IsTypeExplicitlyRegistered(type) : _isExplicitlyRegistered(type, name); #endregion #region Getting objects /// object IUnityContainer.Resolve(Type type, string name, params ResolverOverride[] overrides) { // Verify arguments if (null == type) throw new ArgumentNullException(nameof(type)); var registration = (InternalRegistration)GetRegistration(type, name); var container = registration.Get(typeof(LifetimeManager)) is ContainerControlledLifetimeManager manager ? (UnityContainer)manager.Scope : this; var context = new BuilderContext { List = new PolicyList(), Lifetime = container.LifetimeContainer, Overrides = null != overrides && 0 == overrides.Length ? null : overrides, Registration = registration, RegistrationType = type, Name = name, ExecutePlan = ContextExecutePlan, ResolvePlan = ContextResolvePlan, Type = registration is ContainerRegistration containerRegistration ? containerRegistration.Type : type, }; return container.ExecutePlan(ref context); } #endregion #region BuildUp existing object /// object IUnityContainer.BuildUp(Type type, object existing, string name, params ResolverOverride[] overrides) { // Verify arguments if (null == type) throw new ArgumentNullException(nameof(type)); // Validate if they are assignable if (null != existing && null != TypeValidator) TypeValidator(type, existing.GetType()); var registration = (InternalRegistration)GetRegistration(type, name); var container = registration.Get(typeof(LifetimeManager)) is ContainerControlledLifetimeManager manager ? (UnityContainer)manager.Scope : this; var context = new BuilderContext { List = new PolicyList(), Lifetime = container.LifetimeContainer, Existing = existing, Overrides = null != overrides && 0 == overrides.Length ? null : overrides, Registration = registration, RegistrationType = type, Name = name, ExecutePlan = ContextExecutePlan, ResolvePlan = ContextResolvePlan, Type = registration is ContainerRegistration containerRegistration ? containerRegistration.Type : type }; return ExecutePlan(ref context); } #endregion #region Child container management /// IUnityContainer IUnityContainer.CreateChildContainer() { var child = new UnityContainer(this); ChildContainerCreated?.Invoke(this, new ChildContainerCreatedEventArgs(child._context)); return child; } /// IUnityContainer IUnityContainer.Parent => _parent; #endregion } } ================================================ FILE: src/UnityContainer.Implementation.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Events; using Unity.Extension; using Unity.Injection; using Unity.Lifetime; using Unity.Policy; using Unity.Processors; using Unity.Registration; using Unity.Storage; using Unity.Strategies; namespace Unity { [CLSCompliant(true)] public partial class UnityContainer { #region Delegates internal delegate object GetPolicyDelegate(Type type, string name, Type policyInterface); internal delegate void SetPolicyDelegate(Type type, string name, Type policyInterface, object policy); internal delegate void ClearPolicyDelegate(Type type, string name, Type policyInterface); #endregion #region Fields // Container specific private readonly UnityContainer _root; private readonly UnityContainer _parent; internal readonly LifetimeContainer LifetimeContainer; private List _extensions; private LifetimeManager _typeLifetimeManager; private LifetimeManager _factoryLifetimeManager; private LifetimeManager _instanceLifetimeManager; // Policies private readonly ContainerContext _context; // Strategies private StagedStrategyChain _strategies; private StagedStrategyChain _processors; // Caches private BuilderStrategy[] _strategiesChain; private MemberProcessor[] _processorsChain; // Events private event EventHandler Registering; private event EventHandler RegisteringInstance; private event EventHandler ChildContainerCreated; // Methods [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func GetRegistration; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func Register; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal GetPolicyDelegate GetPolicy; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal SetPolicyDelegate SetPolicy; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal ClearPolicyDelegate ClearPolicy; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Func _get; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func _isExplicitlyRegistered; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Func _getGenericRegistration; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func IsTypeExplicitlyRegistered; private static readonly ContainerLifetimeManager _containerManager = new ContainerLifetimeManager(); #if DEBUG private string id = Guid.NewGuid().ToString(); #endif #endregion #region Constructor /// /// Create a with the given parent container. /// /// The parent . The current object /// will apply its own settings first, and then check the parent for additional ones. private UnityContainer(UnityContainer parent) { // WithLifetime LifetimeContainer = new LifetimeContainer(this); // Context and policies _context = new ContainerContext(this); // Parent _parent = parent ?? throw new ArgumentNullException(nameof(parent)); _parent.LifetimeContainer.Add(this); _root = _parent._root; SetDefaultPolicies = parent.SetDefaultPolicies; // Methods _get = _parent._get; _getGenericRegistration = _parent._getGenericRegistration; _isExplicitlyRegistered = _parent._isExplicitlyRegistered; IsTypeExplicitlyRegistered = _parent.IsTypeExplicitlyRegistered; GetRegistration = (t, n) => _parent.GetRegistration(t, n); Register = CreateAndSetOrUpdate; GetPolicy = parent.GetPolicy; SetPolicy = CreateAndSetPolicy; ClearPolicy = delegate { }; // Strategies _strategies = _parent._strategies; _strategiesChain = _parent._strategiesChain; _strategies.Invalidated += OnStrategiesChanged; // Caches SetDefaultPolicies(this); } #endregion #region Default Policies internal Action SetDefaultPolicies = (UnityContainer container) => { // Default policies container.Defaults = new InternalRegistration(typeof(BuilderContext.ExecutePlanDelegate), container.ContextExecutePlan); // Processors var fieldsProcessor = new FieldProcessor(container.Defaults); var methodsProcessor = new MethodProcessor(container.Defaults, container); var propertiesProcessor = new PropertyProcessor(container.Defaults); var constructorProcessor = new ConstructorProcessor(container.Defaults, container); // Processors chain container._processors = new StagedStrategyChain { { constructorProcessor, BuilderStage.Creation }, { fieldsProcessor, BuilderStage.Fields }, { propertiesProcessor, BuilderStage.Properties }, { methodsProcessor, BuilderStage.Methods } }; // Caches container._processors.Invalidated += (s, e) => container._processorsChain = container._processors.ToArray(); container._processorsChain = container._processors.ToArray(); container.Defaults.Set(typeof(ResolveDelegateFactory), (ResolveDelegateFactory)OptimizingFactory); container.Defaults.Set(typeof(ISelect), constructorProcessor); container.Defaults.Set(typeof(ISelect), fieldsProcessor); container.Defaults.Set(typeof(ISelect), propertiesProcessor); container.Defaults.Set(typeof(ISelect), methodsProcessor); if (null != container._registrations) container.Set(null, null, container.Defaults); }; internal static void SetDiagnosticPolicies(UnityContainer container) { // Default policies container.ContextExecutePlan = UnityContainer.ContextValidatingExecutePlan; container.ContextResolvePlan = UnityContainer.ContextValidatingResolvePlan; container.ExecutePlan = container.ExecuteValidatingPlan; container.Defaults = new InternalRegistration(typeof(BuilderContext.ExecutePlanDelegate), container.ContextExecutePlan); if (null != container._registrations) container.Set(null, null, container.Defaults); // Processors var fieldsProcessor = new FieldDiagnostic(container.Defaults); var methodsProcessor = new MethodDiagnostic(container.Defaults, container); var propertiesProcessor = new PropertyDiagnostic(container.Defaults); var constructorProcessor = new ConstructorDiagnostic(container.Defaults, container); // Processors chain container._processors = new StagedStrategyChain { { constructorProcessor, BuilderStage.Creation }, { fieldsProcessor, BuilderStage.Fields }, { propertiesProcessor, BuilderStage.Properties }, { methodsProcessor, BuilderStage.Methods } }; // Caches container._processors.Invalidated += (s, e) => container._processorsChain = container._processors.ToArray(); container._processorsChain = container._processors.ToArray(); container.Defaults.Set(typeof(ResolveDelegateFactory), container._buildStrategy); container.Defaults.Set(typeof(ISelect), constructorProcessor); container.Defaults.Set(typeof(ISelect), fieldsProcessor); container.Defaults.Set(typeof(ISelect), propertiesProcessor); container.Defaults.Set(typeof(ISelect), methodsProcessor); var validators = new InternalRegistration(); validators.Set(typeof(Func), Validating.ConstructorSelector); validators.Set(typeof(Func), Validating.MethodSelector); validators.Set(typeof(Func), Validating.FieldSelector); validators.Set(typeof(Func), Validating.PropertySelector); container._validators = validators; // Registration Validator container.TypeValidator = (typeFrom, typeTo) => { #if NETSTANDARD1_0 || NETCOREAPP1_0 var infoFrom = typeFrom.GetTypeInfo(); var infoTo = typeTo.GetTypeInfo(); if (null != typeFrom && typeFrom != null && !infoFrom.IsGenericType && null != typeTo && !infoTo.IsGenericType && !infoFrom.IsAssignableFrom(infoTo)) #else if (null != typeFrom && typeFrom != null && !typeFrom.IsGenericType && null != typeTo && !typeTo.IsGenericType && !typeFrom.IsAssignableFrom(typeTo)) #endif { throw new ArgumentException($"The type {typeTo} cannot be assigned to variables of type {typeFrom}."); } #if NETSTANDARD1_0 || NETCOREAPP1_0 if (null != typeFrom && null != typeTo && infoFrom.IsGenericType && infoTo.IsArray && infoFrom.GetGenericTypeDefinition() == typeof(IEnumerable<>)) #else if (null != typeFrom && null != typeTo && typeFrom.IsGenericType && typeTo.IsArray && typeFrom.GetGenericTypeDefinition() == typeof(IEnumerable<>)) #endif throw new ArgumentException($"Type mapping of IEnumerable to array T[] is not supported."); #if NETSTANDARD1_0 || NETCOREAPP1_0 if (null == typeFrom && infoTo.IsInterface) #else if (null == typeFrom && typeTo.IsInterface) #endif throw new ArgumentException($"The type {typeTo} is an interface and can not be constructed."); }; if (null != container._registrations) container.Set(null, null, container.Defaults); } internal LifetimeManager TypeLifetimeManager { get => _typeLifetimeManager ?? _parent.TypeLifetimeManager; set => _typeLifetimeManager = value; } internal LifetimeManager FactoryLifetimeManager { get => _factoryLifetimeManager ?? _parent.FactoryLifetimeManager; set => _factoryLifetimeManager = value; } internal LifetimeManager InstanceLifetimeManager { get => _instanceLifetimeManager ?? _parent.InstanceLifetimeManager; set => _instanceLifetimeManager = value; } #endregion #region Implementation private void CreateAndSetPolicy(Type type, string name, Type policyInterface, object policy) { lock (GetRegistration) { if (null == _registrations) SetupChildContainerBehaviors(); } Set(type, name, policyInterface, policy); } private IPolicySet CreateAndSetOrUpdate(Type type, string name, InternalRegistration registration) { lock (GetRegistration) { if (null == _registrations) SetupChildContainerBehaviors(); } return AddOrUpdate(type, name, registration); } private void SetupChildContainerBehaviors() { lock (_syncRoot) { if (null == _registrations) { _registrations = new Registrations(ContainerInitialCapacity); Set(null, null, Defaults); Register = AddOrUpdate; GetPolicy = Get; SetPolicy = Set; ClearPolicy = Clear; GetRegistration = GetDynamicRegistration; _get = (type, name) => Get(type, name) ?? _parent._get(type, name); _getGenericRegistration = GetOrAddGeneric; IsTypeExplicitlyRegistered = IsTypeTypeExplicitlyRegisteredLocally; _isExplicitlyRegistered = IsExplicitlyRegisteredLocally; } } } private void OnStrategiesChanged(object sender, EventArgs e) { _strategiesChain = _strategies.ToArray(); if (null != _parent && null == _registrations) { SetupChildContainerBehaviors(); } } private BuilderStrategy[] GetBuilders(Type type, InternalRegistration registration) { return _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToBuildType(this, type, registration, null)) .ToArray(); } internal Type GetFinalType(Type argType) { Type next; for (var type = argType; null != type; type = next) { var info = type.GetTypeInfo(); if (info.IsGenericType) { if (IsTypeExplicitlyRegistered(type)) return type; var definition = info.GetGenericTypeDefinition(); if (IsTypeExplicitlyRegistered(definition)) return definition; next = info.GenericTypeArguments[0]; if (IsTypeExplicitlyRegistered(next)) return next; } else if (type.IsArray) { next = type.GetElementType(); if (IsTypeExplicitlyRegistered(next)) return next; } else { return type; } } return argType; } #endregion #region IDisposable Implementation /// /// Dispose this container instance. /// /// /// This class doesn't have a finalizer, so will always be true. /// True if being called typeFrom the IDisposable.Dispose /// method, false if being called typeFrom a finalizer. [SuppressMessage("ReSharper", "InconsistentlySynchronizedField")] protected virtual void Dispose(bool disposing) { if (!disposing) return; List exceptions = null; try { GetPolicy = (type, name, policyInterface) => throw new ObjectDisposedException($"{DebugName()}"); _strategies.Invalidated -= OnStrategiesChanged; _parent?.LifetimeContainer.Remove(this); LifetimeContainer.Dispose(); } catch (Exception exception) { exceptions = new List { exception }; } if (null != _extensions) { foreach (IDisposable disposable in _extensions.OfType() .ToList()) { try { disposable.Dispose(); } catch (Exception e) { if (null == exceptions) exceptions = new List(); exceptions.Add(e); } } _extensions = null; } lock (GetRegistration) { _registrations = new Registrations(1); } if (null != exceptions && exceptions.Count == 1) { throw exceptions[0]; } else if (null != exceptions && exceptions.Count > 1) { throw new AggregateException(exceptions); } } #endregion #region Nested Types private class RegistrationContext : IPolicyList { private readonly InternalRegistration _registration; private readonly UnityContainer _container; private readonly Type _type; private readonly string _name; internal RegistrationContext(UnityContainer container, Type type, string name, InternalRegistration registration) { _registration = registration; _container = container; _type = type; _name = name; } #region IPolicyList public object Get(Type type, Type policyInterface) { if (_type != type) return _container.GetPolicy(type, All, policyInterface); return _registration.Get(policyInterface); } public object Get(Type type, string name, Type policyInterface) { if (_type != type || _name != name) return _container.GetPolicy(type, name, policyInterface); return _registration.Get(policyInterface); } public void Set(Type type, Type policyInterface, object policy) { if (_type != type) _container.SetPolicy(type, All, policyInterface, policy); else _registration.Set(policyInterface, policy); } public void Set(Type type, string name, Type policyInterface, object policy) { if (_type != type || _name != name) _container.SetPolicy(type, name, policyInterface, policy); else _registration.Set(policyInterface, policy); } public void Clear(Type type, string name, Type policyInterface) { if (_type != type || _name != name) _container.ClearPolicy(type, name, policyInterface); else _registration.Clear(policyInterface); } #endregion } [DebuggerDisplay("RegisteredType={RegisteredType?.Name}, Name={Name}, MappedTo={RegisteredType == MappedToType ? string.Empty : MappedToType?.Name ?? string.Empty}, {LifetimeManager?.GetType()?.Name}")] private struct ContainerRegistrationStruct : IContainerRegistration { public Type RegisteredType { get; internal set; } public string Name { get; internal set; } public Type MappedToType { get; internal set; } public LifetimeManager LifetimeManager { get; internal set; } } #endregion } } ================================================ FILE: src/UnityContainer.Public.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Unity.Builder; using Unity.Extension; using Unity.Factories; using Unity.Lifetime; using Unity.Policy; using Unity.Registration; using Unity.Resolution; using Unity.Storage; using Unity.Strategies; namespace Unity { public partial class UnityContainer { #region Constructors /// /// Create a default . /// public UnityContainer() { _root = this; // WithLifetime LifetimeContainer = new LifetimeContainer(this); _typeLifetimeManager = TransientLifetimeManager.Instance; _factoryLifetimeManager = TransientLifetimeManager.Instance; _instanceLifetimeManager = new ContainerControlledLifetimeManager(); // Registrations _registrations = new Registrations(ContainerInitialCapacity); // Context _context = new ContainerContext(this); // Methods _get = Get; _getGenericRegistration = GetOrAddGeneric; _isExplicitlyRegistered = IsExplicitlyRegisteredLocally; IsTypeExplicitlyRegistered = IsTypeTypeExplicitlyRegisteredLocally; GetRegistration = GetOrAdd; Register = AddOrUpdate; GetPolicy = Get; SetPolicy = Set; ClearPolicy = Clear; // Build Strategies _strategies = new StagedStrategyChain { { // Array new ArrayResolveStrategy( typeof(UnityContainer).GetTypeInfo().GetDeclaredMethod(nameof(ResolveArray)), typeof(UnityContainer).GetTypeInfo().GetDeclaredMethod(nameof(ResolveGenericArray))), UnityBuildStage.Enumerable }, {new BuildKeyMappingStrategy(), UnityBuildStage.TypeMapping}, // Mapping {new LifetimeStrategy(), UnityBuildStage.Lifetime}, // WithLifetime {new BuildPlanStrategy(), UnityBuildStage.Creation} // Build }; // Update on change _strategies.Invalidated += OnStrategiesChanged; _strategiesChain = _strategies.ToArray(); // Default Policies and Strategies SetDefaultPolicies(this); Set(typeof(Func<>), All, typeof(LifetimeManager), new PerResolveLifetimeManager()); Set(typeof(Func<>), All, typeof(ResolveDelegateFactory), (ResolveDelegateFactory)DeferredFuncResolverFactory.DeferredResolveDelegateFactory); Set(typeof(Lazy<>), All, typeof(ResolveDelegateFactory), (ResolveDelegateFactory)GenericLazyResolverFactory.GetResolver); Set(typeof(IEnumerable<>), All, typeof(ResolveDelegateFactory), EnumerableResolver.Factory); // Register this instance ((IUnityContainer)this).RegisterInstance(typeof(IUnityContainer), null, this, _containerManager); } #endregion /// public IEnumerable Registrations { get { var set = new QuickSet(); set.Add(NamedType.GetHashCode(typeof(IUnityContainer), null), typeof(IUnityContainer)); // IUnityContainer yield return new ContainerRegistrationStruct { RegisteredType = typeof(IUnityContainer), MappedToType = typeof(UnityContainer), LifetimeManager = _containerManager }; // Scan containers for explicit registrations for (var container = this; null != container; container = container._parent) { // Skip to parent if no registrations if (null == container._registrations) continue; // Hold on to registries var registrations = container._registrations; for (var i = 0; i < registrations.Count; i++) { var registry = registrations.Entries[i].Value; Type type = registrations.Entries[i].Key; switch (registry) { case LinkedRegistry linkedRegistry: for (var node = (LinkedNode)linkedRegistry; null != node; node = node.Next) { if (node.Value is ContainerRegistration containerRegistration && set.Add(NamedType.GetHashCode(type, node.Key), type)) { yield return new ContainerRegistrationStruct { RegisteredType = type, Name = node.Key, LifetimeManager = containerRegistration.LifetimeManager, MappedToType = containerRegistration.Type, }; } } break; case HashRegistry hashRegistry: var count = hashRegistry.Count; var nodes = hashRegistry.Entries; for (var j = 0; j < count; j++) { var name = nodes[j].Key; if (nodes[j].Value is ContainerRegistration containerRegistration && set.Add(NamedType.GetHashCode(type, name), type)) { yield return new ContainerRegistrationStruct { RegisteredType = type, Name = name, LifetimeManager = containerRegistration.LifetimeManager, MappedToType = containerRegistration.Type, }; } } break; default: yield break; } } } } } #region Extension Management /// /// Add an extension to the container. /// /// to add. /// The object that this method was called on (this in C#, Me in Visual Basic). public IUnityContainer AddExtension(IUnityContainerExtensionConfigurator extension) { lock (LifetimeContainer) { if (null == _extensions) _extensions = new List(); _extensions.Add(extension ?? throw new ArgumentNullException(nameof(extension))); } (extension as UnityContainerExtension)?.InitializeExtension(_context); return this; } /// /// Resolve access to a configuration interface exposed by an extension. /// /// Extensions can expose configuration interfaces as well as adding /// strategies and policies to the container. This method walks the list of /// added extensions and returns the first one that implements the requested type. /// /// of configuration interface required. /// The requested extension's configuration interface, or null if not found. public object Configure(Type configurationInterface) { #if NETSTANDARD1_0 || NETCOREAPP1_0 return _extensions?.FirstOrDefault(ex => configurationInterface.GetTypeInfo() .IsAssignableFrom(ex.GetType() .GetTypeInfo())); #else return _extensions?.FirstOrDefault(ex => configurationInterface.IsAssignableFrom(ex.GetType())); #endif } #endregion #region IDisposable Implementation /// /// Dispose this container instance. /// /// /// Disposing the container also disposes any child containers, /// and disposes any instances whose lifetimes are managed /// by the container. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } } ================================================ FILE: src/UnityContainer.Registration.cs ================================================ using System; using System.Diagnostics; using System.Linq; using System.Reflection; using Unity.Policy; using Unity.Registration; using Unity.Storage; namespace Unity { public partial class UnityContainer { #region Constants [DebuggerBrowsable(DebuggerBrowsableState.Never)] private const int ContainerInitialCapacity = 37; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private const int ListToHashCutPoint = 8; [DebuggerBrowsable(DebuggerBrowsableState.Never)] public const string All = "ALL"; [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal const int HashMask = unchecked((int)(uint.MaxValue >> 1)); #endregion #region Registration Fields internal IPolicySet Defaults; private readonly object _syncRoot = new object(); private LinkedNode _validators; private Registrations _registrations; #endregion #region Check Registration private bool IsExplicitlyRegisteredLocally(Type type, string name) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } var registry = candidate.Value; return registry?[name] is ContainerRegistration || (((IUnityContainer)_parent)?.IsRegistered(type, name) ?? false); } return ((IUnityContainer)_parent)?.IsRegistered(type, name) ?? false; } private bool IsTypeTypeExplicitlyRegisteredLocally(Type type) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } return candidate.Value .Values .Any(v => v is ContainerRegistration) || (_parent?.IsTypeExplicitlyRegistered(type) ?? false); } return _parent?.IsTypeExplicitlyRegistered(type) ?? false; } internal bool RegistrationExists(Type type, string name) { IPolicySet defaultRegistration = null; IPolicySet noNameRegistration = null; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; for (var container = this; null != container; container = container._parent) { if (null == container._registrations) continue; var targetBucket = hashCode % container._registrations.Buckets.Length; for (var i = container._registrations.Buckets[targetBucket]; i >= 0; i = container._registrations.Entries[i].Next) { ref var candidate = ref container._registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } var registry = candidate.Value; if (null != registry[name]) return true; if (null == defaultRegistration) defaultRegistration = registry[All]; if (null != name && null == noNameRegistration) noNameRegistration = registry[null]; } } if (null != defaultRegistration) return true; if (null != noNameRegistration) return true; #if NETSTANDARD1_0 || NETCOREAPP1_0 var info = type.GetTypeInfo(); if (!info.IsGenericType) return false; type = info.GetGenericTypeDefinition(); #else if (!type?.IsGenericType ?? false) return false; type = type?.GetGenericTypeDefinition(); #endif hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; for (var container = this; null != container; container = container._parent) { if (null == container._registrations) continue; var targetBucket = hashCode % container._registrations.Buckets.Length; for (var i = container._registrations.Buckets[targetBucket]; i >= 0; i = container._registrations.Entries[i].Next) { ref var candidate = ref container._registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } var registry = candidate.Value; if (null != registry[name]) return true; if (null == defaultRegistration) defaultRegistration = registry[All]; if (null != name && null == noNameRegistration) noNameRegistration = registry[null]; } } if (null != defaultRegistration) return true; return null != noNameRegistration; } #endregion #region Registrations Collections private static RegistrationSet GetRegistrations(UnityContainer container) { var seed = null != container._parent ? GetRegistrations(container._parent) : new RegistrationSet(); if (null == container._registrations) return seed; var length = container._registrations.Count; var entries = container._registrations.Entries; for (var i = null == container._parent ? GetStartIndex() : 0; i < length; i++) { ref var entry = ref entries[i]; var registry = entry.Value; switch (registry) { case LinkedRegistry linkedRegistry: for (var node = (LinkedNode)linkedRegistry; null != node; node = node.Next) { if (node.Value is ContainerRegistration containerRegistration) seed.Add(entry.Key, node.Key, containerRegistration); } break; case HashRegistry hashRegistry: var count = hashRegistry.Count; var nodes = hashRegistry.Entries; for (var j = 0; j < count; j++) { ref var refNode = ref nodes[j]; if (refNode.Value is ContainerRegistration containerRegistration) seed.Add(entry.Key, refNode.Key, containerRegistration); } break; default: throw new InvalidOperationException("Unknown type of registry"); } } return seed; int GetStartIndex() { int start = -1; while (++start < length) { if (typeof(IUnityContainer) != container._registrations.Entries[start].Key) continue; return start; } return 0; } } private static RegistrationSet GetRegistrations(UnityContainer container, params Type[] types) { var seed = null != container._parent ? GetRegistrations(container._parent, types) : new RegistrationSet(); if (null == container._registrations) return seed; foreach (var type in types) { var registry = container.Get(type); if (null == registry?.Values) continue; switch (registry) { case LinkedRegistry linkedRegistry: for (var node = (LinkedNode)linkedRegistry; null != node; node = node.Next) { if (node.Value is ContainerRegistration containerRegistration) seed.Add(type, node.Key, containerRegistration); } break; case HashRegistry hashRegistry: var count = hashRegistry.Count; var nodes = hashRegistry.Entries; for (var j = 0; j < count; j++) { ref var refNode = ref nodes[j]; if (refNode.Value is ContainerRegistration containerRegistration) seed.Add(type, refNode.Key, containerRegistration); } break; default: throw new InvalidOperationException("Unknown type of registry"); } } return seed; } private static RegistrationSet GetNamedRegistrations(UnityContainer container, params Type[] types) { var seed = null != container._parent ? GetNamedRegistrations(container._parent, types) : new RegistrationSet(); if (null == container._registrations) return seed; foreach (var type in types) { var registry = container.Get(type); if (null == registry?.Values) continue; switch (registry) { case LinkedRegistry linkedRegistry: for (var node = (LinkedNode)linkedRegistry; null != node; node = node.Next) { if (node.Value is ContainerRegistration containerRegistration && !string.IsNullOrEmpty(node.Key)) seed.Add(type, node.Key, containerRegistration); } break; case HashRegistry hashRegistry: var count = hashRegistry.Count; var nodes = hashRegistry.Entries; for (var j = 0; j < count; j++) { ref var refNode = ref nodes[j]; if (refNode.Value is ContainerRegistration containerRegistration && !string.IsNullOrEmpty(refNode.Key)) seed.Add(type, refNode.Key, containerRegistration); } break; default: throw new InvalidOperationException("Unknown type of registry"); } } return seed; } #endregion #region Type of named registrations private IRegistry Get(Type type) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } return candidate.Value; } return null; } #endregion #region Registration manipulation // Register new and return overridden registration internal IPolicySet AppendNew(Type type, string name, InternalRegistration registration) { var collisions = 0; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } if (candidate.Value is HashRegistry registry) { candidate.Value = new LinkedRegistry(registry); } var existing = candidate.Value as LinkedRegistry; Debug.Assert(null != existing); existing.Append(name, registration); return null; } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, registration); _registrations.Buckets[targetBucket] = _registrations.Count++; return null; } } // Register new and return overridden registration private IPolicySet AddOrUpdate(Type type, string name, InternalRegistration registration) { var collisions = 0; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } var existing = candidate.Value; if (existing.RequireToGrow) { existing = existing is HashRegistry registry ? new HashRegistry(registry) : new HashRegistry(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing); _registrations.Entries[i].Value = existing; } return existing.SetOrReplace(name, registration); } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, registration); _registrations.Buckets[targetBucket] = _registrations.Count++; return null; } } private IPolicySet GetOrAdd(Type type, string name) { var collisions = 0; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } var policy = candidate.Value?[name]; if (null != policy) return policy; } lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } var existing = candidate.Value; if (existing.RequireToGrow) { existing = existing is HashRegistry registry ? new HashRegistry(registry) : new HashRegistry(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing); _registrations.Entries[i].Value = existing; } return existing.GetOrAdd(name, () => CreateRegistration(type, name)); } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } var registration = CreateRegistration(type, name); ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, registration); _registrations.Buckets[targetBucket] = _registrations.Count++; return registration; } } // Return generic registration or create from factory if not registered private IPolicySet GetOrAddGeneric(Type type, string name, Type definition) { var collisions = 0; int hashCode; int targetBucket; InternalRegistration factory = null; hashCode = (definition?.GetHashCode() ?? 0) & 0x7FFFFFFF; targetBucket = hashCode % _registrations.Buckets.Length; for (var j = _registrations.Buckets[targetBucket]; j >= 0; j = _registrations.Entries[j].Next) { ref var candidate = ref _registrations.Entries[j]; if (candidate.HashCode != hashCode || candidate.Key != definition) { continue; } if (null != (factory = (InternalRegistration)candidate.Value?[name])) break; } if (null == factory && null != _parent) return _parent._getGenericRegistration(type, name, definition); hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; targetBucket = hashCode % _registrations.Buckets.Length; lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } var existing = candidate.Value; if (existing.RequireToGrow) { existing = existing is HashRegistry registry ? new HashRegistry(registry) : new HashRegistry(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing); _registrations.Entries[i].Value = existing; } return existing.GetOrAdd(name, () => CreateRegistration(type, name, factory)); } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } var registration = CreateRegistration(type, name, factory); ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, registration); _registrations.Buckets[targetBucket] = _registrations.Count++; return registration; } } private IPolicySet Get(Type type, string name) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } return candidate.Value?[name]; } return null; } private void Set(Type type, string name, IPolicySet value) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; var collisions = 0; lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } var existing = candidate.Value; if (existing.RequireToGrow) { existing = existing is HashRegistry registry ? new HashRegistry(registry) : new HashRegistry(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing); _registrations.Entries[i].Value = existing; } existing[name] = value; return; } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, value); _registrations.Buckets[targetBucket] = _registrations.Count++; } } #endregion #region Local policy manipulation private object Get(Type type, string name, Type policyInterface) { object policy = null; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } policy = candidate.Value?[name]?.Get(policyInterface); break; } return policy ?? _parent?.GetPolicy(type, name, policyInterface); } private void Set(Type type, string name, Type policyInterface, object policy) { var collisions = 0; var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; lock (_syncRoot) { for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { collisions++; continue; } var existing = candidate.Value; var policySet = existing[name]; if (null != policySet) { policySet.Set(policyInterface, policy); return; } if (existing.RequireToGrow) { existing = existing is HashRegistry registry ? new HashRegistry(registry) : new HashRegistry(LinkedRegistry.ListToHashCutoverPoint * 2, (LinkedRegistry)existing); _registrations.Entries[i].Value = existing; } existing.GetOrAdd(name, () => CreateRegistration(type, policyInterface, policy)); return; } if (_registrations.RequireToGrow || ListToHashCutPoint < collisions) { _registrations = new Registrations(_registrations); targetBucket = hashCode % _registrations.Buckets.Length; } var registration = CreateRegistration(type, policyInterface, policy); ref var entry = ref _registrations.Entries[_registrations.Count]; entry.HashCode = hashCode; entry.Next = _registrations.Buckets[targetBucket]; entry.Key = type; entry.Value = new LinkedRegistry(name, registration); _registrations.Buckets[targetBucket] = _registrations.Count++; } } private void Clear(Type type, string name, Type policyInterface) { var hashCode = (type?.GetHashCode() ?? 0) & 0x7FFFFFFF; var targetBucket = hashCode % _registrations.Buckets.Length; for (var i = _registrations.Buckets[targetBucket]; i >= 0; i = _registrations.Entries[i].Next) { ref var candidate = ref _registrations.Entries[i]; if (candidate.HashCode != hashCode || candidate.Key != type) { continue; } candidate.Value?[name]?.Clear(policyInterface); return; } } #endregion } } ================================================ FILE: src/UnityContainer.Resolution.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Threading; using System.Threading.Tasks; using Unity.Builder; using Unity.Exceptions; using Unity.Lifetime; using Unity.Policy; using Unity.Registration; using Unity.Resolution; using Unity.Storage; using Unity.Strategies; namespace Unity { /// /// A simple, extensible dependency injection container. /// [SecuritySafeCritical] public partial class UnityContainer { #region Dynamic Registrations private IPolicySet GetDynamicRegistration(Type type, string name) { var registration = _get(type, name); if (null != registration) return registration; var info = type.GetTypeInfo(); return !info.IsGenericType ? _root.GetOrAdd(type, name) : GetOrAddGeneric(type, name, info.GetGenericTypeDefinition()); } private IPolicySet CreateRegistration(Type type, string name, InternalRegistration factory) { var registration = new InternalRegistration(type, name); if (null != factory) { registration.InjectionMembers = factory.InjectionMembers; registration.Map = factory.Map; var lifetime = factory.Get(typeof(LifetimeManager)); if (lifetime is IFactoryLifetimeManager ManagerFactory) { var manager = ManagerFactory.CreateLifetimePolicy(); registration.Set(typeof(LifetimeManager), manager); } } registration.BuildChain = GetBuilders(type, registration); return registration; } private IPolicySet CreateRegistration(Type type, string name) { var registration = new InternalRegistration(type, name); if (type.GetTypeInfo().IsGenericType) { var factory = (InternalRegistration)_get(type.GetGenericTypeDefinition(), name); if (null != factory) { registration.InjectionMembers = factory.InjectionMembers; registration.Map = factory.Map; } } registration.BuildChain = GetBuilders(type, registration); return registration; } private IPolicySet CreateRegistration(Type type, Type policyInterface, object policy) { var registration = new InternalRegistration(policyInterface, policy); registration.BuildChain = GetBuilders(type, registration); return registration; } #endregion #region Resolving Enumerable internal IEnumerable ResolveEnumerable(Func resolve, string name) { TElement value; var set = GetRegistrations(this, typeof(TElement)); for (var i = 0; i < set.Count; i++) { try { #if NETSTANDARD1_0 || NETCOREAPP1_0 if (set[i].RegisteredType.GetTypeInfo().IsGenericTypeDefinition) #else if (set[i].RegisteredType.IsGenericTypeDefinition) #endif { var registration = (InternalRegistration)GetRegistration(typeof(TElement), set[i].Name); value = (TElement)resolve(typeof(TElement), set[i].Name, registration); } else value = (TElement)resolve(typeof(TElement), set[i].Name, set[i].Registration); } catch (MakeGenericTypeFailedException) { continue; } catch (ArgumentException ex) when (ex.InnerException is TypeLoadException) { continue; } yield return value; } // If nothing registered attempt to resolve the type if (0 == set.Count) { try { var registration = GetRegistration(typeof(TElement), name); value = (TElement)resolve(typeof(TElement), name, (InternalRegistration)registration); } catch { yield break; } yield return value; } } internal IEnumerable ResolveEnumerable(Func resolve, Type generic, string name) { TElement value; var set = GetRegistrations(this, typeof(TElement), generic); for (var i = 0; i < set.Count; i++) { try { #if NETSTANDARD1_0 || NETCOREAPP1_0 if (set[i].RegisteredType.GetTypeInfo().IsGenericTypeDefinition) #else if (set[i].Registration is ContainerRegistration && set[i].RegisteredType.IsGenericTypeDefinition) #endif { var registration = (InternalRegistration)GetRegistration(typeof(TElement), set[i].Name); value = (TElement)resolve(typeof(TElement), set[i].Name, registration); } else value = (TElement)resolve(typeof(TElement), set[i].Name, set[i].Registration); } catch (MakeGenericTypeFailedException) { continue; } catch (ArgumentException ex) when (ex.InnerException is TypeLoadException) { continue; } yield return value; } // If nothing registered attempt to resolve the type if (0 == set.Count) { try { var registration = GetRegistration(typeof(TElement), name); value = (TElement)resolve(typeof(TElement), name, (InternalRegistration)registration); } catch { yield break; } yield return value; } } #endregion #region Resolving Collections internal static object ResolveArray(ref BuilderContext context) { var type = typeof(TElement); #if NETSTANDARD1_0 || NETCOREAPP1_0 var generic = type.GetTypeInfo().IsGenericType ? type.GetGenericTypeDefinition() : type; #else var generic = type.IsGenericType ? type.GetGenericTypeDefinition() : type; #endif var set = generic == type ? GetNamedRegistrations((UnityContainer)context.Container, type) : GetNamedRegistrations((UnityContainer)context.Container, type, generic); return ResolveRegistrations(ref context, set).ToArray(); } private static IList ResolveRegistrations(ref BuilderContext context, RegistrationSet registrations) { var type = typeof(TElement); var list = new List(); for (var i = 0; i < registrations.Count; i++) { ref var entry = ref registrations[i]; try { #if NETSTANDARD1_0 || NETCOREAPP1_0 if (entry.RegisteredType.GetTypeInfo().IsGenericTypeDefinition) #else if (entry.RegisteredType.IsGenericTypeDefinition) #endif list.Add((TElement)context.Resolve(type, entry.Name)); else list.Add((TElement)context.Resolve(type, entry.Name, entry.Registration)); } catch (MakeGenericTypeFailedException) { /* Ignore */ } catch (ArgumentException ex) when (ex.InnerException is TypeLoadException) { // Ignore } } return list; } #endregion #region Resolving Generic Collections internal static object ResolveGenericArray(ref BuilderContext context, Type type) { #if NETSTANDARD1_0 || NETCOREAPP1_0 var generic = type.GetTypeInfo().IsGenericType ? type.GetGenericTypeDefinition() : type; #else var generic = type.IsGenericType ? type.GetGenericTypeDefinition() : type; #endif var set = generic == type ? GetNamedRegistrations((UnityContainer)context.Container, type) : GetNamedRegistrations((UnityContainer)context.Container, type, generic); return ResolveGenericRegistrations(ref context, set).ToArray(); } private static IList ResolveGenericRegistrations(ref BuilderContext context, RegistrationSet registrations) { var list = new List(); for (var i = 0; i < registrations.Count; i++) { ref var entry = ref registrations[i]; try { list.Add((TElement)context.Resolve(typeof(TElement), entry.Name)); } catch (MakeGenericTypeFailedException) { /* Ignore */ } catch (InvalidOperationException ex) when (ex.InnerException is InvalidRegistrationException) { // Ignore } } return list; } #endregion #region Resolve Delegate Factories private static ResolveDelegate OptimizingFactory(ref BuilderContext context) { var counter = 3; var type = context.Type; var registration = context.Registration; ResolveDelegate seed = null; var chain = ((UnityContainer) context.Container)._processorsChain; // Generate build chain foreach (var processor in chain) seed = processor.GetResolver(type, registration, seed); // Return delegate return (ref BuilderContext c) => { // Check if optimization is required if (0 == Interlocked.Decrement(ref counter)) { #if NET40 Task.Factory.StartNew(() => { #else Task.Run(() => { #endif // Compile build plan on worker thread var expressions = new List(); foreach (var processor in chain) { foreach (var step in processor.GetExpressions(type, registration)) expressions.Add(step); } expressions.Add(BuilderContextExpression.Existing); var lambda = Expression.Lambda>( Expression.Block(expressions), BuilderContextExpression.Context); // Replace this build plan with compiled registration.Set(typeof(ResolveDelegate), lambda.Compile()); }); } return seed?.Invoke(ref c); }; } internal ResolveDelegate CompilingFactory(ref BuilderContext context) { var expressions = new List(); var type = context.Type; var registration = context.Registration; foreach (var processor in _processorsChain) { foreach (var step in processor.GetExpressions(type, registration)) expressions.Add(step); } expressions.Add(BuilderContextExpression.Existing); var lambda = Expression.Lambda>( Expression.Block(expressions), BuilderContextExpression.Context); return lambda.Compile(); } internal ResolveDelegate ResolvingFactory(ref BuilderContext context) { ResolveDelegate seed = null; var type = context.Type; var registration = context.Registration; foreach (var processor in _processorsChain) seed = processor.GetResolver(type, registration, seed); return seed; } #endregion #region Build Plans private ResolveDelegate ExecutePlan { get; set; } = (ref BuilderContext context) => { var i = -1; BuilderStrategy[] chain = ((InternalRegistration)context.Registration).BuildChain; try { while (!context.BuildComplete && ++i < chain.Length) { chain[i].PreBuildUp(ref context); } while (--i >= 0) { chain[i].PostBuildUp(ref context); } } catch (Exception ex) { context.RequiresRecovery?.Recover(); if (!(ex.InnerException is InvalidRegistrationException) && !(ex is InvalidRegistrationException) && !(ex is ObjectDisposedException) && !(ex is MemberAccessException) && !(ex is MakeGenericTypeFailedException) && !(ex is TargetInvocationException)) throw; throw new ResolutionFailedException(context.RegistrationType, context.Name, CreateMessage(ex), ex); } return context.Existing; }; private object ExecuteValidatingPlan(ref BuilderContext context) { var i = -1; BuilderStrategy[] chain = ((InternalRegistration)context.Registration).BuildChain; try { while (!context.BuildComplete && ++i < chain.Length) { chain[i].PreBuildUp(ref context); } while (--i >= 0) { chain[i].PostBuildUp(ref context); } } catch (Exception ex) { context.RequiresRecovery?.Recover(); ex.Data.Add(Guid.NewGuid(), null == context.Name ? context.RegistrationType == context.Type ? (object)context.Type : new Tuple(context.RegistrationType, context.Type) : context.RegistrationType == context.Type ? (object)new Tuple(context.Type, context.Name) : new Tuple(context.RegistrationType, context.Type, context.Name)); var message = CreateDiagnosticMessage(ex); throw new ResolutionFailedException( context.RegistrationType, context.Name, message, ex); } return context.Existing; } #endregion #region BuilderContext internal BuilderContext.ExecutePlanDelegate ContextExecutePlan { get; set; } = (BuilderStrategy[] chain, ref BuilderContext context) => { var i = -1; try { while (!context.BuildComplete && ++i < chain.Length) { chain[i].PreBuildUp(ref context); } while (--i >= 0) { chain[i].PostBuildUp(ref context); } } catch when (null != context.RequiresRecovery) { context.RequiresRecovery.Recover(); throw; } return context.Existing; }; internal static object ContextValidatingExecutePlan(BuilderStrategy[] chain, ref BuilderContext context) { var i = -1; #if !NET40 var value = GetPerResolveValue(context.Parent, context.RegistrationType, context.Name); if (null != value) return value; #endif try { while (!context.BuildComplete && ++i < chain.Length) { chain[i].PreBuildUp(ref context); } while (--i >= 0) { chain[i].PostBuildUp(ref context); } } catch (Exception ex) { context.RequiresRecovery?.Recover(); ex.Data.Add(Guid.NewGuid(), null == context.Name ? context.RegistrationType == context.Type ? (object)context.Type : new Tuple(context.RegistrationType, context.Type) : context.RegistrationType == context.Type ? (object)new Tuple(context.Type, context.Name) : new Tuple(context.RegistrationType, context.Type, context.Name)); throw; } return context.Existing; #if !NET40 object GetPerResolveValue(IntPtr parent, Type registrationType, string name) { if (IntPtr.Zero == parent) return null; unsafe { var parentRef = Unsafe.AsRef(parent.ToPointer()); if (registrationType != parentRef.RegistrationType || name != parentRef.Name) return GetPerResolveValue(parentRef.Parent, registrationType, name); var lifetimeManager = (LifetimeManager)parentRef.Get(typeof(LifetimeManager)); var result = lifetimeManager?.GetValue(); if (LifetimeManager.NoValue != result) return result; throw new InvalidOperationException($"Circular reference for Type: {parentRef.Type}, Name: {parentRef.Name}", new CircularDependencyException(parentRef.Type, parentRef.Name)); } } #endif } internal BuilderContext.ResolvePlanDelegate ContextResolvePlan { get; set; } = (ref BuilderContext context, ResolveDelegate resolver) => resolver(ref context); internal static object ContextValidatingResolvePlan(ref BuilderContext thisContext, ResolveDelegate resolver) { if (null == resolver) throw new ArgumentNullException(nameof(resolver)); #if NET40 return resolver(ref thisContext); #else unsafe { var parent = thisContext.Parent; while(IntPtr.Zero != parent) { var parentRef = Unsafe.AsRef(parent.ToPointer()); if (thisContext.RegistrationType == parentRef.RegistrationType && thisContext.Name == parentRef.Name) throw new CircularDependencyException(thisContext.Type, thisContext.Name); parent = parentRef.Parent; } var context = new BuilderContext { Lifetime = thisContext.Lifetime, Registration = thisContext.Registration, RegistrationType = thisContext.Type, Name = thisContext.Name, Type = thisContext.Type, ExecutePlan = thisContext.ExecutePlan, ResolvePlan = thisContext.ResolvePlan, List = thisContext.List, Overrides = thisContext.Overrides, DeclaringType = thisContext.Type, Parent = new IntPtr(Unsafe.AsPointer(ref thisContext)) }; return resolver(ref context); } #endif } #endregion } } ================================================ FILE: src/Utility/ContainerConstants.cs ================================================  namespace Unity { internal static class Error { public const string MissingDependency = "Could not resolve dependency for build key {0}."; public const string NoOperationExceptionReason = "while resolving"; public const string NotAGenericType = "The type {0} is not a generic type, and you are attempting to inject a generic parameter named '{1}'."; public const string ResolutionFailed = "Resolution of the dependency failed, type = '{0}', name = '{1}'.\nException occurred while: {2}.\nException is: {3} - {4}\n-----------------------------------------------\nAt the time of the exception, the container was: "; public const string SelectedConstructorHasRefParameters = "The constructor {1} selected for type {0} has ref or out parameters. Such parameters are not supported for constructor injection."; public const string SelectedConstructorHasRefItself = "The constructor {1} selected for type {0} has reference to itself. Such references create infinite loop during resolving."; public const string TypesAreNotAssignable = "The type {1} cannot be assigned to variables of type {0}."; public const string UnknownType = ""; } } ================================================ FILE: src/Utility/HashHelpers.cs ================================================ using System; namespace Unity.Utility { internal static class HashHelpers { // Table of prime numbers to use as hash table sizes. public static readonly int[] Primes = { 1, 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369}; internal const Int32 HashPrime = 101; public static bool IsPrime(int candidate) { if ((candidate & 1) != 0) { int limit = (int)Math.Sqrt(candidate); for (int divisor = 3; divisor <= limit; divisor += 2) { if ((candidate % divisor) == 0) return false; } return true; } return (candidate == 2); } public static int GetPrime(int min) { if (min < 0) throw new ArgumentException("Capacity Overflow"); for (int i = 0; i < Primes.Length; i++) { int prime = Primes[i]; if (prime >= min) return prime; } //outside of our predefined table. //compute the hard way. for (int i = (min | 1); i < Int32.MaxValue; i += 2) { if (IsPrime(i) && ((i - 1) % HashPrime != 0)) return i; } return min; } public static int GetMinPrime() { return Primes[0]; } // Returns size of hashtable to grow to. public static int ExpandPrime(int oldSize) { int newSize = 2 * oldSize; // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow. // Note that this check works even when _items.Length overflowed thanks to the (uint) cast if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) { return MaxPrimeArrayLength; } return GetPrime(newSize); } // This is the maximum prime smaller than Array.MaxArrayLength public const int MaxPrimeArrayLength = 0x7FEFFFFD; } } ================================================ FILE: tests/Performance/Abstracts/BasicBase.cs ================================================ using BenchmarkDotNet.Attributes; using Runner.Setup; using System.Collections.Generic; using System.Linq; using Unity; namespace Performance.Tests { [BenchmarkCategory("Basic")] [Config(typeof(BenchmarkConfiguration))] public class BasicBase { protected IUnityContainer _container; protected object[] _storage = new object[20]; private object foo = new Foo(); public virtual void SetupContainer() { _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterFactory("2", c => new Foo00()); _container.RegisterFactory("2", c => new Foo01()); _container.RegisterFactory("2", c => new Foo02()); _container.RegisterFactory("2", c => new Foo03()); _container.RegisterFactory("2", c => new Foo04()); _container.RegisterFactory("2", c => new Foo05()); _container.RegisterFactory("2", c => new Foo06()); _container.RegisterFactory("2", c => new Foo07()); _container.RegisterFactory("2", c => new Foo08()); _container.RegisterFactory("2", c => new Foo09()); _container.RegisterFactory("2", c => new Foo10()); _container.RegisterFactory("2", c => new Foo11()); _container.RegisterFactory("2", c => new Foo12()); _container.RegisterFactory("2", c => new Foo13()); _container.RegisterFactory("2", c => new Foo14()); _container.RegisterFactory("2", c => new Foo15()); _container.RegisterFactory("2", c => new Foo16()); _container.RegisterFactory("2", c => new Foo17()); _container.RegisterFactory("2", c => new Foo18()); _container.RegisterFactory("2", c => new Foo19()); _container.RegisterType(typeof(IFoo00<>), typeof(Foo00<>)); _container.RegisterType(typeof(IFoo01<>), typeof(Foo01<>)); _container.RegisterType(typeof(IFoo02<>), typeof(Foo02<>)); _container.RegisterType(typeof(IFoo03<>), typeof(Foo03<>)); _container.RegisterType(typeof(IFoo04<>), typeof(Foo04<>)); _container.RegisterType(typeof(IFoo05<>), typeof(Foo05<>)); _container.RegisterType(typeof(IFoo06<>), typeof(Foo06<>)); _container.RegisterType(typeof(IFoo07<>), typeof(Foo07<>)); _container.RegisterType(typeof(IFoo08<>), typeof(Foo08<>)); _container.RegisterType(typeof(IFoo09<>), typeof(Foo09<>)); _container.RegisterType(typeof(IFoo10<>), typeof(Foo10<>)); _container.RegisterType(typeof(IFoo11<>), typeof(Foo11<>)); _container.RegisterType(typeof(IFoo12<>), typeof(Foo12<>)); _container.RegisterType(typeof(IFoo13<>), typeof(Foo13<>)); _container.RegisterType(typeof(IFoo14<>), typeof(Foo14<>)); _container.RegisterType(typeof(IFoo15<>), typeof(Foo15<>)); _container.RegisterType(typeof(IFoo16<>), typeof(Foo16<>)); _container.RegisterType(typeof(IFoo17<>), typeof(Foo17<>)); _container.RegisterType(typeof(IFoo18<>), typeof(Foo18<>)); _container.RegisterType(typeof(IFoo19<>), typeof(Foo19<>)); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(new Foo()); _container.RegisterType(typeof(IFoo), typeof(Foo)); _container.RegisterFactory(c => foo); _container.RegisterType( "1"); _container.RegisterType(); _container.RegisterType(typeof(IFoo<>), typeof(Foo<>)); } public virtual object UnityContainer() { _storage[00] = _container.Resolve(typeof(IUnityContainer), null); _storage[01] = _container.Resolve(typeof(IUnityContainer), null); _storage[02] = _container.Resolve(typeof(IUnityContainer), null); _storage[03] = _container.Resolve(typeof(IUnityContainer), null); _storage[04] = _container.Resolve(typeof(IUnityContainer), null); _storage[05] = _container.Resolve(typeof(IUnityContainer), null); _storage[06] = _container.Resolve(typeof(IUnityContainer), null); _storage[07] = _container.Resolve(typeof(IUnityContainer), null); _storage[08] = _container.Resolve(typeof(IUnityContainer), null); _storage[09] = _container.Resolve(typeof(IUnityContainer), null); _storage[10] = _container.Resolve(typeof(IUnityContainer), null); _storage[11] = _container.Resolve(typeof(IUnityContainer), null); _storage[12] = _container.Resolve(typeof(IUnityContainer), null); _storage[13] = _container.Resolve(typeof(IUnityContainer), null); _storage[14] = _container.Resolve(typeof(IUnityContainer), null); _storage[15] = _container.Resolve(typeof(IUnityContainer), null); _storage[16] = _container.Resolve(typeof(IUnityContainer), null); _storage[17] = _container.Resolve(typeof(IUnityContainer), null); _storage[18] = _container.Resolve(typeof(IUnityContainer), null); _storage[19] = _container.Resolve(typeof(IUnityContainer), null); return _storage; } public virtual object UnityContainerAsync() { _storage[00] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[01] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[02] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[03] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[04] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[05] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[06] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[07] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[08] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[09] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[10] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[11] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[12] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[13] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[14] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[15] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[16] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[17] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[18] = _container.Resolve(typeof(IUnityContainerAsync), null); _storage[19] = _container.Resolve(typeof(IUnityContainerAsync), null); return _storage; } public virtual object Unregistered() { _storage[00] = _container.Resolve(typeof(Poco00), null); _storage[01] = _container.Resolve(typeof(Poco01), null); _storage[02] = _container.Resolve(typeof(Poco02), null); _storage[03] = _container.Resolve(typeof(Poco03), null); _storage[04] = _container.Resolve(typeof(Poco04), null); _storage[05] = _container.Resolve(typeof(Poco05), null); _storage[06] = _container.Resolve(typeof(Poco06), null); _storage[07] = _container.Resolve(typeof(Poco07), null); _storage[08] = _container.Resolve(typeof(Poco08), null); _storage[09] = _container.Resolve(typeof(Poco09), null); _storage[10] = _container.Resolve(typeof(Poco10), null); _storage[11] = _container.Resolve(typeof(Poco11), null); _storage[12] = _container.Resolve(typeof(Poco12), null); _storage[13] = _container.Resolve(typeof(Poco13), null); _storage[14] = _container.Resolve(typeof(Poco14), null); _storage[15] = _container.Resolve(typeof(Poco15), null); _storage[16] = _container.Resolve(typeof(Poco16), null); _storage[17] = _container.Resolve(typeof(Poco17), null); _storage[18] = _container.Resolve(typeof(Poco18), null); _storage[19] = _container.Resolve(typeof(Poco19), null); return _storage; } public virtual object Transient() { _storage[00] = _container.Resolve(typeof(PocoWithDependency00), null); _storage[01] = _container.Resolve(typeof(PocoWithDependency01), null); _storage[02] = _container.Resolve(typeof(PocoWithDependency02), null); _storage[03] = _container.Resolve(typeof(PocoWithDependency03), null); _storage[04] = _container.Resolve(typeof(PocoWithDependency04), null); _storage[05] = _container.Resolve(typeof(PocoWithDependency05), null); _storage[06] = _container.Resolve(typeof(PocoWithDependency06), null); _storage[07] = _container.Resolve(typeof(PocoWithDependency07), null); _storage[08] = _container.Resolve(typeof(PocoWithDependency08), null); _storage[09] = _container.Resolve(typeof(PocoWithDependency09), null); _storage[10] = _container.Resolve(typeof(PocoWithDependency10), null); _storage[11] = _container.Resolve(typeof(PocoWithDependency11), null); _storage[12] = _container.Resolve(typeof(PocoWithDependency12), null); _storage[13] = _container.Resolve(typeof(PocoWithDependency13), null); _storage[14] = _container.Resolve(typeof(PocoWithDependency14), null); _storage[15] = _container.Resolve(typeof(PocoWithDependency15), null); _storage[16] = _container.Resolve(typeof(PocoWithDependency16), null); _storage[17] = _container.Resolve(typeof(PocoWithDependency17), null); _storage[18] = _container.Resolve(typeof(PocoWithDependency18), null); _storage[19] = _container.Resolve(typeof(PocoWithDependency19), null); return _storage; } public virtual object Mapping() { _storage[00] = _container.Resolve(typeof(IFoo00), null); _storage[01] = _container.Resolve(typeof(IFoo01), null); _storage[02] = _container.Resolve(typeof(IFoo02), null); _storage[03] = _container.Resolve(typeof(IFoo03), null); _storage[04] = _container.Resolve(typeof(IFoo04), null); _storage[05] = _container.Resolve(typeof(IFoo05), null); _storage[06] = _container.Resolve(typeof(IFoo06), null); _storage[07] = _container.Resolve(typeof(IFoo07), null); _storage[08] = _container.Resolve(typeof(IFoo08), null); _storage[09] = _container.Resolve(typeof(IFoo09), null); _storage[10] = _container.Resolve(typeof(IFoo10), null); _storage[11] = _container.Resolve(typeof(IFoo11), null); _storage[12] = _container.Resolve(typeof(IFoo12), null); _storage[13] = _container.Resolve(typeof(IFoo13), null); _storage[14] = _container.Resolve(typeof(IFoo14), null); _storage[15] = _container.Resolve(typeof(IFoo15), null); _storage[16] = _container.Resolve(typeof(IFoo16), null); _storage[17] = _container.Resolve(typeof(IFoo17), null); _storage[18] = _container.Resolve(typeof(IFoo18), null); _storage[19] = _container.Resolve(typeof(IFoo19), null); return _storage; } public virtual object MappingToSingleton() { _storage[00] = _container.Resolve(typeof(IFoo), null); _storage[01] = _container.Resolve(typeof(IFoo), null); _storage[02] = _container.Resolve(typeof(IFoo), null); _storage[03] = _container.Resolve(typeof(IFoo), null); _storage[04] = _container.Resolve(typeof(IFoo), null); _storage[05] = _container.Resolve(typeof(IFoo), null); _storage[06] = _container.Resolve(typeof(IFoo), null); _storage[07] = _container.Resolve(typeof(IFoo), null); _storage[08] = _container.Resolve(typeof(IFoo), null); _storage[09] = _container.Resolve(typeof(IFoo), null); _storage[10] = _container.Resolve(typeof(IFoo), null); _storage[11] = _container.Resolve(typeof(IFoo), null); _storage[12] = _container.Resolve(typeof(IFoo), null); _storage[13] = _container.Resolve(typeof(IFoo), null); _storage[14] = _container.Resolve(typeof(IFoo), null); _storage[15] = _container.Resolve(typeof(IFoo), null); _storage[16] = _container.Resolve(typeof(IFoo), null); _storage[17] = _container.Resolve(typeof(IFoo), null); _storage[18] = _container.Resolve(typeof(IFoo), null); _storage[19] = _container.Resolve(typeof(IFoo), null); return _storage; } public virtual object GenericInterface() { _storage[00] = _container.Resolve(typeof(IFoo00), null); _storage[01] = _container.Resolve(typeof(IFoo01), null); _storage[02] = _container.Resolve(typeof(IFoo02), null); _storage[03] = _container.Resolve(typeof(IFoo03), null); _storage[04] = _container.Resolve(typeof(IFoo04), null); _storage[05] = _container.Resolve(typeof(IFoo05), null); _storage[06] = _container.Resolve(typeof(IFoo06), null); _storage[07] = _container.Resolve(typeof(IFoo07), null); _storage[08] = _container.Resolve(typeof(IFoo08), null); _storage[09] = _container.Resolve(typeof(IFoo09), null); _storage[10] = _container.Resolve(typeof(IFoo10), null); _storage[11] = _container.Resolve(typeof(IFoo11), null); _storage[12] = _container.Resolve(typeof(IFoo12), null); _storage[13] = _container.Resolve(typeof(IFoo13), null); _storage[14] = _container.Resolve(typeof(IFoo14), null); _storage[15] = _container.Resolve(typeof(IFoo15), null); _storage[16] = _container.Resolve(typeof(IFoo16), null); _storage[17] = _container.Resolve(typeof(IFoo17), null); _storage[18] = _container.Resolve(typeof(IFoo18), null); _storage[19] = _container.Resolve(typeof(IFoo19), null); return _storage; } public virtual object Factory() { _storage[00] = _container.Resolve(typeof(IFoo), null); _storage[01] = _container.Resolve(typeof(IFoo), null); _storage[02] = _container.Resolve(typeof(IFoo), null); _storage[03] = _container.Resolve(typeof(IFoo), null); _storage[04] = _container.Resolve(typeof(IFoo), null); _storage[05] = _container.Resolve(typeof(IFoo), null); _storage[06] = _container.Resolve(typeof(IFoo), null); _storage[07] = _container.Resolve(typeof(IFoo), null); _storage[08] = _container.Resolve(typeof(IFoo), null); _storage[09] = _container.Resolve(typeof(IFoo), null); _storage[10] = _container.Resolve(typeof(IFoo), null); _storage[11] = _container.Resolve(typeof(IFoo), null); _storage[12] = _container.Resolve(typeof(IFoo), null); _storage[13] = _container.Resolve(typeof(IFoo), null); _storage[14] = _container.Resolve(typeof(IFoo), null); _storage[15] = _container.Resolve(typeof(IFoo), null); _storage[16] = _container.Resolve(typeof(IFoo), null); _storage[17] = _container.Resolve(typeof(IFoo), null); _storage[18] = _container.Resolve(typeof(IFoo), null); _storage[19] = _container.Resolve(typeof(IFoo), null); return _storage; } public virtual object Instance() { _storage[00] = _container.Resolve(typeof(IFoo), null); _storage[01] = _container.Resolve(typeof(IFoo), null); _storage[02] = _container.Resolve(typeof(IFoo), null); _storage[03] = _container.Resolve(typeof(IFoo), null); _storage[04] = _container.Resolve(typeof(IFoo), null); _storage[05] = _container.Resolve(typeof(IFoo), null); _storage[06] = _container.Resolve(typeof(IFoo), null); _storage[07] = _container.Resolve(typeof(IFoo), null); _storage[08] = _container.Resolve(typeof(IFoo), null); _storage[09] = _container.Resolve(typeof(IFoo), null); _storage[10] = _container.Resolve(typeof(IFoo), null); _storage[11] = _container.Resolve(typeof(IFoo), null); _storage[12] = _container.Resolve(typeof(IFoo), null); _storage[13] = _container.Resolve(typeof(IFoo), null); _storage[14] = _container.Resolve(typeof(IFoo), null); _storage[15] = _container.Resolve(typeof(IFoo), null); _storage[16] = _container.Resolve(typeof(IFoo), null); _storage[17] = _container.Resolve(typeof(IFoo), null); _storage[18] = _container.Resolve(typeof(IFoo), null); _storage[19] = _container.Resolve(typeof(IFoo), null); return _storage; } public virtual object LegacyFactory() { _storage[00] = _container.Resolve(typeof(IFoo00), "2"); _storage[01] = _container.Resolve(typeof(IFoo01), "2"); _storage[02] = _container.Resolve(typeof(IFoo02), "2"); _storage[03] = _container.Resolve(typeof(IFoo03), "2"); _storage[04] = _container.Resolve(typeof(IFoo04), "2"); _storage[05] = _container.Resolve(typeof(IFoo05), "2"); _storage[06] = _container.Resolve(typeof(IFoo06), "2"); _storage[07] = _container.Resolve(typeof(IFoo07), "2"); _storage[08] = _container.Resolve(typeof(IFoo08), "2"); _storage[09] = _container.Resolve(typeof(IFoo09), "2"); _storage[10] = _container.Resolve(typeof(IFoo10), "2"); _storage[11] = _container.Resolve(typeof(IFoo11), "2"); _storage[12] = _container.Resolve(typeof(IFoo12), "2"); _storage[13] = _container.Resolve(typeof(IFoo13), "2"); _storage[14] = _container.Resolve(typeof(IFoo14), "2"); _storage[15] = _container.Resolve(typeof(IFoo15), "2"); _storage[16] = _container.Resolve(typeof(IFoo16), "2"); _storage[17] = _container.Resolve(typeof(IFoo17), "2"); _storage[18] = _container.Resolve(typeof(IFoo18), "2"); _storage[19] = _container.Resolve(typeof(IFoo19), "2"); return _storage; } public virtual object Array() { _storage[00] = _container.Resolve(typeof(IFoo00[]), null); _storage[01] = _container.Resolve(typeof(IFoo01[]), null); _storage[02] = _container.Resolve(typeof(IFoo02[]), null); _storage[03] = _container.Resolve(typeof(IFoo03[]), null); _storage[04] = _container.Resolve(typeof(IFoo04[]), null); _storage[05] = _container.Resolve(typeof(IFoo05[]), null); _storage[06] = _container.Resolve(typeof(IFoo06[]), null); _storage[07] = _container.Resolve(typeof(IFoo07[]), null); _storage[08] = _container.Resolve(typeof(IFoo08[]), null); _storage[09] = _container.Resolve(typeof(IFoo09[]), null); _storage[10] = _container.Resolve(typeof(IFoo10[]), null); _storage[11] = _container.Resolve(typeof(IFoo11[]), null); _storage[12] = _container.Resolve(typeof(IFoo12[]), null); _storage[13] = _container.Resolve(typeof(IFoo13[]), null); _storage[14] = _container.Resolve(typeof(IFoo14[]), null); _storage[15] = _container.Resolve(typeof(IFoo15[]), null); _storage[16] = _container.Resolve(typeof(IFoo16[]), null); _storage[17] = _container.Resolve(typeof(IFoo17[]), null); _storage[18] = _container.Resolve(typeof(IFoo18[]), null); _storage[19] = _container.Resolve(typeof(IFoo19[]), null); return _storage; } public virtual object Enumerable() { _storage[00] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[01] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[02] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[03] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[04] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[05] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[06] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[07] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[08] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[09] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[10] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[11] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[12] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[13] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[14] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[15] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[16] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[17] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[18] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); _storage[19] = (_container.Resolve(typeof(IEnumerable), null) as IEnumerable)?.Count(); return _storage; } } } ================================================ FILE: tests/Performance/Abstracts/RegistrationBase.cs ================================================ using BenchmarkDotNet.Attributes; using Runner.Setup; using System.Linq; using Unity; namespace Performance.Tests { [BenchmarkCategory("Registration")] [Config(typeof(BenchmarkConfiguration))] public class RegistrationBase { IUnityContainer _container = new UnityContainer(); readonly Foo00 instance00 = new Foo00(); readonly Foo01 instance01 = new Foo01(); readonly Foo02 instance02 = new Foo02(); readonly Foo03 instance03 = new Foo03(); readonly Foo04 instance04 = new Foo04(); readonly Foo05 instance05 = new Foo05(); readonly Foo06 instance06 = new Foo06(); readonly Foo07 instance07 = new Foo07(); readonly Foo08 instance08 = new Foo08(); readonly Foo09 instance09 = new Foo09(); readonly Foo10 instance10 = new Foo10(); readonly Foo11 instance11 = new Foo11(); readonly Foo12 instance12 = new Foo12(); readonly Foo13 instance13 = new Foo13(); readonly Foo14 instance14 = new Foo14(); readonly Foo15 instance15 = new Foo15(); readonly Foo16 instance16 = new Foo16(); readonly Foo17 instance17 = new Foo17(); readonly Foo18 instance18 = new Foo18(); readonly Foo19 instance19 = new Foo19(); protected object[] _storage = new object[20]; [IterationSetup] public virtual void SetupContainer() { _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterType("1"); _container.RegisterFactory("2", c => new Foo00()); _container.RegisterFactory("2", c => new Foo01()); _container.RegisterFactory("2", c => new Foo02()); _container.RegisterFactory("2", c => new Foo03()); _container.RegisterFactory("2", c => new Foo04()); _container.RegisterFactory("2", c => new Foo05()); _container.RegisterFactory("2", c => new Foo06()); _container.RegisterFactory("2", c => new Foo07()); _container.RegisterFactory("2", c => new Foo08()); _container.RegisterFactory("2", c => new Foo09()); _container.RegisterFactory("2", c => new Foo10()); _container.RegisterFactory("2", c => new Foo11()); _container.RegisterFactory("2", c => new Foo12()); _container.RegisterFactory("2", c => new Foo13()); _container.RegisterFactory("2", c => new Foo14()); _container.RegisterFactory("2", c => new Foo15()); _container.RegisterFactory("2", c => new Foo16()); _container.RegisterFactory("2", c => new Foo17()); _container.RegisterFactory("2", c => new Foo18()); _container.RegisterFactory("2", c => new Foo19()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); _container.RegisterInstance(typeof(IFoo), new Foo()); } public virtual object Register() { _storage[00] = _container.RegisterType(null, typeof(Foo00), null, null); _storage[01] = _container.RegisterType(null, typeof(Foo01), null, null); _storage[02] = _container.RegisterType(null, typeof(Foo02), null, null); _storage[03] = _container.RegisterType(null, typeof(Foo03), null, null); _storage[04] = _container.RegisterType(null, typeof(Foo04), null, null); _storage[05] = _container.RegisterType(null, typeof(Foo05), null, null); _storage[06] = _container.RegisterType(null, typeof(Foo06), null, null); _storage[07] = _container.RegisterType(null, typeof(Foo07), null, null); _storage[08] = _container.RegisterType(null, typeof(Foo08), null, null); _storage[09] = _container.RegisterType(null, typeof(Foo09), null, null); _storage[10] = _container.RegisterType(null, typeof(Foo10), null, null); _storage[11] = _container.RegisterType(null, typeof(Foo11), null, null); _storage[12] = _container.RegisterType(null, typeof(Foo12), null, null); _storage[13] = _container.RegisterType(null, typeof(Foo13), null, null); _storage[14] = _container.RegisterType(null, typeof(Foo14), null, null); _storage[15] = _container.RegisterType(null, typeof(Foo15), null, null); _storage[16] = _container.RegisterType(null, typeof(Foo16), null, null); _storage[17] = _container.RegisterType(null, typeof(Foo17), null, null); _storage[18] = _container.RegisterType(null, typeof(Foo18), null, null); _storage[19] = _container.RegisterType(null, typeof(Foo19), null, null); _storage[00] = _container.RegisterType(null, typeof(Foo00), "1", null); _storage[01] = _container.RegisterType(null, typeof(Foo01), "1", null); _storage[02] = _container.RegisterType(null, typeof(Foo02), "1", null); _storage[03] = _container.RegisterType(null, typeof(Foo03), "1", null); _storage[04] = _container.RegisterType(null, typeof(Foo04), "1", null); _storage[05] = _container.RegisterType(null, typeof(Foo05), "1", null); _storage[06] = _container.RegisterType(null, typeof(Foo06), "1", null); _storage[07] = _container.RegisterType(null, typeof(Foo07), "1", null); _storage[08] = _container.RegisterType(null, typeof(Foo08), "1", null); _storage[09] = _container.RegisterType(null, typeof(Foo09), "1", null); _storage[10] = _container.RegisterType(null, typeof(Foo10), "1", null); _storage[11] = _container.RegisterType(null, typeof(Foo11), "1", null); _storage[12] = _container.RegisterType(null, typeof(Foo12), "1", null); _storage[13] = _container.RegisterType(null, typeof(Foo13), "1", null); _storage[14] = _container.RegisterType(null, typeof(Foo14), "1", null); _storage[15] = _container.RegisterType(null, typeof(Foo15), "1", null); _storage[16] = _container.RegisterType(null, typeof(Foo16), "1", null); _storage[17] = _container.RegisterType(null, typeof(Foo17), "1", null); _storage[18] = _container.RegisterType(null, typeof(Foo18), "1", null); _storage[19] = _container.RegisterType(null, typeof(Foo19), "1", null); _storage[00] = _container.RegisterType(null, typeof(Foo00), "2", null); _storage[01] = _container.RegisterType(null, typeof(Foo01), "2", null); _storage[02] = _container.RegisterType(null, typeof(Foo02), "2", null); _storage[03] = _container.RegisterType(null, typeof(Foo03), "2", null); _storage[04] = _container.RegisterType(null, typeof(Foo04), "2", null); _storage[05] = _container.RegisterType(null, typeof(Foo05), "2", null); _storage[06] = _container.RegisterType(null, typeof(Foo06), "2", null); _storage[07] = _container.RegisterType(null, typeof(Foo07), "2", null); _storage[08] = _container.RegisterType(null, typeof(Foo08), "2", null); _storage[09] = _container.RegisterType(null, typeof(Foo09), "2", null); _storage[10] = _container.RegisterType(null, typeof(Foo10), "2", null); _storage[11] = _container.RegisterType(null, typeof(Foo11), "2", null); _storage[12] = _container.RegisterType(null, typeof(Foo12), "2", null); _storage[13] = _container.RegisterType(null, typeof(Foo13), "2", null); _storage[14] = _container.RegisterType(null, typeof(Foo14), "2", null); _storage[15] = _container.RegisterType(null, typeof(Foo15), "2", null); _storage[16] = _container.RegisterType(null, typeof(Foo16), "2", null); _storage[17] = _container.RegisterType(null, typeof(Foo17), "2", null); _storage[18] = _container.RegisterType(null, typeof(Foo18), "2", null); _storage[19] = _container.RegisterType(null, typeof(Foo19), "2", null); _storage[00] = _container.RegisterType(null, typeof(Foo00), "3", null); _storage[01] = _container.RegisterType(null, typeof(Foo01), "3", null); _storage[02] = _container.RegisterType(null, typeof(Foo02), "3", null); _storage[03] = _container.RegisterType(null, typeof(Foo03), "3", null); _storage[04] = _container.RegisterType(null, typeof(Foo04), "3", null); _storage[05] = _container.RegisterType(null, typeof(Foo05), "3", null); _storage[06] = _container.RegisterType(null, typeof(Foo06), "3", null); _storage[07] = _container.RegisterType(null, typeof(Foo07), "3", null); _storage[08] = _container.RegisterType(null, typeof(Foo08), "3", null); _storage[09] = _container.RegisterType(null, typeof(Foo09), "3", null); _storage[10] = _container.RegisterType(null, typeof(Foo10), "3", null); _storage[11] = _container.RegisterType(null, typeof(Foo11), "3", null); _storage[12] = _container.RegisterType(null, typeof(Foo12), "3", null); _storage[13] = _container.RegisterType(null, typeof(Foo13), "3", null); _storage[14] = _container.RegisterType(null, typeof(Foo14), "3", null); _storage[15] = _container.RegisterType(null, typeof(Foo15), "3", null); _storage[16] = _container.RegisterType(null, typeof(Foo16), "3", null); _storage[17] = _container.RegisterType(null, typeof(Foo17), "3", null); _storage[18] = _container.RegisterType(null, typeof(Foo18), "3", null); _storage[19] = _container.RegisterType(null, typeof(Foo19), "3", null); _storage[00] = _container.RegisterType(null, typeof(Foo00), "4", null); _storage[01] = _container.RegisterType(null, typeof(Foo01), "4", null); _storage[02] = _container.RegisterType(null, typeof(Foo02), "4", null); _storage[03] = _container.RegisterType(null, typeof(Foo03), "4", null); _storage[04] = _container.RegisterType(null, typeof(Foo04), "4", null); _storage[05] = _container.RegisterType(null, typeof(Foo05), "4", null); _storage[06] = _container.RegisterType(null, typeof(Foo06), "4", null); _storage[07] = _container.RegisterType(null, typeof(Foo07), "4", null); _storage[08] = _container.RegisterType(null, typeof(Foo08), "4", null); _storage[09] = _container.RegisterType(null, typeof(Foo09), "4", null); _storage[10] = _container.RegisterType(null, typeof(Foo10), "4", null); _storage[11] = _container.RegisterType(null, typeof(Foo11), "4", null); _storage[12] = _container.RegisterType(null, typeof(Foo12), "4", null); _storage[13] = _container.RegisterType(null, typeof(Foo13), "4", null); _storage[14] = _container.RegisterType(null, typeof(Foo14), "4", null); _storage[15] = _container.RegisterType(null, typeof(Foo15), "4", null); _storage[16] = _container.RegisterType(null, typeof(Foo16), "4", null); _storage[17] = _container.RegisterType(null, typeof(Foo17), "4", null); _storage[18] = _container.RegisterType(null, typeof(Foo18), "4", null); _storage[19] = _container.RegisterType(null, typeof(Foo19), "4", null); return _storage; } public virtual object RegisterMapping() { _storage[00] = _container.RegisterType(typeof(IFoo00), typeof(Foo00), null, null); _storage[01] = _container.RegisterType(typeof(IFoo01), typeof(Foo01), null, null); _storage[02] = _container.RegisterType(typeof(IFoo02), typeof(Foo02), null, null); _storage[03] = _container.RegisterType(typeof(IFoo03), typeof(Foo03), null, null); _storage[04] = _container.RegisterType(typeof(IFoo04), typeof(Foo04), null, null); _storage[05] = _container.RegisterType(typeof(IFoo05), typeof(Foo05), null, null); _storage[06] = _container.RegisterType(typeof(IFoo06), typeof(Foo06), null, null); _storage[07] = _container.RegisterType(typeof(IFoo07), typeof(Foo07), null, null); _storage[08] = _container.RegisterType(typeof(IFoo08), typeof(Foo08), null, null); _storage[09] = _container.RegisterType(typeof(IFoo09), typeof(Foo09), null, null); _storage[10] = _container.RegisterType(typeof(IFoo10), typeof(Foo10), null, null); _storage[11] = _container.RegisterType(typeof(IFoo11), typeof(Foo11), null, null); _storage[12] = _container.RegisterType(typeof(IFoo12), typeof(Foo12), null, null); _storage[13] = _container.RegisterType(typeof(IFoo13), typeof(Foo13), null, null); _storage[14] = _container.RegisterType(typeof(IFoo14), typeof(Foo14), null, null); _storage[15] = _container.RegisterType(typeof(IFoo15), typeof(Foo15), null, null); _storage[16] = _container.RegisterType(typeof(IFoo16), typeof(Foo16), null, null); _storage[17] = _container.RegisterType(typeof(IFoo17), typeof(Foo17), null, null); _storage[18] = _container.RegisterType(typeof(IFoo18), typeof(Foo18), null, null); _storage[19] = _container.RegisterType(typeof(IFoo19), typeof(Foo19), null, null); _storage[00] = _container.RegisterType(typeof(IFoo00), typeof(Foo00), "1", null); _storage[01] = _container.RegisterType(typeof(IFoo01), typeof(Foo01), "1", null); _storage[02] = _container.RegisterType(typeof(IFoo02), typeof(Foo02), "1", null); _storage[03] = _container.RegisterType(typeof(IFoo03), typeof(Foo03), "1", null); _storage[04] = _container.RegisterType(typeof(IFoo04), typeof(Foo04), "1", null); _storage[05] = _container.RegisterType(typeof(IFoo05), typeof(Foo05), "1", null); _storage[06] = _container.RegisterType(typeof(IFoo06), typeof(Foo06), "1", null); _storage[07] = _container.RegisterType(typeof(IFoo07), typeof(Foo07), "1", null); _storage[08] = _container.RegisterType(typeof(IFoo08), typeof(Foo08), "1", null); _storage[09] = _container.RegisterType(typeof(IFoo09), typeof(Foo09), "1", null); _storage[10] = _container.RegisterType(typeof(IFoo10), typeof(Foo10), "1", null); _storage[11] = _container.RegisterType(typeof(IFoo11), typeof(Foo11), "1", null); _storage[12] = _container.RegisterType(typeof(IFoo12), typeof(Foo12), "1", null); _storage[13] = _container.RegisterType(typeof(IFoo13), typeof(Foo13), "1", null); _storage[14] = _container.RegisterType(typeof(IFoo14), typeof(Foo14), "1", null); _storage[15] = _container.RegisterType(typeof(IFoo15), typeof(Foo15), "1", null); _storage[16] = _container.RegisterType(typeof(IFoo16), typeof(Foo16), "1", null); _storage[17] = _container.RegisterType(typeof(IFoo17), typeof(Foo17), "1", null); _storage[18] = _container.RegisterType(typeof(IFoo18), typeof(Foo18), "1", null); _storage[19] = _container.RegisterType(typeof(IFoo19), typeof(Foo19), "1", null); _storage[00] = _container.RegisterType(typeof(IFoo00), typeof(Foo00), "2", null); _storage[01] = _container.RegisterType(typeof(IFoo01), typeof(Foo01), "2", null); _storage[02] = _container.RegisterType(typeof(IFoo02), typeof(Foo02), "2", null); _storage[03] = _container.RegisterType(typeof(IFoo03), typeof(Foo03), "2", null); _storage[04] = _container.RegisterType(typeof(IFoo04), typeof(Foo04), "2", null); _storage[05] = _container.RegisterType(typeof(IFoo05), typeof(Foo05), "2", null); _storage[06] = _container.RegisterType(typeof(IFoo06), typeof(Foo06), "2", null); _storage[07] = _container.RegisterType(typeof(IFoo07), typeof(Foo07), "2", null); _storage[08] = _container.RegisterType(typeof(IFoo08), typeof(Foo08), "2", null); _storage[09] = _container.RegisterType(typeof(IFoo09), typeof(Foo09), "2", null); _storage[10] = _container.RegisterType(typeof(IFoo10), typeof(Foo10), "2", null); _storage[11] = _container.RegisterType(typeof(IFoo11), typeof(Foo11), "2", null); _storage[12] = _container.RegisterType(typeof(IFoo12), typeof(Foo12), "2", null); _storage[13] = _container.RegisterType(typeof(IFoo13), typeof(Foo13), "2", null); _storage[14] = _container.RegisterType(typeof(IFoo14), typeof(Foo14), "2", null); _storage[15] = _container.RegisterType(typeof(IFoo15), typeof(Foo15), "2", null); _storage[16] = _container.RegisterType(typeof(IFoo16), typeof(Foo16), "2", null); _storage[17] = _container.RegisterType(typeof(IFoo17), typeof(Foo17), "2", null); _storage[18] = _container.RegisterType(typeof(IFoo18), typeof(Foo18), "2", null); _storage[19] = _container.RegisterType(typeof(IFoo19), typeof(Foo19), "2", null); _storage[00] = _container.RegisterType(typeof(IFoo00), typeof(Foo00), "3", null); _storage[01] = _container.RegisterType(typeof(IFoo01), typeof(Foo01), "3", null); _storage[02] = _container.RegisterType(typeof(IFoo02), typeof(Foo02), "3", null); _storage[03] = _container.RegisterType(typeof(IFoo03), typeof(Foo03), "3", null); _storage[04] = _container.RegisterType(typeof(IFoo04), typeof(Foo04), "3", null); _storage[05] = _container.RegisterType(typeof(IFoo05), typeof(Foo05), "3", null); _storage[06] = _container.RegisterType(typeof(IFoo06), typeof(Foo06), "3", null); _storage[07] = _container.RegisterType(typeof(IFoo07), typeof(Foo07), "3", null); _storage[08] = _container.RegisterType(typeof(IFoo08), typeof(Foo08), "3", null); _storage[09] = _container.RegisterType(typeof(IFoo09), typeof(Foo09), "3", null); _storage[10] = _container.RegisterType(typeof(IFoo10), typeof(Foo10), "3", null); _storage[11] = _container.RegisterType(typeof(IFoo11), typeof(Foo11), "3", null); _storage[12] = _container.RegisterType(typeof(IFoo12), typeof(Foo12), "3", null); _storage[13] = _container.RegisterType(typeof(IFoo13), typeof(Foo13), "3", null); _storage[14] = _container.RegisterType(typeof(IFoo14), typeof(Foo14), "3", null); _storage[15] = _container.RegisterType(typeof(IFoo15), typeof(Foo15), "3", null); _storage[16] = _container.RegisterType(typeof(IFoo16), typeof(Foo16), "3", null); _storage[17] = _container.RegisterType(typeof(IFoo17), typeof(Foo17), "3", null); _storage[18] = _container.RegisterType(typeof(IFoo18), typeof(Foo18), "3", null); _storage[19] = _container.RegisterType(typeof(IFoo19), typeof(Foo19), "3", null); _storage[00] = _container.RegisterType(typeof(IFoo00), typeof(Foo00), "4", null); _storage[01] = _container.RegisterType(typeof(IFoo01), typeof(Foo01), "4", null); _storage[02] = _container.RegisterType(typeof(IFoo02), typeof(Foo02), "4", null); _storage[03] = _container.RegisterType(typeof(IFoo03), typeof(Foo03), "4", null); _storage[04] = _container.RegisterType(typeof(IFoo04), typeof(Foo04), "4", null); _storage[05] = _container.RegisterType(typeof(IFoo05), typeof(Foo05), "4", null); _storage[06] = _container.RegisterType(typeof(IFoo06), typeof(Foo06), "4", null); _storage[07] = _container.RegisterType(typeof(IFoo07), typeof(Foo07), "4", null); _storage[08] = _container.RegisterType(typeof(IFoo08), typeof(Foo08), "4", null); _storage[09] = _container.RegisterType(typeof(IFoo09), typeof(Foo09), "4", null); _storage[10] = _container.RegisterType(typeof(IFoo10), typeof(Foo10), "4", null); _storage[11] = _container.RegisterType(typeof(IFoo11), typeof(Foo11), "4", null); _storage[12] = _container.RegisterType(typeof(IFoo12), typeof(Foo12), "4", null); _storage[13] = _container.RegisterType(typeof(IFoo13), typeof(Foo13), "4", null); _storage[14] = _container.RegisterType(typeof(IFoo14), typeof(Foo14), "4", null); _storage[15] = _container.RegisterType(typeof(IFoo15), typeof(Foo15), "4", null); _storage[16] = _container.RegisterType(typeof(IFoo16), typeof(Foo16), "4", null); _storage[17] = _container.RegisterType(typeof(IFoo17), typeof(Foo17), "4", null); _storage[18] = _container.RegisterType(typeof(IFoo18), typeof(Foo18), "4", null); _storage[19] = _container.RegisterType(typeof(IFoo19), typeof(Foo19), "4", null); return _storage; } public virtual object RegisterInstance() { _storage[00] = _container.RegisterInstance(null, null, instance00, null); _storage[01] = _container.RegisterInstance(null, null, instance01, null); _storage[02] = _container.RegisterInstance(null, null, instance02, null); _storage[03] = _container.RegisterInstance(null, null, instance03, null); _storage[04] = _container.RegisterInstance(null, null, instance04, null); _storage[05] = _container.RegisterInstance(null, null, instance05, null); _storage[06] = _container.RegisterInstance(null, null, instance06, null); _storage[07] = _container.RegisterInstance(null, null, instance07, null); _storage[08] = _container.RegisterInstance(null, null, instance08, null); _storage[09] = _container.RegisterInstance(null, null, instance09, null); _storage[10] = _container.RegisterInstance(null, null, instance10, null); _storage[11] = _container.RegisterInstance(null, null, instance11, null); _storage[12] = _container.RegisterInstance(null, null, instance12, null); _storage[13] = _container.RegisterInstance(null, null, instance13, null); _storage[14] = _container.RegisterInstance(null, null, instance14, null); _storage[15] = _container.RegisterInstance(null, null, instance15, null); _storage[16] = _container.RegisterInstance(null, null, instance16, null); _storage[17] = _container.RegisterInstance(null, null, instance17, null); _storage[18] = _container.RegisterInstance(null, null, instance18, null); _storage[19] = _container.RegisterInstance(null, null, instance19, null); _storage[00] = _container.RegisterInstance(null, "1", instance00, null); _storage[01] = _container.RegisterInstance(null, "1", instance01, null); _storage[02] = _container.RegisterInstance(null, "1", instance02, null); _storage[03] = _container.RegisterInstance(null, "1", instance03, null); _storage[04] = _container.RegisterInstance(null, "1", instance04, null); _storage[05] = _container.RegisterInstance(null, "1", instance05, null); _storage[06] = _container.RegisterInstance(null, "1", instance06, null); _storage[07] = _container.RegisterInstance(null, "1", instance07, null); _storage[08] = _container.RegisterInstance(null, "1", instance08, null); _storage[09] = _container.RegisterInstance(null, "1", instance09, null); _storage[10] = _container.RegisterInstance(null, "1", instance10, null); _storage[11] = _container.RegisterInstance(null, "1", instance11, null); _storage[12] = _container.RegisterInstance(null, "1", instance12, null); _storage[13] = _container.RegisterInstance(null, "1", instance13, null); _storage[14] = _container.RegisterInstance(null, "1", instance14, null); _storage[15] = _container.RegisterInstance(null, "1", instance15, null); _storage[16] = _container.RegisterInstance(null, "1", instance16, null); _storage[17] = _container.RegisterInstance(null, "1", instance17, null); _storage[18] = _container.RegisterInstance(null, "1", instance18, null); _storage[19] = _container.RegisterInstance(null, "1", instance19, null); _storage[00] = _container.RegisterInstance(null, "2", instance00, null); _storage[01] = _container.RegisterInstance(null, "2", instance01, null); _storage[02] = _container.RegisterInstance(null, "2", instance02, null); _storage[03] = _container.RegisterInstance(null, "2", instance03, null); _storage[04] = _container.RegisterInstance(null, "2", instance04, null); _storage[05] = _container.RegisterInstance(null, "2", instance05, null); _storage[06] = _container.RegisterInstance(null, "2", instance06, null); _storage[07] = _container.RegisterInstance(null, "2", instance07, null); _storage[08] = _container.RegisterInstance(null, "2", instance08, null); _storage[09] = _container.RegisterInstance(null, "2", instance09, null); _storage[10] = _container.RegisterInstance(null, "2", instance10, null); _storage[11] = _container.RegisterInstance(null, "2", instance11, null); _storage[12] = _container.RegisterInstance(null, "2", instance12, null); _storage[13] = _container.RegisterInstance(null, "2", instance13, null); _storage[14] = _container.RegisterInstance(null, "2", instance14, null); _storage[15] = _container.RegisterInstance(null, "2", instance15, null); _storage[16] = _container.RegisterInstance(null, "2", instance16, null); _storage[17] = _container.RegisterInstance(null, "2", instance17, null); _storage[18] = _container.RegisterInstance(null, "2", instance18, null); _storage[19] = _container.RegisterInstance(null, "2", instance19, null); _storage[00] = _container.RegisterInstance(null, "3", instance00, null); _storage[01] = _container.RegisterInstance(null, "3", instance01, null); _storage[02] = _container.RegisterInstance(null, "3", instance02, null); _storage[03] = _container.RegisterInstance(null, "3", instance03, null); _storage[04] = _container.RegisterInstance(null, "3", instance04, null); _storage[05] = _container.RegisterInstance(null, "3", instance05, null); _storage[06] = _container.RegisterInstance(null, "3", instance06, null); _storage[07] = _container.RegisterInstance(null, "3", instance07, null); _storage[08] = _container.RegisterInstance(null, "3", instance08, null); _storage[09] = _container.RegisterInstance(null, "3", instance09, null); _storage[10] = _container.RegisterInstance(null, "3", instance10, null); _storage[11] = _container.RegisterInstance(null, "3", instance11, null); _storage[12] = _container.RegisterInstance(null, "3", instance12, null); _storage[13] = _container.RegisterInstance(null, "3", instance13, null); _storage[14] = _container.RegisterInstance(null, "3", instance14, null); _storage[15] = _container.RegisterInstance(null, "3", instance15, null); _storage[16] = _container.RegisterInstance(null, "3", instance16, null); _storage[17] = _container.RegisterInstance(null, "3", instance17, null); _storage[18] = _container.RegisterInstance(null, "3", instance18, null); _storage[19] = _container.RegisterInstance(null, "3", instance19, null); _storage[00] = _container.RegisterInstance(null, "4", instance00, null); _storage[01] = _container.RegisterInstance(null, "4", instance01, null); _storage[02] = _container.RegisterInstance(null, "4", instance02, null); _storage[03] = _container.RegisterInstance(null, "4", instance03, null); _storage[04] = _container.RegisterInstance(null, "4", instance04, null); _storage[05] = _container.RegisterInstance(null, "4", instance05, null); _storage[06] = _container.RegisterInstance(null, "4", instance06, null); _storage[07] = _container.RegisterInstance(null, "4", instance07, null); _storage[08] = _container.RegisterInstance(null, "4", instance08, null); _storage[09] = _container.RegisterInstance(null, "4", instance09, null); _storage[10] = _container.RegisterInstance(null, "4", instance10, null); _storage[11] = _container.RegisterInstance(null, "4", instance11, null); _storage[12] = _container.RegisterInstance(null, "4", instance12, null); _storage[13] = _container.RegisterInstance(null, "4", instance13, null); _storage[14] = _container.RegisterInstance(null, "4", instance14, null); _storage[15] = _container.RegisterInstance(null, "4", instance15, null); _storage[16] = _container.RegisterInstance(null, "4", instance16, null); _storage[17] = _container.RegisterInstance(null, "4", instance17, null); _storage[18] = _container.RegisterInstance(null, "4", instance18, null); _storage[19] = _container.RegisterInstance(null, "4", instance19, null); return _storage; } public virtual object Registrations() { _storage[00] = _container.Registrations.ToArray(); _storage[01] = _container.Registrations.ToArray(); _storage[02] = _container.Registrations.ToArray(); _storage[03] = _container.Registrations.ToArray(); _storage[04] = _container.Registrations.ToArray(); _storage[05] = _container.Registrations.ToArray(); _storage[06] = _container.Registrations.ToArray(); _storage[07] = _container.Registrations.ToArray(); _storage[08] = _container.Registrations.ToArray(); _storage[09] = _container.Registrations.ToArray(); _storage[10] = _container.Registrations.ToArray(); _storage[11] = _container.Registrations.ToArray(); _storage[12] = _container.Registrations.ToArray(); _storage[13] = _container.Registrations.ToArray(); _storage[14] = _container.Registrations.ToArray(); _storage[15] = _container.Registrations.ToArray(); _storage[16] = _container.Registrations.ToArray(); _storage[17] = _container.Registrations.ToArray(); _storage[18] = _container.Registrations.ToArray(); _storage[19] = _container.Registrations.ToArray(); _storage[00] = _container.Registrations.ToArray(); _storage[01] = _container.Registrations.ToArray(); _storage[02] = _container.Registrations.ToArray(); _storage[03] = _container.Registrations.ToArray(); _storage[04] = _container.Registrations.ToArray(); _storage[05] = _container.Registrations.ToArray(); _storage[06] = _container.Registrations.ToArray(); _storage[07] = _container.Registrations.ToArray(); _storage[08] = _container.Registrations.ToArray(); _storage[09] = _container.Registrations.ToArray(); _storage[10] = _container.Registrations.ToArray(); _storage[11] = _container.Registrations.ToArray(); _storage[12] = _container.Registrations.ToArray(); _storage[13] = _container.Registrations.ToArray(); _storage[14] = _container.Registrations.ToArray(); _storage[15] = _container.Registrations.ToArray(); _storage[16] = _container.Registrations.ToArray(); _storage[17] = _container.Registrations.ToArray(); _storage[18] = _container.Registrations.ToArray(); _storage[19] = _container.Registrations.ToArray(); _storage[00] = _container.Registrations.ToArray(); _storage[01] = _container.Registrations.ToArray(); _storage[02] = _container.Registrations.ToArray(); _storage[03] = _container.Registrations.ToArray(); _storage[04] = _container.Registrations.ToArray(); _storage[05] = _container.Registrations.ToArray(); _storage[06] = _container.Registrations.ToArray(); _storage[07] = _container.Registrations.ToArray(); _storage[08] = _container.Registrations.ToArray(); _storage[09] = _container.Registrations.ToArray(); _storage[10] = _container.Registrations.ToArray(); _storage[11] = _container.Registrations.ToArray(); _storage[12] = _container.Registrations.ToArray(); _storage[13] = _container.Registrations.ToArray(); _storage[14] = _container.Registrations.ToArray(); _storage[15] = _container.Registrations.ToArray(); _storage[16] = _container.Registrations.ToArray(); _storage[17] = _container.Registrations.ToArray(); _storage[18] = _container.Registrations.ToArray(); _storage[19] = _container.Registrations.ToArray(); _storage[00] = _container.Registrations.ToArray(); _storage[01] = _container.Registrations.ToArray(); _storage[02] = _container.Registrations.ToArray(); _storage[03] = _container.Registrations.ToArray(); _storage[04] = _container.Registrations.ToArray(); _storage[05] = _container.Registrations.ToArray(); _storage[06] = _container.Registrations.ToArray(); _storage[07] = _container.Registrations.ToArray(); _storage[08] = _container.Registrations.ToArray(); _storage[09] = _container.Registrations.ToArray(); _storage[10] = _container.Registrations.ToArray(); _storage[11] = _container.Registrations.ToArray(); _storage[12] = _container.Registrations.ToArray(); _storage[13] = _container.Registrations.ToArray(); _storage[14] = _container.Registrations.ToArray(); _storage[15] = _container.Registrations.ToArray(); _storage[16] = _container.Registrations.ToArray(); _storage[17] = _container.Registrations.ToArray(); _storage[18] = _container.Registrations.ToArray(); _storage[19] = _container.Registrations.ToArray(); _storage[00] = _container.Registrations.ToArray(); _storage[01] = _container.Registrations.ToArray(); _storage[02] = _container.Registrations.ToArray(); _storage[03] = _container.Registrations.ToArray(); _storage[04] = _container.Registrations.ToArray(); _storage[05] = _container.Registrations.ToArray(); _storage[06] = _container.Registrations.ToArray(); _storage[07] = _container.Registrations.ToArray(); _storage[08] = _container.Registrations.ToArray(); _storage[09] = _container.Registrations.ToArray(); _storage[10] = _container.Registrations.ToArray(); _storage[11] = _container.Registrations.ToArray(); _storage[12] = _container.Registrations.ToArray(); _storage[13] = _container.Registrations.ToArray(); _storage[14] = _container.Registrations.ToArray(); _storage[15] = _container.Registrations.ToArray(); _storage[16] = _container.Registrations.ToArray(); _storage[17] = _container.Registrations.ToArray(); _storage[18] = _container.Registrations.ToArray(); _storage[19] = _container.Registrations.ToArray(); return _storage; } public virtual object IsRegistered() { _storage[00] = _container.IsRegistered(typeof(IUnityContainer)); _storage[01] = _container.IsRegistered(typeof(IUnityContainer)); _storage[02] = _container.IsRegistered(typeof(IUnityContainer)); _storage[03] = _container.IsRegistered(typeof(IUnityContainer)); _storage[04] = _container.IsRegistered(typeof(IUnityContainer)); _storage[05] = _container.IsRegistered(typeof(IUnityContainer)); _storage[06] = _container.IsRegistered(typeof(IUnityContainer)); _storage[07] = _container.IsRegistered(typeof(IUnityContainer)); _storage[08] = _container.IsRegistered(typeof(IUnityContainer)); _storage[09] = _container.IsRegistered(typeof(IUnityContainer)); _storage[10] = _container.IsRegistered(typeof(IUnityContainer)); _storage[11] = _container.IsRegistered(typeof(IUnityContainer)); _storage[12] = _container.IsRegistered(typeof(IUnityContainer)); _storage[13] = _container.IsRegistered(typeof(IUnityContainer)); _storage[14] = _container.IsRegistered(typeof(IUnityContainer)); _storage[15] = _container.IsRegistered(typeof(IUnityContainer)); _storage[16] = _container.IsRegistered(typeof(IUnityContainer)); _storage[17] = _container.IsRegistered(typeof(IUnityContainer)); _storage[18] = _container.IsRegistered(typeof(IUnityContainer)); _storage[19] = _container.IsRegistered(typeof(IUnityContainer)); _storage[00] = _container.IsRegistered(typeof(PocoWithDependency00)); _storage[01] = _container.IsRegistered(typeof(PocoWithDependency01)); _storage[02] = _container.IsRegistered(typeof(PocoWithDependency02)); _storage[03] = _container.IsRegistered(typeof(PocoWithDependency03)); _storage[04] = _container.IsRegistered(typeof(PocoWithDependency04)); _storage[05] = _container.IsRegistered(typeof(PocoWithDependency05)); _storage[06] = _container.IsRegistered(typeof(PocoWithDependency06)); _storage[07] = _container.IsRegistered(typeof(PocoWithDependency07)); _storage[08] = _container.IsRegistered(typeof(PocoWithDependency08)); _storage[09] = _container.IsRegistered(typeof(PocoWithDependency09)); _storage[10] = _container.IsRegistered(typeof(PocoWithDependency10)); _storage[11] = _container.IsRegistered(typeof(PocoWithDependency11)); _storage[12] = _container.IsRegistered(typeof(PocoWithDependency12)); _storage[13] = _container.IsRegistered(typeof(PocoWithDependency13)); _storage[14] = _container.IsRegistered(typeof(PocoWithDependency14)); _storage[15] = _container.IsRegistered(typeof(PocoWithDependency15)); _storage[16] = _container.IsRegistered(typeof(PocoWithDependency16)); _storage[17] = _container.IsRegistered(typeof(PocoWithDependency17)); _storage[18] = _container.IsRegistered(typeof(PocoWithDependency18)); _storage[19] = _container.IsRegistered(typeof(PocoWithDependency19)); _storage[00] = _container.IsRegistered(typeof(IUnityContainer)); _storage[01] = _container.IsRegistered(typeof(IUnityContainer)); _storage[02] = _container.IsRegistered(typeof(IUnityContainer)); _storage[03] = _container.IsRegistered(typeof(IUnityContainer)); _storage[04] = _container.IsRegistered(typeof(IUnityContainer)); _storage[05] = _container.IsRegistered(typeof(IUnityContainer)); _storage[06] = _container.IsRegistered(typeof(IUnityContainer)); _storage[07] = _container.IsRegistered(typeof(IUnityContainer)); _storage[08] = _container.IsRegistered(typeof(IUnityContainer)); _storage[09] = _container.IsRegistered(typeof(IUnityContainer)); _storage[10] = _container.IsRegistered(typeof(IUnityContainer)); _storage[11] = _container.IsRegistered(typeof(IUnityContainer)); _storage[12] = _container.IsRegistered(typeof(IUnityContainer)); _storage[13] = _container.IsRegistered(typeof(IUnityContainer)); _storage[14] = _container.IsRegistered(typeof(IUnityContainer)); _storage[15] = _container.IsRegistered(typeof(IUnityContainer)); _storage[16] = _container.IsRegistered(typeof(IUnityContainer)); _storage[17] = _container.IsRegistered(typeof(IUnityContainer)); _storage[18] = _container.IsRegistered(typeof(IUnityContainer)); _storage[19] = _container.IsRegistered(typeof(IUnityContainer)); _storage[00] = _container.IsRegistered(typeof(PocoWithDependency00)); _storage[01] = _container.IsRegistered(typeof(PocoWithDependency01)); _storage[02] = _container.IsRegistered(typeof(PocoWithDependency02)); _storage[03] = _container.IsRegistered(typeof(PocoWithDependency03)); _storage[04] = _container.IsRegistered(typeof(PocoWithDependency04)); _storage[05] = _container.IsRegistered(typeof(PocoWithDependency05)); _storage[06] = _container.IsRegistered(typeof(PocoWithDependency06)); _storage[07] = _container.IsRegistered(typeof(PocoWithDependency07)); _storage[08] = _container.IsRegistered(typeof(PocoWithDependency08)); _storage[09] = _container.IsRegistered(typeof(PocoWithDependency09)); _storage[10] = _container.IsRegistered(typeof(PocoWithDependency10)); _storage[11] = _container.IsRegistered(typeof(PocoWithDependency11)); _storage[12] = _container.IsRegistered(typeof(PocoWithDependency12)); _storage[13] = _container.IsRegistered(typeof(PocoWithDependency13)); _storage[14] = _container.IsRegistered(typeof(PocoWithDependency14)); _storage[15] = _container.IsRegistered(typeof(PocoWithDependency15)); _storage[16] = _container.IsRegistered(typeof(PocoWithDependency16)); _storage[17] = _container.IsRegistered(typeof(PocoWithDependency17)); _storage[18] = _container.IsRegistered(typeof(PocoWithDependency18)); _storage[19] = _container.IsRegistered(typeof(PocoWithDependency19)); _storage[00] = _container.IsRegistered(typeof(IUnityContainer)); _storage[01] = _container.IsRegistered(typeof(IUnityContainer)); _storage[02] = _container.IsRegistered(typeof(IUnityContainer)); _storage[03] = _container.IsRegistered(typeof(IUnityContainer)); _storage[04] = _container.IsRegistered(typeof(IUnityContainer)); _storage[05] = _container.IsRegistered(typeof(IUnityContainer)); _storage[06] = _container.IsRegistered(typeof(IUnityContainer)); _storage[07] = _container.IsRegistered(typeof(IUnityContainer)); _storage[08] = _container.IsRegistered(typeof(IUnityContainer)); _storage[09] = _container.IsRegistered(typeof(IUnityContainer)); _storage[10] = _container.IsRegistered(typeof(PocoWithDependency10)); _storage[11] = _container.IsRegistered(typeof(PocoWithDependency11)); _storage[12] = _container.IsRegistered(typeof(PocoWithDependency12)); _storage[13] = _container.IsRegistered(typeof(PocoWithDependency13)); _storage[14] = _container.IsRegistered(typeof(PocoWithDependency14)); _storage[15] = _container.IsRegistered(typeof(PocoWithDependency15)); _storage[16] = _container.IsRegistered(typeof(PocoWithDependency16)); _storage[17] = _container.IsRegistered(typeof(PocoWithDependency17)); _storage[18] = _container.IsRegistered(typeof(PocoWithDependency18)); _storage[19] = _container.IsRegistered(typeof(PocoWithDependency19)); return _storage; } public virtual object IsRegisteredFalse() { _storage[00] = _container.IsRegistered(typeof(PocoWithDependency00), "00"); _storage[01] = _container.IsRegistered(typeof(PocoWithDependency01), "01"); _storage[02] = _container.IsRegistered(typeof(PocoWithDependency02), "02"); _storage[03] = _container.IsRegistered(typeof(PocoWithDependency03), "03"); _storage[04] = _container.IsRegistered(typeof(PocoWithDependency04), "04"); _storage[05] = _container.IsRegistered(typeof(PocoWithDependency05), "05"); _storage[06] = _container.IsRegistered(typeof(PocoWithDependency06), "06"); _storage[07] = _container.IsRegistered(typeof(PocoWithDependency07), "07"); _storage[08] = _container.IsRegistered(typeof(PocoWithDependency08), "08"); _storage[09] = _container.IsRegistered(typeof(PocoWithDependency09), "09"); _storage[10] = _container.IsRegistered(typeof(PocoWithDependency10), "10"); _storage[11] = _container.IsRegistered(typeof(PocoWithDependency11), "11"); _storage[12] = _container.IsRegistered(typeof(PocoWithDependency12), "12"); _storage[13] = _container.IsRegistered(typeof(PocoWithDependency13), "13"); _storage[14] = _container.IsRegistered(typeof(PocoWithDependency14), "14"); _storage[15] = _container.IsRegistered(typeof(PocoWithDependency15), "15"); _storage[16] = _container.IsRegistered(typeof(PocoWithDependency16), "16"); _storage[17] = _container.IsRegistered(typeof(PocoWithDependency17), "17"); _storage[18] = _container.IsRegistered(typeof(PocoWithDependency18), "18"); _storage[19] = _container.IsRegistered(typeof(PocoWithDependency19), "19"); _storage[00] = _container.IsRegistered(typeof(IFoo), "00"); _storage[01] = _container.IsRegistered(typeof(IFoo), "01"); _storage[02] = _container.IsRegistered(typeof(IFoo), "02"); _storage[03] = _container.IsRegistered(typeof(IFoo), "03"); _storage[04] = _container.IsRegistered(typeof(IFoo), "04"); _storage[05] = _container.IsRegistered(typeof(IFoo), "05"); _storage[06] = _container.IsRegistered(typeof(IFoo), "06"); _storage[07] = _container.IsRegistered(typeof(IFoo), "07"); _storage[08] = _container.IsRegistered(typeof(IFoo), "08"); _storage[09] = _container.IsRegistered(typeof(IFoo), "09"); _storage[10] = _container.IsRegistered(typeof(IFoo), "10"); _storage[11] = _container.IsRegistered(typeof(IFoo), "11"); _storage[12] = _container.IsRegistered(typeof(IFoo), "12"); _storage[13] = _container.IsRegistered(typeof(IFoo), "13"); _storage[14] = _container.IsRegistered(typeof(IFoo), "14"); _storage[15] = _container.IsRegistered(typeof(IFoo), "15"); _storage[16] = _container.IsRegistered(typeof(IFoo), "16"); _storage[17] = _container.IsRegistered(typeof(IFoo), "17"); _storage[18] = _container.IsRegistered(typeof(IFoo), "18"); _storage[19] = _container.IsRegistered(typeof(IFoo), "19"); _storage[00] = _container.IsRegistered(typeof(PocoWithDependency00), "00"); _storage[01] = _container.IsRegistered(typeof(PocoWithDependency01), "01"); _storage[02] = _container.IsRegistered(typeof(PocoWithDependency02), "02"); _storage[03] = _container.IsRegistered(typeof(PocoWithDependency03), "03"); _storage[04] = _container.IsRegistered(typeof(PocoWithDependency04), "04"); _storage[05] = _container.IsRegistered(typeof(PocoWithDependency05), "05"); _storage[06] = _container.IsRegistered(typeof(PocoWithDependency06), "06"); _storage[07] = _container.IsRegistered(typeof(PocoWithDependency07), "07"); _storage[08] = _container.IsRegistered(typeof(PocoWithDependency08), "08"); _storage[09] = _container.IsRegistered(typeof(PocoWithDependency09), "09"); _storage[10] = _container.IsRegistered(typeof(PocoWithDependency10), "10"); _storage[11] = _container.IsRegistered(typeof(PocoWithDependency11), "11"); _storage[12] = _container.IsRegistered(typeof(PocoWithDependency12), "12"); _storage[13] = _container.IsRegistered(typeof(PocoWithDependency13), "13"); _storage[14] = _container.IsRegistered(typeof(PocoWithDependency14), "14"); _storage[15] = _container.IsRegistered(typeof(PocoWithDependency15), "15"); _storage[16] = _container.IsRegistered(typeof(PocoWithDependency16), "16"); _storage[17] = _container.IsRegistered(typeof(PocoWithDependency17), "17"); _storage[18] = _container.IsRegistered(typeof(PocoWithDependency18), "18"); _storage[19] = _container.IsRegistered(typeof(PocoWithDependency19), "19"); _storage[00] = _container.IsRegistered(typeof(IFoo), "00"); _storage[01] = _container.IsRegistered(typeof(IFoo), "01"); _storage[02] = _container.IsRegistered(typeof(IFoo), "02"); _storage[03] = _container.IsRegistered(typeof(IFoo), "03"); _storage[04] = _container.IsRegistered(typeof(IFoo), "04"); _storage[05] = _container.IsRegistered(typeof(IFoo), "05"); _storage[06] = _container.IsRegistered(typeof(IFoo), "06"); _storage[07] = _container.IsRegistered(typeof(IFoo), "07"); _storage[08] = _container.IsRegistered(typeof(IFoo), "08"); _storage[09] = _container.IsRegistered(typeof(IFoo), "09"); _storage[10] = _container.IsRegistered(typeof(IFoo), "10"); _storage[11] = _container.IsRegistered(typeof(IFoo), "11"); _storage[12] = _container.IsRegistered(typeof(IFoo), "12"); _storage[13] = _container.IsRegistered(typeof(IFoo), "13"); _storage[14] = _container.IsRegistered(typeof(IFoo), "14"); _storage[15] = _container.IsRegistered(typeof(IFoo), "15"); _storage[16] = _container.IsRegistered(typeof(IFoo), "16"); _storage[17] = _container.IsRegistered(typeof(IFoo), "17"); _storage[18] = _container.IsRegistered(typeof(IFoo), "18"); _storage[19] = _container.IsRegistered(typeof(IFoo), "19"); _storage[00] = _container.IsRegistered(typeof(PocoWithDependency00), "00"); _storage[01] = _container.IsRegistered(typeof(PocoWithDependency01), "01"); _storage[02] = _container.IsRegistered(typeof(PocoWithDependency02), "02"); _storage[03] = _container.IsRegistered(typeof(PocoWithDependency03), "03"); _storage[04] = _container.IsRegistered(typeof(PocoWithDependency04), "04"); _storage[05] = _container.IsRegistered(typeof(PocoWithDependency05), "05"); _storage[06] = _container.IsRegistered(typeof(PocoWithDependency06), "06"); _storage[07] = _container.IsRegistered(typeof(PocoWithDependency07), "07"); _storage[08] = _container.IsRegistered(typeof(PocoWithDependency08), "08"); _storage[09] = _container.IsRegistered(typeof(PocoWithDependency09), "09"); _storage[10] = _container.IsRegistered(typeof(IFoo), "10"); _storage[11] = _container.IsRegistered(typeof(IFoo), "11"); _storage[12] = _container.IsRegistered(typeof(IFoo), "12"); _storage[13] = _container.IsRegistered(typeof(IFoo), "13"); _storage[14] = _container.IsRegistered(typeof(IFoo), "14"); _storage[15] = _container.IsRegistered(typeof(IFoo), "15"); _storage[16] = _container.IsRegistered(typeof(IFoo), "16"); _storage[17] = _container.IsRegistered(typeof(IFoo), "17"); _storage[18] = _container.IsRegistered(typeof(IFoo), "18"); _storage[19] = _container.IsRegistered(typeof(IFoo), "19"); return _storage; } } } ================================================ FILE: tests/Performance/Configuration/BenchmarkConfiguration.cs ================================================ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Validators; namespace Runner.Setup { public class BenchmarkConfiguration : ManualConfig { public BenchmarkConfiguration() { Add(Job.Default .WithUnrollFactor(1) .WithInvocationCount(1)); Add(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS } } } ================================================ FILE: tests/Performance/Data/MultiType.cs ================================================ using System; using System.Linq; using BenchmarkDotNet.Attributes; using Runner.Setup; using Unity; namespace Runner.Tests { [BenchmarkCategory("Registration")] [Config(typeof(BenchmarkConfiguration))] public class MultiType { IUnityContainer _container; private static readonly string[] Names = Enumerable.Range(0, 200).Select(i => i.ToString()).ToArray(); private static readonly Type[] Types = { new {q11_1 = 1}.GetType(), new {w11_1 = 1}.GetType(), new {e11_1 = 1}.GetType(), new {r11_1 = 1}.GetType(), new {t11_1 = 1}.GetType(), new {y11_1 = 1}.GetType(), new {u11_1 = 1}.GetType(), new {i11_1 = 1}.GetType(), new {o11_1 = 1}.GetType(), new {p11_1 = 1}.GetType(), new {a11_1 = 1}.GetType(), new {s11_1 = 1}.GetType(), new {d11_1 = 1}.GetType(), new {f11_1 = 1}.GetType(), new {g11_1 = 1}.GetType(), new {h11_1 = 1}.GetType(), new {j11_1 = 1}.GetType(), new {k11_1 = 1}.GetType(), new {l11_1 = 1}.GetType(), new {z11_1 = 1}.GetType(), new {x11_1 = 1}.GetType(), new {c11_1 = 1}.GetType(), new {v11_1 = 1}.GetType(), new {b11_1 = 1}.GetType(), new {n11_1 = 1}.GetType(), new {m11_1 = 1}.GetType(), new {q21_1 = 1}.GetType(), new {w21_1 = 1}.GetType(), new {e21_1 = 1}.GetType(), new {r21_1 = 1}.GetType(), new {t21_1 = 1}.GetType(), new {y21_1 = 1}.GetType(), new {u21_1 = 1}.GetType(), new {i21_1 = 1}.GetType(), new {o21_1 = 1}.GetType(), new {p21_1 = 1}.GetType(), new {a21_1 = 1}.GetType(), new {s21_1 = 1}.GetType(), new {d21_1 = 1}.GetType(), new {f21_1 = 1}.GetType(), new {g21_1 = 1}.GetType(), new {h21_1 = 1}.GetType(), new {j21_1 = 1}.GetType(), new {k21_1 = 1}.GetType(), new {l21_1 = 1}.GetType(), new {z21_1 = 1}.GetType(), new {x21_1 = 1}.GetType(), new {c21_1 = 1}.GetType(), new {v21_1 = 1}.GetType(), new {b21_1 = 1}.GetType(), new {n21_1 = 1}.GetType(), new {m21_1 = 1}.GetType(), new {q12_1 = 1}.GetType(), new {w12_1 = 1}.GetType(), new {e12_1 = 1}.GetType(), new {r12_1 = 1}.GetType(), new {t12_1 = 1}.GetType(), new {y12_1 = 1}.GetType(), new {u12_1 = 1}.GetType(), new {i12_1 = 1}.GetType(), new {o12_1 = 1}.GetType(), new {p12_1 = 1}.GetType(), new {a12_1 = 1}.GetType(), new {s12_1 = 1}.GetType(), new {d12_1 = 1}.GetType(), new {f12_1 = 1}.GetType(), new {g12_1 = 1}.GetType(), new {h12_1 = 1}.GetType(), new {j12_1 = 1}.GetType(), new {k12_1 = 1}.GetType(), new {l12_1 = 1}.GetType(), new {z12_1 = 1}.GetType(), new {x12_1 = 1}.GetType(), new {c12_1 = 1}.GetType(), new {v12_1 = 1}.GetType(), new {b12_1 = 1}.GetType(), new {n12_1 = 1}.GetType(), new {m12_1 = 1}.GetType(), new {q22_1 = 1}.GetType(), new {w22_1 = 1}.GetType(), new {e22_1 = 1}.GetType(), new {r22_1 = 1}.GetType(), new {t22_1 = 1}.GetType(), new {y22_1 = 1}.GetType(), new {u22_1 = 1}.GetType(), new {i22_1 = 1}.GetType(), new {o22_1 = 1}.GetType(), new {p22_1 = 1}.GetType(), new {a22_1 = 1}.GetType(), new {s22_1 = 1}.GetType(), new {d22_1 = 1}.GetType(), new {f22_1 = 1}.GetType(), new {g22_1 = 1}.GetType(), new {h22_1 = 1}.GetType(), new {j22_1 = 1}.GetType(), new {k22_1 = 1}.GetType(), new {l22_1 = 1}.GetType(), new {z22_1 = 1}.GetType(), new {x22_1 = 1}.GetType(), new {c22_1 = 1}.GetType(), new {v22_1 = 1}.GetType(), new {b22_1 = 1}.GetType(), new {n22_1 = 1}.GetType(), new {m22_1 = 1}.GetType(), new {q11_2 = 1}.GetType(), new {w11_2 = 1}.GetType(), new {e11_2 = 1}.GetType(), new {r11_2 = 1}.GetType(), new {t11_2 = 1}.GetType(), new {y11_2 = 1}.GetType(), new {u11_2 = 1}.GetType(), new {i11_2 = 1}.GetType(), new {o11_2 = 1}.GetType(), new {p11_2 = 1}.GetType(), new {a11_2 = 1}.GetType(), new {s11_2 = 1}.GetType(), new {d11_2 = 1}.GetType(), new {f11_2 = 1}.GetType(), new {g11_2 = 1}.GetType(), new {h11_2 = 1}.GetType(), new {j11_2 = 1}.GetType(), new {k11_2 = 1}.GetType(), new {l11_2 = 1}.GetType(), new {z11_2 = 1}.GetType(), new {x11_2 = 1}.GetType(), new {c11_2 = 1}.GetType(), new {v11_2 = 1}.GetType(), new {b11_2 = 1}.GetType(), new {n11_2 = 1}.GetType(), new {m11_2 = 1}.GetType(), new {q21_2 = 1}.GetType(), new {w21_2 = 1}.GetType(), new {e21_2 = 1}.GetType(), new {r21_2 = 1}.GetType(), new {t21_2 = 1}.GetType(), new {y21_2 = 1}.GetType(), new {u21_2 = 1}.GetType(), new {i21_2 = 1}.GetType(), new {o21_2 = 1}.GetType(), new {p21_2 = 1}.GetType(), new {a21_2 = 1}.GetType(), new {s21_2 = 1}.GetType(), new {d21_2 = 1}.GetType(), new {f21_2 = 1}.GetType(), new {g21_2 = 1}.GetType(), new {h21_2 = 1}.GetType(), new {j21_2 = 1}.GetType(), new {k21_2 = 1}.GetType(), new {l21_2 = 1}.GetType(), new {z21_2 = 1}.GetType(), new {x21_2 = 1}.GetType(), new {c21_2 = 1}.GetType(), new {v21_2 = 1}.GetType(), new {b21_2 = 1}.GetType(), new {n21_2 = 1}.GetType(), new {m21_2 = 1}.GetType(), new {q12_2 = 1}.GetType(), new {w12_2 = 1}.GetType(), new {e12_2 = 1}.GetType(), new {r12_2 = 1}.GetType(), new {t12_2 = 1}.GetType(), new {y12_2 = 1}.GetType(), new {u12_2 = 1}.GetType(), new {i12_2 = 1}.GetType(), new {o12_2 = 1}.GetType(), new {p12_2 = 1}.GetType(), new {a12_2 = 1}.GetType(), new {s12_2 = 1}.GetType(), new {d12_2 = 1}.GetType(), new {f12_2 = 1}.GetType(), new {g12_2 = 1}.GetType(), new {h12_2 = 1}.GetType(), new {j12_2 = 1}.GetType(), new {k12_2 = 1}.GetType(), new {l12_2 = 1}.GetType(), new {z12_2 = 1}.GetType(), new {x12_2 = 1}.GetType(), new {c12_2 = 1}.GetType(), new {v12_2 = 1}.GetType(), new {b12_2 = 1}.GetType(), new {n12_2 = 1}.GetType(), new {m12_2 = 1}.GetType(), new {q22_2 = 1}.GetType(), new {w22_2 = 1}.GetType(), new {e22_2 = 1}.GetType(), new {r22_2 = 1}.GetType(), new {t22_2 = 1}.GetType(), new {y22_2 = 1}.GetType(), new {u22_2 = 1}.GetType(), new {i22_2 = 1}.GetType(), new {o22_2 = 1}.GetType(), new {p22_2 = 1}.GetType(), new {a22_2 = 1}.GetType(), new {s22_2 = 1}.GetType(), new {d22_2 = 1}.GetType(), new {f22_2 = 1}.GetType(), new {g22_2 = 1}.GetType(), new {h22_2 = 1}.GetType(), new {j22_2 = 1}.GetType(), new {k22_2 = 1}.GetType(), new {l22_2 = 1}.GetType(), new {z22_2 = 1}.GetType(), new {x22_2 = 1}.GetType(), new {c22_2 = 1}.GetType(), new {v22_2 = 1}.GetType(), new {b22_2 = 1}.GetType(), new {n22_2 = 1}.GetType(), new {m22_2 = 1}.GetType() }; [IterationSetup] public virtual void SetupContainer() { _container = new UnityContainer(); _container.RegisterType(); _container.RegisterType(); _container.RegisterType("1"); _container.RegisterType("2"); } public interface IService { } public class Service : IService { } public class Poco { } } } ================================================ FILE: tests/Performance/Data/TestData.cs ================================================ using Unity; namespace Performance.Tests { #region Plain Old CLR object public class Poco00 { } public class Poco01 { } public class Poco02 { } public class Poco03 { } public class Poco04 { } public class Poco05 { } public class Poco06 { } public class Poco07 { } public class Poco08 { } public class Poco09 { } public class Poco10 { } public class Poco11 { } public class Poco12 { } public class Poco13 { } public class Poco14 { } public class Poco15 { } public class Poco16 { } public class Poco17 { } public class Poco18 { } public class Poco19 { } #endregion #region PocoWithDependency public class PocoWithDependency { [Dependency] public object Dependency { get; set; } [InjectionMethod] public object CallMe([Dependency]object data) => data; } public class PocoWithDependency00 : PocoWithDependency { } public class PocoWithDependency01 : PocoWithDependency { } public class PocoWithDependency02 : PocoWithDependency { } public class PocoWithDependency03 : PocoWithDependency { } public class PocoWithDependency04 : PocoWithDependency { } public class PocoWithDependency05 : PocoWithDependency { } public class PocoWithDependency06 : PocoWithDependency { } public class PocoWithDependency07 : PocoWithDependency { } public class PocoWithDependency08 : PocoWithDependency { } public class PocoWithDependency09 : PocoWithDependency { } public class PocoWithDependency10 : PocoWithDependency { } public class PocoWithDependency11 : PocoWithDependency { } public class PocoWithDependency12 : PocoWithDependency { } public class PocoWithDependency13 : PocoWithDependency { } public class PocoWithDependency14 : PocoWithDependency { } public class PocoWithDependency15 : PocoWithDependency { } public class PocoWithDependency16 : PocoWithDependency { } public class PocoWithDependency17 : PocoWithDependency { } public class PocoWithDependency18 : PocoWithDependency { } public class PocoWithDependency19 : PocoWithDependency { } #endregion #region IFoo public interface IFoo { } public interface IFoo00 { } public interface IFoo01 { } public interface IFoo02 { } public interface IFoo03 { } public interface IFoo04 { } public interface IFoo05 { } public interface IFoo06 { } public interface IFoo07 { } public interface IFoo08 { } public interface IFoo09 { } public interface IFoo10 { } public interface IFoo11 { } public interface IFoo12 { } public interface IFoo13 { } public interface IFoo14 { } public interface IFoo15 { } public interface IFoo16 { } public interface IFoo17 { } public interface IFoo18 { } public interface IFoo19 { } #endregion #region Foo public class Foo : IFoo { } public class Foo00 : IFoo00 { } public class Foo01 : IFoo01 { } public class Foo02 : IFoo02 { } public class Foo03 : IFoo03 { } public class Foo04 : IFoo04 { } public class Foo05 : IFoo05 { } public class Foo06 : IFoo06 { } public class Foo07 : IFoo07 { } public class Foo08 : IFoo08 { } public class Foo09 : IFoo09 { } public class Foo10 : IFoo10 { } public class Foo11 : IFoo11 { } public class Foo12 : IFoo12 { } public class Foo13 : IFoo13 { } public class Foo14 : IFoo14 { } public class Foo15 : IFoo15 { } public class Foo16 : IFoo16 { } public class Foo17 : IFoo17 { } public class Foo18 : IFoo18 { } public class Foo19 : IFoo19 { } #endregion #region IFoo<> public interface IFoo { } public interface IFoo00 { } public interface IFoo01 { } public interface IFoo02 { } public interface IFoo03 { } public interface IFoo04 { } public interface IFoo05 { } public interface IFoo06 { } public interface IFoo07 { } public interface IFoo08 { } public interface IFoo09 { } public interface IFoo10 { } public interface IFoo11 { } public interface IFoo12 { } public interface IFoo13 { } public interface IFoo14 { } public interface IFoo15 { } public interface IFoo16 { } public interface IFoo17 { } public interface IFoo18 { } public interface IFoo19 { } #endregion #region IFoo<> public class Foo : IFoo { } public class Foo00 : IFoo00 { } public class Foo01 : IFoo01 { } public class Foo02 : IFoo02 { } public class Foo03 : IFoo03 { } public class Foo04 : IFoo04 { } public class Foo05 : IFoo05 { } public class Foo06 : IFoo06 { } public class Foo07 : IFoo07 { } public class Foo08 : IFoo08 { } public class Foo09 : IFoo09 { } public class Foo10 : IFoo10 { } public class Foo11 : IFoo11 { } public class Foo12 : IFoo12 { } public class Foo13 : IFoo13 { } public class Foo14 : IFoo14 { } public class Foo15 : IFoo15 { } public class Foo16 : IFoo16 { } public class Foo17 : IFoo17 { } public class Foo18 : IFoo18 { } public class Foo19 : IFoo19 { } #endregion } ================================================ FILE: tests/Performance/Performance.csproj ================================================  Exe net461 true ..\..\src\package.snk false ================================================ FILE: tests/Performance/Program.cs ================================================ using BenchmarkDotNet.Running; using System.Reflection; using Unity; namespace Performance { class Program { static void Main(string[] args) { //var container = new UnityContainer(); //var res = container.Resolve(typeof(IUnityContainer), null, null); //if (0 == args.Length) // BenchmarkSwitcher.FromAssembly(typeof(Program).GetTypeInfo().Assembly).RunAllJoined(); //else BenchmarkSwitcher.FromAssembly(typeof(Program).GetTypeInfo().Assembly).Run(args); } } } ================================================ FILE: tests/Performance/Tests/Registration/Registration.cs ================================================ using BenchmarkDotNet.Attributes; namespace Performance.Tests { public class Registration : RegistrationBase { [Benchmark(Description = "Register (No Mapping)", OperationsPerInvoke = 100)] public override object Register() => base.Register(); [Benchmark(Description = "Register Mapping", OperationsPerInvoke = 100)] public override object RegisterMapping() => base.RegisterMapping(); [Benchmark(Description = "Register Instance", OperationsPerInvoke = 100)] public override object RegisterInstance() => base.RegisterInstance(); [Benchmark(Description = "Registrations.ToArray(100)", OperationsPerInvoke = 100)] public override object Registrations() => base.Registrations(); [Benchmark(Description = "IsRegistered (True)", OperationsPerInvoke = 100)] public override object IsRegistered() => base.IsRegistered(); [Benchmark(Description = "IsRegistered (False)", OperationsPerInvoke = 100)] public override object IsRegisteredFalse() => base.IsRegisteredFalse(); } } ================================================ FILE: tests/Performance/Tests/Resolution/Compiled.cs ================================================ using BenchmarkDotNet.Attributes; using Unity; namespace Performance.Tests { public class Compiled : BasicBase { const string name = nameof(Compiled); [IterationSetup] public override void SetupContainer() { _container = new UnityContainer().AddExtension(new ForceCompillation()); base.SetupContainer(); } [Benchmark(Description = "(" + name + ") IUnityContainer", OperationsPerInvoke = 20)] public override object UnityContainer() => base.UnityContainer(); [Benchmark(Description = " IUnityContainerAsync", OperationsPerInvoke = 20)] public override object UnityContainerAsync() => base.UnityContainerAsync(); [Benchmark(Description = "Factory (c,t,n)=>new Foo()", OperationsPerInvoke = 20)] public override object Factory() => base.Factory(); [Benchmark(Description = "Factory (with name)", OperationsPerInvoke = 20)] public override object LegacyFactory() => base.LegacyFactory(); [Benchmark(Description = "Instance", OperationsPerInvoke = 20)] public override object Instance() => base.Instance(); [Benchmark(Description = "Unregistered type", OperationsPerInvoke = 20)] public override object Unregistered() => base.Unregistered(); [Benchmark(Description = "Registered type with dependencies", OperationsPerInvoke = 20)] public override object Transient() => base.Transient(); [Benchmark(Description = "Registered interface to type mapping", OperationsPerInvoke = 20)] public override object Mapping() => base.Mapping(); [Benchmark(Description = "Mapping to Singleton", OperationsPerInvoke = 20)] public override object MappingToSingleton() => base.MappingToSingleton(); [Benchmark(Description = "Registered generic type mapping", OperationsPerInvoke = 20)] public override object GenericInterface() => base.GenericInterface(); [Benchmark(Description = "Array", OperationsPerInvoke = 20)] public override object Array() => base.Array(); [Benchmark(Description = "Enumerable", OperationsPerInvoke = 20)] public override object Enumerable() => base.Enumerable(); } } ================================================ FILE: tests/Performance/Tests/Resolution/PreCompiled.cs ================================================ using BenchmarkDotNet.Attributes; using Unity; namespace Performance.Tests { public class PreCompiled : BasicBase { const string name = nameof(PreCompiled); [IterationSetup] public override void SetupContainer() { _container = new UnityContainer().AddExtension(new ForceCompillation()); base.SetupContainer(); for (var i = 0; i < 3; i++) { base.UnityContainer(); base.UnityContainerAsync(); base.LegacyFactory(); base.Factory(); base.Instance(); base.Unregistered(); base.Transient(); base.Mapping(); base.MappingToSingleton(); base.GenericInterface(); base.Array(); base.Enumerable(); } } [Benchmark(Description = "(" + name + ") IUnityContainer", OperationsPerInvoke = 20)] public override object UnityContainer() => base.UnityContainer(); [Benchmark(Description = " IUnityContainerAsync", OperationsPerInvoke = 20)] public override object UnityContainerAsync() => base.UnityContainerAsync(); [Benchmark(Description = "Factory (c,t,n)=>new Foo()", OperationsPerInvoke = 20)] public override object Factory() => base.Factory(); [Benchmark(Description = "Factory (with name)", OperationsPerInvoke = 20)] public override object LegacyFactory() => base.LegacyFactory(); [Benchmark(Description = "Instance", OperationsPerInvoke = 20)] public override object Instance() => base.Instance(); [Benchmark(Description = "Unregistered type", OperationsPerInvoke = 20)] public override object Unregistered() => base.Unregistered(); [Benchmark(Description = "Registered type with dependencies", OperationsPerInvoke = 20)] public override object Transient() => base.Transient(); [Benchmark(Description = "Registered interface to type mapping", OperationsPerInvoke = 20)] public override object Mapping() => base.Mapping(); [Benchmark(Description = "Mapping to Singleton", OperationsPerInvoke = 20)] public override object MappingToSingleton() => base.MappingToSingleton(); [Benchmark(Description = "Registered generic type mapping", OperationsPerInvoke = 20)] public override object GenericInterface() => base.GenericInterface(); [Benchmark(Description = "Array", OperationsPerInvoke = 20)] public override object Array() => base.Array(); [Benchmark(Description = "Enumerable", OperationsPerInvoke = 20)] public override object Enumerable() => base.Enumerable(); } } ================================================ FILE: tests/Performance/Tests/Resolution/PreResolved.cs ================================================ using BenchmarkDotNet.Attributes; using Unity; namespace Performance.Tests { public class PreResolved : BasicBase { const string name = nameof(PreResolved); [IterationSetup] public override void SetupContainer() { _container = new UnityContainer().AddExtension(new ForceActivation()); base.SetupContainer(); for (var i = 0; i < 3; i++) { base.UnityContainer(); base.LegacyFactory(); base.Factory(); base.Instance(); base.Unregistered(); base.Transient(); base.Mapping(); base.MappingToSingleton(); base.GenericInterface(); base.Array(); base.Enumerable(); } } [Benchmark(Description = "(" + name + ") IUnityContainer", OperationsPerInvoke = 20)] public override object UnityContainer() => base.UnityContainer(); [Benchmark(Description = " IUnityContainerAsync", OperationsPerInvoke = 20)] public override object UnityContainerAsync() => base.UnityContainerAsync(); [Benchmark(Description = "Factory (c,t,n)=>new Foo()", OperationsPerInvoke = 20)] public override object Factory() => base.Factory(); [Benchmark(Description = "Factory (with name)", OperationsPerInvoke = 20)] public override object LegacyFactory() => base.LegacyFactory(); [Benchmark(Description = "Instance", OperationsPerInvoke = 20)] public override object Instance() => base.Instance(); [Benchmark(Description = "Unregistered type", OperationsPerInvoke = 20)] public override object Unregistered() => base.Unregistered(); [Benchmark(Description = "Registered type with dependencies", OperationsPerInvoke = 20)] public override object Transient() => base.Transient(); [Benchmark(Description = "Registered interface to type mapping", OperationsPerInvoke = 20)] public override object Mapping() => base.Mapping(); [Benchmark(Description = "Registered generic type mapping", OperationsPerInvoke = 20)] public override object GenericInterface() => base.GenericInterface(); [Benchmark(Description = "Mapping to Singleton", OperationsPerInvoke = 20)] public override object MappingToSingleton() => base.MappingToSingleton(); [Benchmark(Description = "Array", OperationsPerInvoke = 20)] public override object Array() => base.Array(); [Benchmark(Description = "Enumerable", OperationsPerInvoke = 20)] public override object Enumerable() => base.Enumerable(); } } ================================================ FILE: tests/Performance/Tests/Resolution/Resolved.cs ================================================ using BenchmarkDotNet.Attributes; using Unity; namespace Performance.Tests { public class Resolved : BasicBase { const string name = nameof(Resolved); [IterationSetup] public override void SetupContainer() { _container = new UnityContainer().AddExtension(new ForceActivation()); base.SetupContainer(); } [Benchmark(Description = "(" + name + ") IUnityContainer", OperationsPerInvoke = 20)] public override object UnityContainer() => base.UnityContainer(); [Benchmark(Description = " IUnityContainerAsync", OperationsPerInvoke = 20)] public override object UnityContainerAsync() => base.UnityContainerAsync(); [Benchmark(Description = "Factory (c,t,n)=>new Foo()", OperationsPerInvoke = 20)] public override object Factory() => base.Factory(); [Benchmark(Description = "Factory (with name)", OperationsPerInvoke = 20)] public override object LegacyFactory() => base.LegacyFactory(); [Benchmark(Description = "Instance", OperationsPerInvoke = 20)] public override object Instance() => base.Instance(); [Benchmark(Description = "Unregistered type", OperationsPerInvoke = 20)] public override object Unregistered() => base.Unregistered(); [Benchmark(Description = "Registered type with dependencies", OperationsPerInvoke = 20)] public override object Transient() => base.Transient(); [Benchmark(Description = "Registered interface to type mapping", OperationsPerInvoke = 20)] public override object Mapping() => base.Mapping(); [Benchmark(Description = "Registered generic type mapping", OperationsPerInvoke = 20)] public override object GenericInterface() => base.GenericInterface(); [Benchmark(Description = "Mapping to Singleton", OperationsPerInvoke = 20)] public override object MappingToSingleton() => base.MappingToSingleton(); [Benchmark(Description = "Array", OperationsPerInvoke = 20)] public override object Array() => base.Array(); [Benchmark(Description = "Enumerable", OperationsPerInvoke = 20)] public override object Enumerable() => base.Enumerable(); } } ================================================ FILE: tests/Unity.Diagnostic/BuildUp.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class BuildUp : Unity.Specification.Diagnostic.BuildUp.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class BuildUp : Unity.Specification.Diagnostic.BuildUp.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Constructor.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Extension; namespace Compiled.Constructor { [TestClass] public class Annotation : Unity.Specification.Diagnostic.Constructor.Annotation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Parameters : Unity.Specification.Diagnostic.Constructor.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Types : Unity.Specification.Diagnostic.Constructor.Types.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Injection : Unity.Specification.Diagnostic.Constructor.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved.Constructor { [TestClass] public class Annotation : Unity.Specification.Diagnostic.Constructor.Annotation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Parameters : Unity.Specification.Diagnostic.Constructor.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Types : Unity.Specification.Diagnostic.Constructor.Types.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Injection : Unity.Specification.Diagnostic.Constructor.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Cyclic.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Cyclic : Unity.Specification.Diagnostic.Cyclic.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class Cyclic : Unity.Specification.Diagnostic.Cyclic.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Field.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Field : Unity.Specification.Diagnostic.Field.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class Field : Unity.Specification.Diagnostic.Field.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Hierarchical.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Hierarchical : Unity.Specification.Diagnostic.Hierarchical.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class Hierarchical : Unity.Specification.Diagnostic.Hierarchical.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Issues.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Issues { [TestClass] public class GitHub : Unity.Specification.Diagnostic.Issues.GitHub.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddNewExtension(); } } [TestClass] public class CodePlex : Unity.Specification.Issues.Codeplex.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddNewExtension(); } } } ================================================ FILE: tests/Unity.Diagnostic/Method.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Extension; namespace Compiled.Method { [TestClass] public class Parameters : Unity.Specification.Diagnostic.Method.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Validation : Unity.Specification.Diagnostic.Method.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved.Method { [TestClass] public class Parameters : Unity.Specification.Diagnostic.Method.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } [TestClass] public class Validation : Unity.Specification.Diagnostic.Method.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Overrides.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Override : Unity.Specification.Diagnostic.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class Override : Unity.Specification.Diagnostic.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Property.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Property : Unity.Specification.Diagnostic.Property.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()) .AddExtension(new Diagnostic()); } } } namespace Resolved { [TestClass] public class Property : Unity.Specification.Diagnostic.Property.Validation.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()) .AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Registration.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Registration { [TestClass] public class Types : Unity.Specification.Diagnostic.Registration.Types.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new Diagnostic()); } } [TestClass] public class Instance : Unity.Specification.Diagnostic.Registration.Instance.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new Diagnostic()); } } [TestClass] public class Factory : Unity.Specification.Diagnostic.Registration.Factory.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new Diagnostic()); } } } ================================================ FILE: tests/Unity.Diagnostic/Unity.Specification.Tests.Diagnostic.csproj ================================================  net48 false true ..\..\src\package.snk false ================================================ FILE: tests/Unity.Specification/BuildUp.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class BuildUp : Unity.Specification.BuildUp.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved { [TestClass] public class BuildUp : Unity.Specification.BuildUp.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Constructor.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled.Constructor { [TestClass] public class Injection : Unity.Specification.Constructor.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Attribute : Unity.Specification.Constructor.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Parameters : Unity.Specification.Constructor.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Overrides : Unity.Specification.Constructor.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved.Constructor { [TestClass] public class Injection : Unity.Specification.Constructor.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Attribute : Unity.Specification.Constructor.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Parameters : Unity.Specification.Constructor.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Overrides : Unity.Specification.Constructor.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Container/Hierachy.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Container.Hierarchy; namespace Container { [TestClass] public class Hierarchy : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Container/IsRegistered.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Container.IsRegistered; namespace Container { [TestClass] public class IsRegistered : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Container/Registrations.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Container.Registrations; namespace Container { [TestClass] public class Registrations : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Factory/Registration.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Factory.Registration; namespace Factory { [TestClass] public class Registration : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Factory/Resolution.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Factory.Resolution; namespace Factory { [TestClass] public class Resolution : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Field.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled.Field { [TestClass] public class Attribute : Unity.Specification.Field.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Injection : Unity.Specification.Field.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Overrides : Unity.Specification.Field.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved.Field { [TestClass] public class Attribute : Unity.Specification.Field.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Injection : Unity.Specification.Field.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Overrides : Unity.Specification.Field.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Issues.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Issues { [TestClass] public class GitHub : Unity.Specification.Issues.GitHub.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class CodePlex : Unity.Specification.Issues.Codeplex.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Lifetime.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled { [TestClass] public class Lifetime : Unity.Specification.Lifetime.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved { [TestClass] public class Lifetime : Unity.Specification.Lifetime.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Method.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled.Method { [TestClass] public class Attribute : Unity.Specification.Method.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Injection : Unity.Specification.Method.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Selection : Unity.Specification.Method.Selection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Parameters : Unity.Specification.Method.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Overrides : Unity.Specification.Method.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved.Method { [TestClass] public class Attribute : Unity.Specification.Method.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Injection : Unity.Specification.Method.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Selection : Unity.Specification.Method.Selection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Parameters : Unity.Specification.Method.Parameters.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Overrides : Unity.Specification.Method.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Parameter.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled.Parameter { [TestClass] public class Attribute : Unity.Specification.Parameter.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Injected : Unity.Specification.Parameter.Injected.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Resolved : Unity.Specification.Parameter.Resolved.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Optional : Unity.Specification.Parameter.Optional.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Overrides : Unity.Specification.Parameter.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved.Parameter { [TestClass] public class Attribute : Unity.Specification.Parameter.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Injected : Unity.Specification.Parameter.Injected.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Resolved : Unity.Specification.Parameter.Resolved.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Optional : Unity.Specification.Parameter.Optional.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Overrides : Unity.Specification.Parameter.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Property.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Compiled.Property { [TestClass] public class Attribute : Unity.Specification.Property.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Injection : Unity.Specification.Property.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } [TestClass] public class Override : Unity.Specification.Property.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceCompillation()); } } } namespace Resolved.Property { [TestClass] public class Attribute : Unity.Specification.Property.Attribute.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Injection : Unity.Specification.Property.Injection.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } [TestClass] public class Override : Unity.Specification.Property.Overrides.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer().AddExtension(new ForceActivation()); } } } ================================================ FILE: tests/Unity.Specification/Registration.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Registration { [TestClass] public class Native : Unity.Specification.Registration.Native.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class Extended : Unity.Specification.Registration.Extended.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class Syntax : Unity.Specification.Registration.Syntax.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class Factory : Unity.Specification.Registration.Factory.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class Instance : Unity.Specification.Registration.Instance.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } [TestClass] public class Types : Unity.Specification.Registration.Types.SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Array.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Array; namespace Resolution { [TestClass] public class Array : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Basics.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Basics; namespace Resolution { [TestClass] public class Basics : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Deferred.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Deferred; namespace Resolution { [TestClass] public class Deferred : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Enumerable.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Enumerable; namespace Resolution { [TestClass] public class Enumerable : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Generic.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Generic; namespace Resolution { [TestClass] public class Generic : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Lazy.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Lazy; namespace Resolution { [TestClass] public class Lazy : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Mapping.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Mapping; namespace Resolution { [TestClass] public class Mapping : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Resolution/Overrides.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; using Unity.Specification.Resolution.Overrides; namespace Resolution { [TestClass] public class Overrides : SpecificationTests { public override IUnityContainer GetContainer() { return new UnityContainer(); } } } ================================================ FILE: tests/Unity.Specification/Unity.Specification.Tests.csproj ================================================  net48 false true ..\..\src\package.snk false ================================================ FILE: tests/Unity.Tests/ChildContainer/ChildContainerInterfaceChangeFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using Unity.Lifetime; namespace Unity.Tests.v5.ChildContainer { /// /// Summary description for TestChildContainerInterfaceChanges /// [TestClass] public class ChildContainerInterfaceChangeFixture { /// /// create parent and child container and then get the parent from child using the property parent. /// [TestMethod] public void CheckParentContOfChild() { IUnityContainer uc = new UnityContainer(); IUnityContainer ucchild = uc.CreateChildContainer(); object obj = ucchild.Parent; Assert.AreSame(uc, obj); } /// /// Check what do we get when we ask for parent's parent container /// [TestMethod] public void CheckParentContOfParent() { IUnityContainer uc = new UnityContainer(); IUnityContainer ucchild = uc.CreateChildContainer(); object obj = uc.Parent; Assert.IsNull(obj); } /// /// Check whether child inherits the configuration of the parent container or not using registertype method /// [TestMethod] public void ChildInheritsParentsConfiguration_RegisterTypeResolve() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(new ContainerControlledLifetimeManager()); IUnityContainer child = parent.CreateChildContainer(); ITestContainer objtest = child.Resolve(); Assert.IsNotNull(objtest); Assert.IsInstanceOfType(objtest, typeof(TestContainer)); } /// /// Check whether child inherits the configuration of the parent container or /// not, using registerinstance method /// [TestMethod] public void ChildInheritsParentsConfiguration_RegisterInstanceResolve() { IUnityContainer parent = new UnityContainer(); ITestContainer obj = new TestContainer(); parent.RegisterInstance("InParent", obj); IUnityContainer child = parent.CreateChildContainer(); ITestContainer objtest = child.Resolve("InParent"); Assert.IsNotNull(objtest); Assert.AreSame(objtest, obj); } /// /// Check whether child inherits the configuration of the parent container or /// not,using registertype method and then resolveall /// [TestMethod] public void ChildInheritsParentsConfiguration_RegisterTypeResolveAll() { IUnityContainer parent = new UnityContainer(); parent.RegisterType() .RegisterType("first") .RegisterType("second"); IUnityContainer child = parent.CreateChildContainer() .RegisterType("third"); List list = new List(child.ResolveAll()); Assert.AreEqual(3, list.Count); } /// /// Check whether child inherits the configuration of the parent container or /// not, Using registerinstance method and then resolveall /// [TestMethod] public void ChildInheritsParentsConfiguration_RegisterInstanceResolveAll() { ITestContainer objdefault = new TestContainer(); ITestContainer objfirst = new TestContainer1(); ITestContainer objsecond = new TestContainer2(); ITestContainer objthird = new TestContainer3(); IUnityContainer parent = new UnityContainer(); parent.RegisterInstance(objdefault) .RegisterInstance("first", objfirst) .RegisterInstance("second", objsecond); IUnityContainer child = parent.CreateChildContainer() .RegisterInstance("third", objthird); List list = new List(child.ResolveAll()); Assert.AreEqual(3, list.Count); } /// /// Register same type in parent and child and see the behavior /// [TestMethod] public void RegisterSameTypeInChildAndParentOverriden() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(); IUnityContainer child = parent.CreateChildContainer() .RegisterType(); ITestContainer parentregister = parent.Resolve(); ITestContainer childregister = child.Resolve(); Assert.IsInstanceOfType(parentregister, typeof(TestContainer)); Assert.IsInstanceOfType(childregister, typeof(TestContainer1)); } /// /// Register type in parent and resolve using child. /// Change in parent and changes reflected in child. /// [TestMethod] public void ChangeInParentConfigurationIsReflectedInChild() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(); IUnityContainer child = parent.CreateChildContainer(); ITestContainer first = child.Resolve(); parent.RegisterType(); ITestContainer second = child.Resolve(); Assert.IsInstanceOfType(first, typeof(TestContainer)); Assert.IsInstanceOfType(second, typeof(TestContainer1)); } /// /// dispose parent container, child should get disposed. /// [TestMethod] public void WhenDisposingParentChildDisposes() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); TestContainer3 obj = new TestContainer3(); child.RegisterInstance(obj); parent.Dispose(); Assert.IsTrue(obj.WasDisposed); } /// /// dispose child, check if parent is disposed or not. /// [TestMethod] public void ParentNotDisposedWhenChildDisposed() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); TestContainer obj1 = new TestContainer(); TestContainer3 obj3 = new TestContainer3(); parent.RegisterInstance(obj1); child.RegisterInstance(obj3); child.Dispose(); //parent not getting disposed Assert.IsFalse(obj1.WasDisposed); //child getting disposed. Assert.IsTrue(obj3.WasDisposed); } [TestMethod] public void ChainOfContainers() { IUnityContainer parent = new UnityContainer(); var child1 = parent.CreateChildContainer(); var child2 = child1.CreateChildContainer(); var child3 = child2.CreateChildContainer(); var obj1 = new TestContainer(); parent.RegisterInstance("InParent", obj1); child1.RegisterInstance("InChild1", obj1); child2.RegisterInstance("InChild2", obj1); child3.RegisterInstance("InChild3", obj1); object objresolve = child3.Resolve("InParent"); object objresolve1 = parent.Resolve("InChild3"); Assert.AreSame(obj1, objresolve); child1.Dispose(); //parent not getting disposed Assert.IsTrue(obj1.WasDisposed); } } } ================================================ FILE: tests/Unity.Tests/ChildContainer/ITestContainer.cs ================================================ namespace Unity.Tests.v5.ChildContainer { public interface ITestContainer { } } ================================================ FILE: tests/Unity.Tests/ChildContainer/TestContainer.cs ================================================ using System; namespace Unity.Tests.v5.ChildContainer { public class TestContainer : ITestContainer, IDisposable { private bool wasDisposed = false; public bool WasDisposed { get { return wasDisposed; } set { wasDisposed = value; } } public void Dispose() { wasDisposed = true; } } } ================================================ FILE: tests/Unity.Tests/ChildContainer/TestContainer1.cs ================================================ namespace Unity.Tests.v5.ChildContainer { public class TestContainer1 : ITestContainer { } } ================================================ FILE: tests/Unity.Tests/ChildContainer/TestContainer2.cs ================================================ namespace Unity.Tests.v5.ChildContainer { public class TestContainer2 : ITestContainer { } } ================================================ FILE: tests/Unity.Tests/ChildContainer/TestContainer3.cs ================================================ using System; namespace Unity.Tests.v5.ChildContainer { public class TestContainer3 : ITestContainer, IDisposable { private bool wasDisposed = false; public bool WasDisposed { get { return wasDisposed; } set { wasDisposed = value; } } public void Dispose() { wasDisposed = true; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/CollectionSupportFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Threading; using Unity.Injection; using Unity.Lifetime; namespace Unity.Tests.v5.CollectionSupport { [TestClass] public class CollectionSupportFixture { [TestMethod] public void ResolvingEnumTypeSucceedsIfItWasNotRegistered() { IUnityContainer container = new UnityContainer(); Assert.IsNotNull(container.Resolve>()); } [TestMethod] public void ClosedGenericsWinInArray() { // Arrange var Name = "name"; var instance = new Foo(new OtherService()); IUnityContainer Container = new UnityContainer(); Container.RegisterInstance>(Name, instance) .RegisterType(typeof(IFoo<>), typeof(Foo<>), Name) .RegisterType, Foo>("closed") .RegisterType(); // Act var array = Container.Resolve[]>(); // Assert Assert.AreEqual(2, array.Length); Assert.IsNotNull(array[0]); Assert.IsNotNull(array[1]); } public interface IFoo { TEntity Value { get; } } public class Foo : IFoo { public Foo() { } public Foo(TEntity value) { Value = value; } public TEntity Value { get; } } public interface IService { } public interface IOtherService { } public class Service : IService, IDisposable { public string Id { get; } = Guid.NewGuid().ToString(); public static int Instances; public Service() { Interlocked.Increment(ref Instances); } public bool Disposed; public void Dispose() { Disposed = true; } } public class OtherService : IService, IOtherService, IDisposable { [InjectionConstructor] public OtherService() { } public OtherService(IUnityContainer container) { } public bool Disposed = false; public void Dispose() { Disposed = true; } } [TestMethod] public void ResolvingAnArrayTypeSucceedsIfItWasNotRegistered() { IUnityContainer container = new UnityContainer(); Assert.IsNotNull(container.Resolve()); } [TestMethod] public void ResolvingAnArrayWithFactory() { var name = "test"; var data = new [] { new TestClass(), new TestClass() }; var container = new UnityContainer() .RegisterFactory(c => data) .RegisterFactory(name, c => data); Assert.AreSame(data, container.Resolve()); Assert.AreSame(data, container.Resolve(name)); } [TestMethod] public void ResolvingEnumWithFactory() { var name = "test"; var data = new [] { new TestClass(), new TestClass() }; var container = new UnityContainer() .RegisterFactory>(c => data) .RegisterFactory>(name, c => data); Assert.AreSame(data, container.Resolve>()); Assert.AreSame(data, container.Resolve>(name)); } [TestMethod] public void ResolvingEnumWithMap() { var container = new UnityContainer() .RegisterType, List>(new InjectionConstructor()); var instance = container.Resolve>(); Assert.IsInstanceOfType(instance, typeof(List)); } [TestMethod] public void ResolvingAnArrayTypeSucceedsIfItWasRegistered() { IUnityContainer container = new UnityContainer(); TestClass[] array = new TestClass[0]; container.RegisterInstance(array); TestClass[] resolved = container.Resolve(); Assert.AreSame(array, resolved); } [TestMethod] public void ResolvingAllRegistratiosnForaTypeReturnsAnEmptyArrayWhenNothingIsRegisterd() { IUnityContainer container = new UnityContainer(); IEnumerable resolved = container.ResolveAll(); List resolvedList = new List(resolved); Assert.AreEqual(0, resolvedList.Count); } [TestMethod] public void ResolvingAllRegistratiosnForaTypeReturnsAnEquivalentArrayWhenItemsAreRegisterd() { IUnityContainer container = new UnityContainer(); container.RegisterType("Element1", new ContainerControlledLifetimeManager()); container.RegisterType("Element2", new ContainerControlledLifetimeManager()); container.RegisterType("Element3", new ContainerControlledLifetimeManager()); IEnumerable resolved = container.ResolveAll(); List resolvedList = new List(resolved); Assert.AreEqual(3, resolvedList.Count); } [TestMethod] public void InjectingAnArrayTypeSucceedsIfItWasNotRegistered() { IUnityContainer container = new UnityContainer(); TestClassWithArrayDependency resolved = container.Resolve(); } [TestMethod] public void InjectingAnArrayTypeSucceedsIfItWasRegistered() { IUnityContainer container = new UnityContainer(); TestClass[] array = new TestClass[0]; container.RegisterInstance(array); TestClassWithArrayDependency resolved = container.Resolve(); Assert.AreSame(array, resolved.Dependency); } [TestMethod] public void InjectingAnArrayDependencySucceedsIfNoneWereRegistered() { IUnityContainer container = new UnityContainer(); TestClassWithDependencyArrayProperty resolved = container.Resolve(); Assert.AreEqual(0, resolved.Dependency.Length); } [TestMethod] public void InjectingAnArrayDependencySucceedsIfSomeWereRegistered() { IUnityContainer container = new UnityContainer(); container.RegisterType("Element1", new ContainerControlledLifetimeManager()); container.RegisterType("Element2", new ContainerControlledLifetimeManager()); container.RegisterType("Element3", new ContainerControlledLifetimeManager()); TestClassWithDependencyArrayProperty resolved = container.Resolve(); Assert.AreEqual(3, resolved.Dependency.Length); } [TestMethod] public void ConstructingAnDependencyArrayWithNoRegisteredElementsSucceeds() { IUnityContainer container = new UnityContainer(); TestClassWithDependencyArrayConstructor resolved = container.Resolve(); Assert.AreEqual(0, resolved.Dependency.Length); } [TestMethod] public void ConstructingAnDependencyArrayWithRegisteredElementsSucceeds() { IUnityContainer container = new UnityContainer(); container.RegisterType("Element1", new ContainerControlledLifetimeManager()); container.RegisterType("Element2", new ContainerControlledLifetimeManager()); container.RegisterType("Element3", new ContainerControlledLifetimeManager()); TestClassWithDependencyArrayConstructor resolved = container.Resolve(); Assert.AreEqual(3, resolved.Dependency.Length); } [TestMethod] public void ConstructingAnDependencyArrayTypeSucceedsIfItWasNotRegistered() { IUnityContainer container = new UnityContainer(); TestClassWithDependencyTypeConstructor resolved = container.Resolve(); } [TestMethod] public void ConstructingWithMethodInjectionAnDependencyArrayWithNoRegisteredElementsSucceeds() { IUnityContainer container = new UnityContainer(); TestClassWithDependencyArrayMethod resolved = container.Resolve(); Assert.AreEqual(0, resolved.Dependency.Length); } [TestMethod] public void ConstructingWithMethodInjectionAnDependencyArrayWithRegisteredElementsSucceeds() { IUnityContainer container = new UnityContainer(); container.RegisterType("Element1", new ContainerControlledLifetimeManager()); container.RegisterType("Element2", new ContainerControlledLifetimeManager()); container.RegisterType("Element3", new ContainerControlledLifetimeManager()); TestClassWithDependencyArrayMethod resolved = container.Resolve(); Assert.AreEqual(3, resolved.Dependency.Length); } [TestMethod] public void ConstructingWithMethodInjectionAnDependencyArrayTypeSucceedsIfItWasNotRegistered() { IUnityContainer container = new UnityContainer(); TestClassWithDependencyTypeMethod resolved = container.Resolve(); } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/ConfigurationTestClass.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class ConfigurationTestClass { private TestClass[] arrayProperty; public TestClass[] ArrayProperty { get { return arrayProperty; } set { arrayProperty = value; } } private TestClass[] arrayMethod; public TestClass[] ArrayMethod { get { return arrayMethod; } set { arrayMethod = value; } } private TestClass[] arrayCtor; public TestClass[] ArrayCtor { get { return arrayCtor; } set { arrayCtor = value; } } public void InjectionMethod(TestClass[] arrayMethod) { ArrayMethod = arrayMethod; } [InjectionConstructor] public ConfigurationTestClass() { } public ConfigurationTestClass(TestClass[] arrayCtor) { ArrayCtor = arrayCtor; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/ConfigurationTestClassGeneric.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class ConfigurationTestClassGeneric { private T[] arrayProperty; public T[] ArrayProperty { get { return arrayProperty; } set { arrayProperty = value; } } private T[] arrayMethod; public T[] ArrayMethod { get { return arrayMethod; } set { arrayMethod = value; } } private T[] arrayCtor; public T[] ArrayCtor { get { return arrayCtor; } set { arrayCtor = value; } } public void InjectionMethod(T[] arrayMethod) { ArrayMethod = arrayMethod; } [InjectionConstructor] public ConfigurationTestClassGeneric() { } public ConfigurationTestClassGeneric(T[] arrayCtor) { ArrayCtor = arrayCtor; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/ITestInterface.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public interface ITestInterface { } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClass.cs ================================================ using System; namespace Unity.Tests.v5.CollectionSupport { public class TestClass : ITestInterface { public string ID { get; } = Guid.NewGuid().ToString(); } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassDerived.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassDerived : TestClass { } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithArrayDependency.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithArrayDependency { [Dependency] public TestClass[] Dependency { get; set; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyArrayConstructor.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyArrayConstructor { public TestClass[] Dependency { get; set; } public TestClassWithDependencyArrayConstructor(TestClass[] dependency) { Dependency = dependency; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyArrayMethod.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyArrayMethod { public TestClass[] Dependency { get; set; } [InjectionMethod] public void Injector(TestClass[] dependency) { Dependency = dependency; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyArrayProperty.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyArrayProperty { [Dependency] public TestClass[] Dependency { get; set; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyEnumerableConstructor.cs ================================================ using System.Collections.Generic; namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyEnumerableConstructor { public IEnumerable Dependency { get; set; } public TestClassWithDependencyEnumerableConstructor(IEnumerable dependency) { Dependency = dependency; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyTypeConstructor.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyTypeConstructor { public TestClass[] Dependency { get; set; } public TestClassWithDependencyTypeConstructor(TestClass[] dependency) { Dependency = dependency; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithDependencyTypeMethod.cs ================================================ namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithDependencyTypeMethod { public TestClass[] Dependency { get; set; } [InjectionMethod] public void Injector(TestClass[] dependency) { Dependency = dependency; } } } ================================================ FILE: tests/Unity.Tests/CollectionSupport/TestClassWithEnumerableDependency.cs ================================================ using System.Collections.Generic; namespace Unity.Tests.v5.CollectionSupport { public class TestClassWithEnumerableDependency { [Dependency] public IEnumerable Dependency { get; set; } } } ================================================ FILE: tests/Unity.Tests/Container/ContainerBuildUpFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Exceptions; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Container { [TestClass] public class ContainerBuildUpFixture { #region BuildUp method with null input or empty string [TestMethod] public void BuildNullObject1() { try { UnityContainer uc = new UnityContainer(); uc.BuildUp((object) null); } catch (Exception ex) { Assert.IsInstanceOfType(ex, typeof(ArgumentNullException)); } } [TestMethod] public void BuildNullObject2() { UnityContainer uc = new UnityContainer(); object myNullObject = null; AssertHelper.ThrowsException(() => uc.BuildUp(myNullObject, "myNullObject"), "Null object is not allowed"); } [TestMethod] public void BuildNullObject3() { UnityContainer uc = new UnityContainer(); object myNullObject = null; AssertHelper.ThrowsException(() => uc.BuildUp(null, myNullObject), "Null object is not allowed"); } [TestMethod] public void BuildNullObject4() { IUnityContainer uc = new UnityContainer(); object myNullObject = null; AssertHelper.ThrowsException(() => uc.BuildUp(null, myNullObject, "myNullObject"), "Null object is not allowed"); } [TestMethod] public void BuildNullObject5() { UnityContainer uc = new UnityContainer(); SimpleClass myObject = new SimpleClass(); uc.BuildUp(myObject, (string)null); Assert.AreNotEqual(uc.Resolve(), myObject); } [TestMethod] public void BuildNullObject6() { UnityContainer uc = new UnityContainer(); SimpleClass myObject = new SimpleClass(); uc.BuildUp(myObject, String.Empty); Assert.AreNotEqual(uc.Resolve(), myObject); } [TestMethod] public void BuildNullObject7() { UnityContainer uc = new UnityContainer(); SimpleClass myObject1 = new SimpleClass(); SimpleClass myObject2 = new SimpleClass(); uc.BuildUp(myObject1, String.Empty); uc.BuildUp(myObject2, (string)null); Assert.AreNotEqual(uc.Resolve(), myObject2); } [TestMethod] public void BuildNullObject8() { UnityContainer uc = new UnityContainer(); SimpleClass myObject1 = new SimpleClass(); SimpleClass myObject2 = new SimpleClass(); uc.BuildUp(myObject1, String.Empty); uc.BuildUp(myObject2, " "); Assert.AreNotEqual(uc.Resolve(), myObject2); } [TestMethod] public void BuildNullObject9() { IUnityContainer uc = new UnityContainer(); SimpleClass myObject1 = new SimpleClass(); SimpleClass myObject2 = new SimpleClass(); uc.BuildUp(myObject1, "a"); uc.BuildUp(myObject2, " a "); Assert.AreNotEqual(uc.Resolve(typeof(SimpleClass), "a"), myObject2); } [TestMethod] [ExpectedException(typeof(ResolutionFailedException))] public void BuildUpPrimitiveAndDotNetClassTest() { IUnityContainer uc = new UnityContainer(); int i = 0; uc.BuildUp(i, "a"); var res = uc.Resolve(typeof(int), "a"); } [TestMethod] public void BuildNullObject10() { IUnityContainer uc = new UnityContainer(); SimpleClass myObject2 = new SimpleClass(); uc.BuildUp(myObject2, " "); Assert.AreNotEqual( uc.Resolve(typeof(SimpleClass), ""), myObject2); } [TestMethod] public void BuildNullObject11() { IUnityContainer uc = new UnityContainer(); SimpleClass myObject1 = new SimpleClass(); uc.BuildUp(myObject1, " a b c "); Assert.AreNotEqual(uc.Resolve(typeof(SimpleClass), "a b c"), myObject1); } public class SimpleClass { private object myFirstObj; public static int Count = 0; [Dependency] public object MyFirstObj { get { return myFirstObj; } set { myFirstObj = value; } } } #endregion #region BuildUp Method with mismatched type and object [TestMethod] public void BuildUnmatchedObject1() { UnityContainer uc = new UnityContainer(); BuildUnmatchedObject1_TestClass obj1 = new BuildUnmatchedObject1_TestClass(); uc.BuildUp(typeof(object), obj1); Assert.IsNull(obj1.MyFirstObj); } public class BuildUnmatchedObject1_TestClass { private object myFirstObj; [Dependency] public object MyFirstObj { get { return myFirstObj; } set { myFirstObj = value; } } } #endregion #region BuildUp method with Base and Child [TestMethod] public void BuildBaseAndChildObject1() { UnityContainer uc = new UnityContainer(); ChildStub1 objChild = new ChildStub1(); Assert.IsNotNull(objChild); Assert.IsNull(objChild.BaseProp); Assert.IsNull(objChild.ChildProp); uc.BuildUp(typeof(BaseStub1), objChild); Assert.IsNotNull(objChild.BaseProp); Assert.IsNull(objChild.ChildProp); //the base does not know about child, so it will not build the child property uc.BuildUp(typeof(ChildStub1), objChild); Assert.IsNotNull(objChild.BaseProp); Assert.IsNotNull(objChild.ChildProp); //ChildProp get created uc.BuildUp(typeof(BaseStub1), objChild); Assert.IsNotNull(objChild.BaseProp); Assert.IsNotNull(objChild.ChildProp); //ChildProp is not touched, so it is still NotNull } [TestMethod] public void BuildBaseAndChildObject2() { UnityContainer uc = new UnityContainer(); ChildStub1 objChild = new ChildStub1(); Assert.IsNotNull(objChild); Assert.IsNull(objChild.BaseProp); Assert.IsNull(objChild.ChildProp); uc.BuildUp(typeof(ChildStub1), objChild); Assert.IsNotNull(objChild.BaseProp); Assert.IsNotNull(objChild.ChildProp); //ChildProp get created } public interface Interface1 { [Dependency] object InterfaceProp { get; set; } } public class BaseStub1 : Interface1 { private object baseProp; private object interfaceProp; [Dependency] public object BaseProp { get { return this.baseProp; } set { this.baseProp = value; } } public object InterfaceProp { get { return this.interfaceProp; } set { this.interfaceProp = value; } } } public class ChildStub1 : BaseStub1 { private object childProp; [Dependency] public object ChildProp { get { return this.childProp; } set { this.childProp = value; } } } #endregion #region BuildUp method with Abstract Base [TestMethod] public void BuildAbstractBaseAndChildObject2() { UnityContainer uc = new UnityContainer(); ConcreteChild objChild = new ConcreteChild(); Assert.IsNotNull(objChild); Assert.IsNull(objChild.AbsBaseProp); Assert.IsNull(objChild.ChildProp); uc.BuildUp(typeof(ConcreteChild), objChild); Assert.IsNotNull(objChild.AbsBaseProp); Assert.IsNotNull(objChild.ChildProp); //ChildProp get created } public abstract class AbstractBase { private object baseProp; [Dependency] public object AbsBaseProp { get { return baseProp; } set { baseProp = value; } } public abstract void AbstractMethod(); } public class ConcreteChild : AbstractBase { public override void AbstractMethod() { } [Dependency] public object ChildProp { get; set; } } #endregion #region BuildUp method with Contained Object [TestMethod] public void BuildContainedObject1() { UnityContainer uc = new UnityContainer(); MainClass objMain = new MainClass(); Assert.IsNotNull(objMain); Assert.IsNull(objMain.ContainedObj); uc.BuildUp(objMain); Assert.IsNotNull(objMain.ContainedObj); Assert.IsNotNull(objMain.ContainedObj.DependencyProp1); Assert.IsNull(objMain.ContainedObj.RegularProp1); } public class MainClass { private ContainnedClass containedObj; [Dependency] public ContainnedClass ContainedObj { get { return containedObj; } set { containedObj = value; } } } public class ContainnedClass { private object dependencyProp1; private object regularProp1; [Dependency] public object DependencyProp1 { get { return dependencyProp1; } set { dependencyProp1 = value; } } public object RegularProp1 { get { return regularProp1; } set { regularProp1 = value; } } } #endregion #region BuildUp Calling BuildUp method on itself private class ObjectUsingLogger { [InjectionMethod] public void BuildUpTest() { IUnityContainer container = new UnityContainer(); container.BuildUp(this); } } #endregion #region GetOrDefault method [TestMethod] public void GetObject1() { UnityContainer uc = new UnityContainer(); object obj = uc.Resolve(); Assert.IsNotNull(obj); } [TestMethod] public void GetObject2() { UnityContainer uc = new UnityContainer(); object obj = uc.Resolve(typeof(object)); Assert.IsNotNull(obj); } [TestMethod] public void GetObject3() { UnityContainer uc = new UnityContainer(); GetTestClass1 obj = uc.Resolve(); Assert.IsNotNull(obj.BaseProp); } [TestMethod] public void GetObject4() { UnityContainer uc = new UnityContainer(); GetTestClass1 obj = (GetTestClass1)uc.Resolve(typeof(GetTestClass1)); Assert.IsNotNull(obj.BaseProp); } [TestMethod] public void GetObject5() { UnityContainer uc = new UnityContainer(); GetTestClass1 obj = uc.Resolve("hello"); Assert.IsNotNull(obj.BaseProp); } [TestMethod] public void GetObject6() { UnityContainer uc = new UnityContainer(); GetTestClass1 objA = uc.Resolve("helloA"); Assert.IsNotNull(objA.BaseProp); GetTestClass1 objB = uc.Resolve("helloB"); Assert.IsNotNull(objB.BaseProp); Assert.AreNotSame(objA, objB); } public class GetTestClass1 { private object baseProp; [Dependency] public object BaseProp { get { return baseProp; } set { baseProp = value; } } } #endregion } } ================================================ FILE: tests/Unity.Tests/Container/ContainerControlledLifetimeThreadingFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Threading; using Unity.Builder; using Unity.Lifetime; using Unity.Strategies; using Unity.Tests.v5.TestDoubles; namespace Unity.Tests.v5.Container { // Test for a race condition in the ContainerControlledLifetime // class. [TestClass] public class ContainerControlledLifetimeThreadingFixture { [TestMethod] public void SameInstanceFromMultipleThreads() { IUnityContainer container = new UnityContainer(); container.AddExtension(new SpyExtension(new DelayStrategy(), UnityBuildStage.Lifetime)); container.RegisterType(new ContainerControlledLifetimeManager()); object result1 = null; object result2 = null; Thread thread1 = new Thread(delegate () { result1 = container.Resolve(); }); Thread thread2 = new Thread(delegate () { result2 = container.Resolve(); }); thread1.Name = "1"; thread2.Name = "2"; thread1.Start(); thread2.Start(); thread2.Join(); thread1.Join(); Assert.IsNotNull(result1); Assert.AreSame(result1, result2); } [TestMethod] public void ContainerControlledLifetimeDoesNotLeaveHangingLockIfBuildThrowsException() { IUnityContainer container = new UnityContainer() .AddExtension(new SpyExtension(new ThrowingStrategy(), UnityBuildStage.PostInitialization)) .RegisterType(new ContainerControlledLifetimeManager()); bool failed = true; object result1 = null; object result2 = null; bool thread2Finished = false; Thread thread1 = new Thread( delegate() { try { result1 = container.Resolve(); } catch (ResolutionFailedException) { /* ignore */ } catch (Exception) { // Make sure user exception is passed through failed = false; } }); Thread thread2 = new Thread( delegate() { result2 = container.Resolve(); thread2Finished = true; }); thread1.Start(); thread1.Join(); // Thread1 threw an exception. However, lock should be correctly freed. // Run thread2, and if it finished, we're ok. thread2.Start(); thread2.Join(1000); Assert.IsFalse(failed); Assert.IsTrue(thread2Finished); Assert.IsNull(result1); Assert.IsNotNull(result2); } // A test strategy that introduces a variable delay in // the strategy chain to work out private class DelayStrategy : BuilderStrategy { private int delayMS = 500; public override void PreBuildUp(ref BuilderContext context) { Thread.Sleep(this.delayMS); this.delayMS = this.delayMS == 0 ? 500 : 0; } } // Another test strategy that throws an exeception the // first time it is executed. private class ThrowingStrategy : BuilderStrategy { private bool shouldThrow = true; public override void PreBuildUp(ref BuilderContext context) { if (this.shouldThrow) { this.shouldThrow = false; throw new Exception("Expected test exception thrown from test strategy the first time it is executed"); } } } } } ================================================ FILE: tests/Unity.Tests/Container/ContainerDefaultContentFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.Container { [TestClass] public class ContainerDefaultContentFixture { [TestMethod] public void WhenResolvingAnIUnityContainerItResolvesItself() { IUnityContainer container = new UnityContainer(); IUnityContainer resolvedContainer = container.Resolve(); Assert.AreSame(container, resolvedContainer); } [TestMethod] public void WhenResolveingAnIUnityContainerForAChildContainerItResolvesTheChildContainer() { IUnityContainer container = new UnityContainer(); IUnityContainer childContainer = container.CreateChildContainer(); IUnityContainer resolvedContainer = childContainer.Resolve(); Assert.AreSame(childContainer, resolvedContainer); } [TestMethod] public void AClassThatHasADependencyOnTheContainerGetsItInjected() { IUnityContainer container = new UnityContainer(); IUnityContainerInjectionClass obj; obj = container.Resolve(); Assert.AreSame(container, obj.Container); } public class IUnityContainerInjectionClass { [Dependency] public IUnityContainer Container { get; set; } } } } ================================================ FILE: tests/Unity.Tests/Container/SeparateContainerFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Lifetime; namespace Unity.Tests.v5.Container { [TestClass] public class SeperateContainerFixture { [TestMethod] public void GetObject() { UnityContainer uc = new UnityContainer(); object obj = uc.Resolve(); Assert.IsNotNull(obj); } [TestMethod] public void RecursiveDependencies() { IUnityContainer uc = new UnityContainer(); object obj1 = uc.Resolve(); Assert.IsNotNull(obj1); Assert.IsInstanceOfType(obj1, typeof(MyDependency)); } [TestMethod] public void CheckPropertyInjectionWorks() { IUnityContainer uc = new UnityContainer(); MySetterInjectionClass obj1 = uc.Resolve(); Assert.IsNotNull(obj1); Assert.IsNull(obj1.MyObj); Assert.IsInstanceOfType(obj1, typeof(MySetterInjectionClass)); } [TestMethod] public void CheckPropertyDependencyInjectionWorks() { IUnityContainer uc = new UnityContainer(); MySetterDependencyClass obj1 = uc.Resolve(); Assert.IsNotNull(obj1); Assert.IsNotNull(obj1.MyObj); Assert.IsInstanceOfType(obj1, typeof(MySetterDependencyClass)); } [TestMethod] public void Check2PropertyDependencyInjectionWorks() { IUnityContainer uc = new UnityContainer(); My2PropertyDependencyClass obj1 = uc.Resolve(); Assert.IsNotNull(obj1); Assert.IsNotNull(obj1.MyFirstObj); Assert.IsNotNull(obj1.MySecondObj); Assert.IsInstanceOfType(obj1, typeof(My2PropertyDependencyClass)); } [TestMethod] public void Check2PropertyDependencyBuildUpWorks() { UnityContainer uc = new UnityContainer(); My2PropertyDependencyClass obj1 = new My2PropertyDependencyClass(); Assert.IsNotNull(obj1); Assert.IsNull(obj1.MyFirstObj); Assert.IsNull(obj1.MySecondObj); uc.BuildUp(obj1); Assert.IsNotNull(obj1.MyFirstObj); Assert.IsNotNull(obj1.MySecondObj); } [TestMethod] public void CheckMultipleDependencyNonDependencyInjectionWorks() { UnityContainer uc = new UnityContainer(); MySetterDependencyNonDependencyClass obj1 = uc.Resolve(); Assert.IsNotNull(obj1); Assert.IsNotNull(obj1.MyObj); Assert.IsNull(obj1.MyAnotherObj); Assert.IsInstanceOfType(obj1, typeof(MySetterDependencyNonDependencyClass)); } [TestMethod] public void TwoInstancesAreNotSame() { UnityContainer uc = new UnityContainer(); object obj1 = uc.Resolve(); object obj2 = uc.Resolve(); Assert.AreNotSame(obj1, obj2); } [TestMethod] public void SingletonsAreSame() { IUnityContainer uc = new UnityContainer() .RegisterType(new ContainerControlledLifetimeManager()); object obj1 = uc.Resolve(); object obj2 = uc.Resolve(); Assert.AreSame(obj1, obj2); Assert.IsInstanceOfType(obj1.GetType(), typeof(object)); } [TestMethod] public void NamedUnnamedSingletonareNotSame() { IUnityContainer uc = new UnityContainer() .RegisterType(new ContainerControlledLifetimeManager()) .RegisterType("MyObject", new ContainerControlledLifetimeManager()); object obj1 = uc.Resolve(); object obj2 = uc.Resolve("MyObject"); Assert.AreNotSame(obj1, obj2); } } public class MyDependency { private object myDepObj; public MyDependency(object obj) { this.myDepObj = obj; } } public class MyDependency1 { private object myDepObj; public MyDependency1(object obj) { this.myDepObj = obj; } [InjectionConstructor] public MyDependency1(string str) { this.myDepObj = str; } } public class MultipleConstructors { public MultipleConstructors() { System.Diagnostics.Debug.WriteLine("Default Empty constructor"); } public MultipleConstructors(object obj) { System.Diagnostics.Debug.WriteLine("object constructor"); } } public class MySetterInjectionClass { public object MyObj { get; set; } } public class MySetterDependencyClass { [Dependency] public object MyObj { get; set; } } public class MySetterDependencyNonDependencyClass { [Dependency] public object MyObj { get; set; } public object MyAnotherObj { get; set; } } public class My2PropertyDependencyClass { [Dependency] public object MyFirstObj { get; set; } [Dependency] public object MySecondObj { get; set; } } public class MyMethodDependencyClass { private string myObj; [InjectionMethod] public void Initialize(string obj) { myObj = obj; } public object MyObj { get { return myObj; } } } internal interface IMySingeltonInterface { } internal class MyFirstSingetonclass : IMySingeltonInterface { } internal class MySecondSingetonclass : IMySingeltonInterface { } internal interface IMyClass { } internal class MyBaseClass : IMyClass { } internal class MyClassDerivedBaseClass : MyBaseClass { } internal class MyDisposeClass : IDisposable { public bool IsDisposed { get; set; } public void Dispose() { IsDisposed = true; } } internal interface IMyInterface { } internal interface ITemporary { } public class Temp : ITemporary { } internal class Temporary : ITemporary { } } ================================================ FILE: tests/Unity.Tests/Container/UnityExtensionFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Builder; using Unity.Extension; using Unity.Tests.v5.TestDoubles; namespace Unity.Tests.v5.Container { [TestClass] public class UnityExtensionFixture { [TestMethod] public void ContainerCallsExtensionsInitializeMethod() { MockContainerExtension extension = new MockContainerExtension(); IUnityContainer container = new UnityContainer(); container.AddExtension(extension); Assert.IsTrue(extension.InitializeWasCalled); } [TestMethod] public void ExtensionReceivesExtensionContextInInitialize() { MockContainerExtension extension = new MockContainerExtension(); IUnityContainer container = new UnityContainer(); container.AddExtension(extension); Assert.IsNotNull(extension.Context); Assert.AreSame(container, extension.Context.Container); } [TestMethod] public void CanGetConfigurationInterfaceFromExtension() { MockContainerExtension extension = new MockContainerExtension(); IUnityContainer container = new UnityContainer() .AddExtension(extension); IMockConfiguration config = container.Configure(); Assert.AreSame(extension, config); Assert.AreSame(container, config.Container); } [TestMethod] public void CanGetConfigurationWithoutGenericMethod() { MockContainerExtension extension = new MockContainerExtension(); IUnityContainer container = new UnityContainer() .AddExtension(extension); IMockConfiguration config = (IMockConfiguration)container.Configure(typeof(IMockConfiguration)); Assert.AreSame(extension, config); Assert.AreSame(container, config.Container); } [TestMethod] public void ExtensionCanAddStrategy() { SpyStrategy spy = new SpyStrategy(); SpyExtension extension = new SpyExtension(spy, UnityBuildStage.PreCreation); IUnityContainer container = new UnityContainer() .AddExtension(extension); object result = container.Resolve(); Assert.IsTrue(spy.BuildUpWasCalled); Assert.AreSame(result, spy.Existing); } [TestMethod] public void ExtensionCanAddPolicy() { SpyStrategy spy = new SpyStrategy(); SpyPolicy spyPolicy = new SpyPolicy(); SpyExtension extension = new SpyExtension(spy, UnityBuildStage.PreCreation, spyPolicy, typeof(SpyPolicy)); IUnityContainer container = new UnityContainer() .AddExtension(extension); container.Resolve(); Assert.IsTrue(spyPolicy.WasSpiedOn); } [TestMethod] public void CanLookupExtensionByClassName() { MockContainerExtension extension = new MockContainerExtension(); IUnityContainer container = new UnityContainer(); container.AddExtension(extension); MockContainerExtension result = container.Configure(); Assert.AreSame(extension, result); } [TestMethod] public void ContainerRaisesChildContainerCreatedToExtension() { bool childContainerEventRaised = false; var mockExtension = new MockContainerExtension(); var container = new UnityContainer() .AddExtension(mockExtension); mockExtension.Context.ChildContainerCreated += (sender, ev) => { childContainerEventRaised = true; }; var child = container.CreateChildContainer(); Assert.IsTrue(childContainerEventRaised); } [TestMethod] public void ChildContainerCreatedEventGivesChildContainerToExtension() { var mockExtension = new MockContainerExtension(); ExtensionContext childContext = null; var container = new UnityContainer() .AddExtension(mockExtension); mockExtension.Context.ChildContainerCreated += (sender, ev) => { childContext = ev.ChildContext; }; var child = container.CreateChildContainer(); Assert.AreSame(child, childContext.Container); } [TestMethod] public void CanAddExtensionWithNonDefaultConstructor() { IUnityContainer container = new UnityContainer(); container.AddNewExtension(); var extension = container.Configure(typeof(ContainerExtensionWithNonDefaultConstructor)); Assert.IsNotNull(extension); } } } ================================================ FILE: tests/Unity.Tests/Container/UnityHierarchyFixture.cs ================================================ using Microsoft.Practices.Unity.Tests.TestObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Container { /// /// Tests for the hierarchical features of the UnityContainer. /// [TestClass] public class UnityHierarchyFixture { [TestMethod] public void ChildBuildsUsingParentsConfiguration() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(); var child = parent.CreateChildContainer(); var logger = child.Resolve(); Assert.IsNotNull(logger); AssertExtensions.IsInstanceOfType(logger, typeof(MockLogger)); } [TestMethod] public void NamesRegisteredInParentAppearInChild() { IUnityContainer parent = new UnityContainer(); parent.RegisterType("special"); IUnityContainer child = parent.CreateChildContainer(); ILogger l = child.Resolve("special"); AssertExtensions.IsInstanceOfType(l, typeof(SpecialLogger)); } [TestMethod] public void NamesRegisteredInParentAppearInChildGetAll() { string[] databases = { "northwind", "adventureworks", "fabrikam" }; IUnityContainer parent = new UnityContainer(); parent.RegisterInstance("nwnd", databases[0]) .RegisterInstance("advwks", databases[1]); IUnityContainer child = parent.CreateChildContainer() .RegisterInstance("fbkm", databases[2]); List dbs = new List(child.ResolveAll()); CollectionAssertExtensions.AreEquivalent(databases, dbs); } [TestMethod] public void ChildConfigurationOverridesParentConfiguration() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(); IUnityContainer child = parent.CreateChildContainer() .RegisterType(); ILogger parentLogger = parent.Resolve(); ILogger childLogger = child.Resolve(); AssertExtensions.IsInstanceOfType(parentLogger, typeof(MockLogger)); AssertExtensions.IsInstanceOfType(childLogger, typeof(SpecialLogger)); } [TestMethod] public void ChangeInParentConfigurationIsReflectedInChild() { IUnityContainer parent = new UnityContainer(); parent.RegisterType(); IUnityContainer child = parent.CreateChildContainer(); ILogger first = child.Resolve(); parent.RegisterType(); ILogger second = child.Resolve(); AssertExtensions.IsInstanceOfType(first, typeof(MockLogger)); AssertExtensions.IsInstanceOfType(second, typeof(SpecialLogger)); } [TestMethod] public void ChildExtensionDoesntAffectParent() { bool factoryWasCalled = false; IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer() .RegisterFactory(c => { factoryWasCalled = true; return new object(); }); parent.Resolve(); Assert.IsFalse(factoryWasCalled); child.Resolve(); Assert.IsTrue(factoryWasCalled); } [TestMethod] public void DisposingParentDisposesChild() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); DisposableObject spy = new DisposableObject(); child.RegisterInstance(spy); parent.Dispose(); Assert.IsTrue(spy.WasDisposed); } [TestMethod] public void CanDisposeChildWithoutDisposingParent() { DisposableObject parentSpy = new DisposableObject(); DisposableObject childSpy = new DisposableObject(); IUnityContainer parent = new UnityContainer(); parent.RegisterInstance(parentSpy); IUnityContainer child = parent.CreateChildContainer() .RegisterInstance(childSpy); child.Dispose(); Assert.IsFalse(parentSpy.WasDisposed); Assert.IsTrue(childSpy.WasDisposed); childSpy.WasDisposed = false; parent.Dispose(); Assert.IsTrue(parentSpy.WasDisposed); Assert.IsFalse(childSpy.WasDisposed); } } } ================================================ FILE: tests/Unity.Tests/ContainerRegistration/AnotherTypeImplementation.cs ================================================  namespace Unity.Tests.v5.ContainerRegistration { internal class AnotherTypeImplementation : ITypeAnotherInterface { private readonly string name; public AnotherTypeImplementation() { } public AnotherTypeImplementation(string name) { this.name = name; } #region ITypeAnotherInterface Members public string GetName() { return name; } #endregion } } ================================================ FILE: tests/Unity.Tests/ContainerRegistration/GivenContainerIntrospectionCorrectUsageFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Injection; namespace Unity.Tests.v5.ContainerRegistration { [TestClass] public class GivenContainerIntrospectionCorrectUsageFixture { private IUnityContainer container; [TestInitialize] public void Init() { container = new UnityContainer(); } [TestMethod] public void WhenIsRegisteredIsCalledForDefaultTypeFromChildContainer() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var child = container.CreateChildContainer(); child.RegisterType(new InjectionConstructor("default")); child.RegisterType("another", new InjectionConstructor("another")); var result = child.IsRegistered(typeof(ITypeAnotherInterface)); Assert.IsTrue(result); } [TestMethod] public void WhenIsRegisteredIsCalledForDefaultTypeRegisteredOnChildContainerFromParent() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var child = container.CreateChildContainer(); child.RegisterType(new InjectionConstructor("default")); child.RegisterType("another", new InjectionConstructor("another")); var result = container.IsRegistered(typeof(ITypeAnotherInterface)); Assert.IsFalse(result); } [TestMethod] public void WhenIsRegisteredIsCalledForDefaultType() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var result = container.IsRegistered(typeof(ITypeInterface)); Assert.IsTrue(result); } [TestMethod] public void WhenIsRegisteredIsCalledForSpecificName() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var result = container.IsRegistered(typeof(ITypeInterface), "foo"); Assert.IsTrue(result); } [TestMethod] public void WhenIsRegisteredGenericIsCalledForDefaultType() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var result = container.IsRegistered(); Assert.IsTrue(result); } [TestMethod] public void WhenIsRegisteredGenericIsCalledForSpecificName() { container.RegisterType(new InjectionConstructor("default")); container.RegisterType("foo", new InjectionConstructor("foo")); var result = container.IsRegistered("foo"); Assert.IsTrue(result); } } } ================================================ FILE: tests/Unity.Tests/ContainerRegistration/ITypeAnotherInterface.cs ================================================  namespace Unity.Tests.v5.ContainerRegistration { internal interface ITypeAnotherInterface { string GetName(); } } ================================================ FILE: tests/Unity.Tests/ContainerRegistration/ITypeInterface.cs ================================================ namespace Unity.Tests.v5.ContainerRegistration { internal interface ITypeInterface { string GetName(); } } ================================================ FILE: tests/Unity.Tests/ContainerRegistration/TypeImplementation.cs ================================================ namespace Unity.Tests.v5.ContainerRegistration { internal class TypeImplementation : ITypeInterface { private string name; public TypeImplementation() { } public TypeImplementation(string name) { this.name = name; } #region ITypeInterface Members public string GetName() { return name; } #endregion } } ================================================ FILE: tests/Unity.Tests/Extensions/DefaultLifetimeExtensionTests.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Lifetime; namespace Unity.Tests.v5 { [TestClass] public class DefaultLifetimeExtensionTests { [TestMethod] public void Register() { // Setup var container = new UnityContainer(); // Act container.AddNewExtension(); var config = container.Configure(); // Validate Assert.IsNotNull(config); } [TestMethod] public void Defaults() { // Setup var container = new UnityContainer(); // Act container.AddNewExtension(); var config = container.Configure(); // Validate Assert.IsNotNull(config); Assert.IsInstanceOfType(config.TypeDefaultLifetime, typeof(TransientLifetimeManager)); Assert.IsInstanceOfType(config.InstanceDefaultLifetime, typeof(ContainerControlledLifetimeManager)); Assert.IsInstanceOfType(config.FactoryDefaultLifetime, typeof(TransientLifetimeManager)); } [TestMethod] public void GetSetValidation() { // Setup var manager = new TestLifetimeManager(); var config = new UnityContainer().AddNewExtension() .Configure(); // Act config.TypeDefaultLifetime = manager; config.InstanceDefaultLifetime = manager; config.FactoryDefaultLifetime = manager; // Validate Assert.IsNotNull(config); Assert.IsInstanceOfType(config.TypeDefaultLifetime, typeof(TestLifetimeManager)); Assert.IsInstanceOfType(config.InstanceDefaultLifetime, typeof(TestLifetimeManager)); Assert.IsInstanceOfType(config.FactoryDefaultLifetime, typeof(TestLifetimeManager)); } [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void TypeNull() { // Setup var config = new UnityContainer().AddNewExtension() .Configure(); // Act config.TypeDefaultLifetime = null; // Validate Assert.Fail("Should throw above"); } [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void InstanceNull() { // Setup var config = new UnityContainer().AddNewExtension() .Configure(); // Act config.InstanceDefaultLifetime = null; // Validate Assert.Fail("Should throw above"); } [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void FactoryNull() { // Setup var config = new UnityContainer().AddNewExtension() .Configure(); // Act config.FactoryDefaultLifetime = null; // Validate Assert.Fail("Should throw above"); } } public class TestLifetimeManager : LifetimeManager, ITypeLifetimeManager, IInstanceLifetimeManager, IFactoryLifetimeManager { protected override LifetimeManager OnCreateLifetimeManager() => throw new System.NotImplementedException(); } } ================================================ FILE: tests/Unity.Tests/Extensions/DiagnosticExtensionTests.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Extension; namespace Unity.Tests.v5 { [TestClass] public class DiagnosticExtensionTests { [TestMethod] public void Register() { // Setup var container = new UnityContainer(); // Act container.AddNewExtension(); var config = container.Configure(); // Validate Assert.IsNotNull(config); } [TestMethod] public void ErrorMessage() { // Setup var container = new UnityContainer(); // Validate try { container.Resolve(); } catch (Exception ex) { var message = ex.Message; } } [TestMethod] public void DisposableExtensionsAreDisposedWithContainerButNotRemoved() { DisposableExtension extension = new DisposableExtension(); IUnityContainer container = new UnityContainer() .AddExtension(extension); container.Dispose(); Assert.IsTrue(extension.Disposed); Assert.IsFalse(extension.Removed); } [TestMethod] public void OnlyDisposableExtensionAreDisposed() { DisposableExtension extension = new DisposableExtension(); NoopExtension noop = new NoopExtension(); IUnityContainer container = new UnityContainer() .AddExtension(noop) .AddExtension(extension); container.Dispose(); Assert.IsTrue(extension.Disposed); } [TestMethod] public void CanSafelyDisposeContainerTwice() { DisposableExtension extension = new DisposableExtension(); IUnityContainer container = new UnityContainer() .AddExtension(extension); container.Dispose(); container.Dispose(); } /// /// Add the Diagnostic to the UnityContainer /// [TestMethod] public void AddMyCustonExtensionToContainer() { IUnityContainer uc = new UnityContainer(); uc.AddNewExtension(); Assert.IsNotNull(uc); } /// /// Check whether extension is added to the container created. /// [TestMethod] public void CheckExtensionAddedToContainer() { Diagnostic extension = new Diagnostic(); IUnityContainer uc = new UnityContainer(); uc.AddExtension(extension); Assert.AreSame(uc, extension.Container); } /// /// Add extension to the container. Check if object is returned. /// [TestMethod] public void AddExtensionGetObject() { Diagnostic extension = new Diagnostic(); IUnityContainer container = new UnityContainer() .AddExtension(extension); object result = container.Resolve(); Assert.IsNotNull(result); } /// /// Remove all extensions. Add default extension and the new extension. /// [TestMethod] public void AddDefaultAndCustomExtensions() { IUnityContainer container = new UnityContainer() .AddExtension(new Diagnostic()); object result = container.Resolve(); Assert.IsNotNull(result); Assert.IsNotNull(container); } /// /// Add existing instance of extension. SetLifetime of the extension with the container. /// [TestMethod] public void AddExtensionSetLifetime() { Diagnostic extension = new Diagnostic(); IUnityContainer container = new UnityContainer() .AddExtension(extension); container.RegisterInstance(extension); object result = container.Resolve(); Assert.IsNotNull(result); Assert.IsNotNull(container); } private class DisposableExtension : UnityContainerExtension, IDisposable { public bool Disposed = false; public bool Removed = false; protected override void Initialize() { } public override void Remove() { this.Removed = true; } public void Dispose() { if (this.Disposed) { throw new Exception("Can't dispose twice!"); } this.Disposed = true; } } private class NoopExtension : UnityContainerExtension { protected override void Initialize() { } } } } ================================================ FILE: tests/Unity.Tests/Extensions/LegacyExtensionTests.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Extension; namespace Unity.Tests.v5 { [TestClass] public class LegacyExtensionTests { [TestMethod] public void Register() { // Setup var container = new UnityContainer(); container.AddNewExtension(); // Act var config = container.Configure(); // Validate Assert.IsNotNull(config); } [TestMethod] public void SmartByDefault() { // Setup var container = new UnityContainer(); // Act var result = container.Resolve(); // Validate Assert.IsNotNull(result); } [TestMethod] [ExpectedException(typeof(ResolutionFailedException))] public void LegacySelection() { // Setup var container = new UnityContainer(); container.AddNewExtension(); // Act var instance = container.Resolve(); // Validate Assert.AreEqual(ObjectWithMultipleConstructors.Three, instance.Signature); } [TestMethod] [ExpectedException(typeof(ResolutionFailedException))] public void LegacySelectionDiagnostic() { // Setup var container = new UnityContainer(); container.AddNewExtension(); container.AddNewExtension(); // Act var instance = container.Resolve(); // Validate Assert.AreEqual(ObjectWithMultipleConstructors.Three, instance.Signature); } [TestMethod] public void CorrectLegacySelection() { // Setup var container = new UnityContainer(); container.AddNewExtension(); container.RegisterInstance("test"); // Act var instance = container.Resolve(); // Validate Assert.AreEqual(ObjectWithMultipleConstructors.Three, instance.Signature); } } #region Test Data public class ObjectWithMultipleConstructors { public const string One = "1"; public const string Two = "2"; public const string Three = "3"; public const string Four = "4"; public const string Five = "5"; public string Signature { get; } public ObjectWithMultipleConstructors(int first) { Signature = One; } public ObjectWithMultipleConstructors(object first, IUnityContainer second) { Signature = Two; } public ObjectWithMultipleConstructors(object first, string second, IUnityContainer third) { Signature = Three; } } #endregion } ================================================ FILE: tests/Unity.Tests/Generics/ClassWithConstMethodandProperty.cs ================================================ namespace Unity.Tests.v5.Generics { public class ClassWithConstMethodandProperty { private T value; public ClassWithConstMethodandProperty() { } public ClassWithConstMethodandProperty(T value) { this.value = value; } public T Value { get { return this.value; } set { this.value = value; } } public void SetValue(T value) { this.value = value; } } } ================================================ FILE: tests/Unity.Tests/Generics/Foo.cs ================================================ namespace Unity.Tests.v5.Generics { public class Foo : IFoo { public Foo() { } public Foo(TEntity value) { Value = value; } public TEntity Value { get; } } public class Foo : IFoo { } } ================================================ FILE: tests/Unity.Tests/Generics/FooRepository.cs ================================================ namespace Unity.Tests.v5.Generics { public class FooRepository : IRepository { } } ================================================ FILE: tests/Unity.Tests/Generics/GenMockLogger.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenMockLogger : IGenLogger { } } ================================================ FILE: tests/Unity.Tests/Generics/GenSpecialLogger.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenSpecialLogger : IGenLogger { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericA.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenericA { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericB.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenericB { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericC.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenericC { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericChainingFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Injection; using Unity.Lifetime; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Generics { // Test fixture to verify generic object chaining. // Reported as a bug in http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=27231 [TestClass] public class GenericChainingFixture { [TestMethod] public void CanSpecializeGenericTypes() { IUnityContainer container = new UnityContainer(); container.RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>)); ICommand cmd = container.Resolve>(); AssertExtensions.IsInstanceOfType(cmd, typeof(ConcreteCommand)); } [TestMethod] public void ConfiguringConstructorThatTakesOpenGenericTypeDoesNotThrow() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(LoggingCommand<>), new InjectionConstructor(new ResolvedParameter(typeof(ICommand<>), "concrete"))); } [TestMethod] public void CanConfigureGenericMethodInjectionInContainer() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ICommand<>), typeof(LoggingCommand<>), new InjectionConstructor(new ResolvedParameter(typeof(ICommand<>), "concrete")), new InjectionMethod("ChainedExecute", new ResolvedParameter(typeof(ICommand<>), "inner"))) .RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>), "concrete") .RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>), "inner"); } [TestMethod] public void CanConfigureInjectionForNonGenericMethodOnGenericClass() { IUnityContainer container = new UnityContainer(); container.RegisterType(typeof(ICommand<>), typeof(LoggingCommand<>), new InjectionConstructor(), new InjectionMethod("InjectMe")); ICommand result = container.Resolve>(); LoggingCommand logResult = (LoggingCommand)result; Assert.IsTrue(logResult.WasInjected); } [TestMethod] public void CanCallDefaultConstructorOnGeneric() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ICommand<>), typeof(LoggingCommand<>), new InjectionConstructor()) .RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>), "inner"); ICommand result = container.Resolve>(); AssertExtensions.IsInstanceOfType(result, typeof(LoggingCommand)); ICommand accountResult = container.Resolve>(); AssertExtensions.IsInstanceOfType(accountResult, typeof(LoggingCommand)); } [TestMethod] public void CanConfigureInjectionForGenericProperty() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ICommand<>), typeof(LoggingCommand<>), new InjectionConstructor(), new InjectionProperty("Inner", new ResolvedParameter(typeof(ICommand<>), "inner"))) .RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>), "inner"); } [TestMethod] public void CanInjectNonGenericPropertyOnGenericClass() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ICommand<>), typeof(ConcreteCommand<>), new InjectionProperty("NonGenericProperty")); ConcreteCommand result = (ConcreteCommand)(container.Resolve>()); Assert.IsNotNull(result.NonGenericProperty); } [TestMethod] public void ContainerControlledOpenGenericsAreDisposed() { var container = new UnityContainer(); container.RegisterType(typeof(ICommand<>), typeof(DisposableCommand<>), new ContainerControlledLifetimeManager()); var accountCommand = container.Resolve>(); var userCommand = container.Resolve>(); container.Dispose(); Assert.IsTrue(((DisposableCommand)accountCommand).Disposed); Assert.IsTrue(((DisposableCommand)userCommand).Disposed); } } // Our generic interface public interface ICommand { void Execute(T data); void ChainedExecute(ICommand inner); } // An implementation of ICommand that executes them. public class ConcreteCommand : ICommand { private object p = null; public void Execute(T data) { } public void ChainedExecute(ICommand inner) { } public object NonGenericProperty { get { return p; } set { p = value; } } } // And a decorator implementation that wraps an Inner ICommand<> public class LoggingCommand : ICommand { private ICommand inner; public bool ChainedExecuteWasCalled = false; public bool WasInjected = false; public LoggingCommand(ICommand inner) { this.inner = inner; } public LoggingCommand() { } public ICommand Inner { get { return inner; } set { inner = value; } } public void Execute(T data) { // do logging here Inner.Execute(data); } public void ChainedExecute(ICommand innerCommand) { ChainedExecuteWasCalled = true; } public void InjectMe() { WasInjected = true; } } // Test class for lifetime and dispose with open generics public class DisposableCommand : ICommand, IDisposable { public bool Disposed { get; private set; } public void Execute(T data) { } public void ChainedExecute(ICommand inner) { } public void Dispose() { Disposed = true; } } // A type with some nasty generics in the constructor public class Pathological { public Pathological(ICommand cmd1, ICommand cmd2) { } public ICommand AProperty { get { return null; } set { } } } // A couple of sample objects we're stuffing into our commands public class User { public void DoSomething(string message) { } } public class Account { } // InjectionParameterValue type used for testing nesting public struct Customer { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericConstraintsFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Exceptions; namespace Unity.Tests.v5.Generics { [TestClass] public class GenericConstraintsFixture { interface IFoo { } class Foo : IFoo where T : struct { } [TestMethod] public void ThrowsAppropriateExceptionWhenGenericArgumentFailsToMeetConstraintsOfMappedToType() { var ioc = new UnityContainer(); ioc.RegisterType(typeof(IFoo<>), typeof(Foo<>)); Assert.ThrowsException(() => ioc.Resolve>()); } [TestMethod] public void CanResolveOpenGenericInterfaceWithConstraintsInMappedToTypeWhenConstraintsAreMet() { var ioc = new UnityContainer(); ioc.RegisterType(typeof(IFoo<>), typeof(Foo<>)); Assert.IsNotNull(ioc.Resolve>()); } } } ================================================ FILE: tests/Unity.Tests/Generics/GenericD.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenericD { } } ================================================ FILE: tests/Unity.Tests/Generics/GenericList.cs ================================================ namespace Unity.Tests.v5.Generics { public class GenericList { private void Add(T input) { } } } ================================================ FILE: tests/Unity.Tests/Generics/GenericParameterFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Exceptions; using Unity.Injection; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Generics { /// /// Tests that use the GenericParameter class to ensure that /// generic object injection works. /// [TestClass] public class GenericParameterFixture { [TestMethod] public void CanCallNonGenericConstructorOnOpenGenericType() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor("Fiddle", new InjectionParameter("someValue"))); ClassWithOneGenericParameter result = container.Resolve>(); Assert.IsNull(result.InjectedValue); } [TestMethod] public void CanCallConstructorTakingGenericParameter() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new GenericParameter("T"))); Account a = new Account(); container.RegisterInstance(a); ClassWithOneGenericParameter result = container.Resolve>(); Assert.AreSame(a, result.InjectedValue); } [TestMethod] public void CanConfiguredNamedResolutionOfGenericParameter() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new GenericParameter("T", "named"))); Account a = new Account(); container.RegisterInstance(a); Account named = new Account(); container.RegisterInstance("named", named); ClassWithOneGenericParameter result = container.Resolve>(); Assert.AreSame(named, result.InjectedValue); } // Our various test objects public class ClassWithOneGenericParameter { public T InjectedValue; public ClassWithOneGenericParameter(string s, object o) { } public ClassWithOneGenericParameter(T injectedValue) { InjectedValue = injectedValue; } } public class GenericTypeWithMultipleGenericTypeParameters { private T theT; private U theU; public string Value; [InjectionConstructor] public GenericTypeWithMultipleGenericTypeParameters() { } public GenericTypeWithMultipleGenericTypeParameters(T theT) { this.theT = theT; } public GenericTypeWithMultipleGenericTypeParameters(U theU) { this.theU = theU; } public void Set(T theT) { this.theT = theT; } public void Set(U theU) { this.theU = theU; } public void SetAlt(T theT) { this.theT = theT; } public void SetAlt(string value) { this.Value = value; } } } } ================================================ FILE: tests/Unity.Tests/Generics/GenericResolvedArrayParameterFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Reflection; using Unity.Injection; namespace Unity.Tests.v5.Generics { [TestClass] public class GenericResolvedArrayParameterFixture { [TestMethod] public void MatchesArrayOfGenericTypeOnly() { var parameterValue = (IEquatable)new GenericResolvedArrayParameter("T"); Type genericTypeT = this.GetType().GetTypeInfo().GetDeclaredMethod("GetT") .GetGenericArguments()[0]; Type genericTypeU = this.GetType().GetTypeInfo().GetDeclaredMethod("GetU") .GetGenericArguments()[0]; Assert.IsFalse(parameterValue.Equals(genericTypeT)); Assert.IsFalse(parameterValue.Equals(genericTypeU)); Assert.IsFalse(parameterValue.Equals(typeof(object))); Assert.IsTrue( parameterValue.Equals(genericTypeT.MakeArrayType(1))); Assert.IsFalse(parameterValue.Equals(genericTypeT.MakeArrayType(2))); Assert.IsFalse(parameterValue.Equals(genericTypeU.MakeArrayType(1))); Assert.IsFalse(parameterValue.Equals(typeof(object[]))); } [TestMethod] public void CanCallConstructorTakingGenericParameterArray() { IUnityContainer container = new UnityContainer() .RegisterType( typeof(ClassWithOneArrayGenericParameter<>), new InjectionConstructor(new GenericParameter("T[]"))); Account a0 = new Account(); container.RegisterInstance("a0", a0); Account a1 = new Account(); container.RegisterInstance("a1", a1); Account a2 = new Account(); container.RegisterInstance(a2); ClassWithOneArrayGenericParameter result = container.Resolve>(); Assert.IsFalse(result.DefaultConstructorCalled); Assert.AreEqual(2, result.InjectedValue.Length); Assert.AreSame(a0, result.InjectedValue[0]); Assert.AreSame(a1, result.InjectedValue[1]); } [TestMethod] public void CanCallConstructorTakingGenericParameterArrayWithValues() { IUnityContainer container = new UnityContainer() .RegisterType( typeof(ClassWithOneArrayGenericParameter<>), new InjectionConstructor( new GenericResolvedArrayParameter( "T", new GenericParameter("T", "a2"), new GenericParameter("T", "a1")))); Account a0 = new Account(); container.RegisterInstance("a0", a0); Account a1 = new Account(); container.RegisterInstance("a1", a1); Account a2 = new Account(); container.RegisterInstance("a2", a2); ClassWithOneArrayGenericParameter result = container.Resolve>(); Assert.IsFalse(result.DefaultConstructorCalled); Assert.AreEqual(2, result.InjectedValue.Length); Assert.AreSame(a2, result.InjectedValue[0]); Assert.AreSame(a1, result.InjectedValue[1]); } [TestMethod] public void CanSetPropertyWithGenericParameterArrayType() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneArrayGenericParameter<>), new InjectionConstructor(), new InjectionProperty("InjectedValue", new GenericParameter("T()"))); Account a0 = new Account(); container.RegisterInstance("a1", a0); Account a1 = new Account(); container.RegisterInstance("a2", a1); Account a2 = new Account(); container.RegisterInstance(a2); ClassWithOneArrayGenericParameter result = container.Resolve>(); Assert.IsTrue(result.DefaultConstructorCalled); Assert.AreEqual(2, result.InjectedValue.Length); Assert.AreSame(a0, result.InjectedValue[0]); Assert.AreSame(a1, result.InjectedValue[1]); } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void AppropriateExceptionIsThrownWhenNoMatchingConstructorCanBeFound() { new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new GenericResolvedArrayParameter("T"))); } private void GetT() { } private void GetU() { } public class ClassWithOneArrayGenericParameter { private T[] injectedValue; public readonly bool DefaultConstructorCalled; public ClassWithOneArrayGenericParameter() { DefaultConstructorCalled = true; } public ClassWithOneArrayGenericParameter(T[] injectedValue) { DefaultConstructorCalled = false; this.injectedValue = injectedValue; } public T[] InjectedValue { get { return this.injectedValue; } set { this.injectedValue = value; } } } public class ClassWithOneGenericParameter { } } } ================================================ FILE: tests/Unity.Tests/Generics/GenericsFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Injection; using Unity.Lifetime; namespace Unity.Tests.v5.Generics { /// /// Summary description for TestGenerics /// [TestClass] public class GenericsFixture { public class GenericArrayPropertyDependency { public T[] Stuff { get; set; } } /// /// Tries to resolve a generic class that at registration, is open and contains an array property of the generic type. /// /// See Bug 3849 [TestMethod] public void ResolveConfiguredGenericType() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(GenericArrayPropertyDependency<>), "testing", new InjectionProperty("Stuff")) .RegisterInstance("first", "first") .RegisterInstance("second", "second"); var result = container.Resolve>("testing"); CollectionAssert.AreEquivalent(new[] { "first", "second" }, result.Stuff); } /// /// Sample from Unit test cases. /// modified for WithLifetime. /// pass /// [TestMethod] public void CanRegisterGenericTypesAndResolveThem() { IDictionary myDict = new Dictionary(); myDict.Add("One", "two"); myDict.Add("Two", "three"); IUnityContainer container = new UnityContainer(); container.RegisterInstance(myDict); container.RegisterType(typeof(IDictionary<,>), typeof(Dictionary<,>), new InjectionConstructor()); IDictionary result = container.Resolve>(); Assert.AreSame(myDict, result); } /// /// Sample from Unit test cases. /// [TestMethod] public void CanSpecializeGenericsViaTypeMappings() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IRepository<>), typeof(MockRespository<>)) .RegisterType, FooRepository>(); IRepository generalResult = container.Resolve>(); IRepository specializedResult = container.Resolve>(); Assert.IsInstanceOfType(generalResult, typeof(MockRespository)); Assert.IsInstanceOfType(specializedResult, typeof(FooRepository)); } /// /// Using List of int type. Pass /// WithLifetime passed is null. /// [TestMethod] public void Testmethod_NoLifetimeSpecified() { var myList = new List(); var container = new UnityContainer() .RegisterInstance>(myList) .RegisterType>(); var result = container.Resolve>(); Assert.AreSame(myList, result); } /// /// check mapping with generics /// [TestMethod] public void TypeMappingWithExternallyControlled() { IUnityContainer container = new UnityContainer() .RegisterInstance("Test String") .RegisterType(typeof(IFoo<>), typeof(Foo<>), new ContainerControlledLifetimeManager()); IFoo result = container.Resolve>(); Assert.IsInstanceOfType(result, typeof(Foo)); } /// /// Using List of string type. /// Passes if WithLifetime passed is null. Pass /// [TestMethod] public void Testmethod_ListOfString() { var myList = new List(); var container = new UnityContainer() .RegisterInstance>(myList) .RegisterType>(); IList result = container.Resolve>(); Assert.AreSame(myList, result); } /// /// Using List of object type. /// Passes if WithLifetime passed is null. Pass /// [TestMethod] public void Testmethod_ListOfObjectType() { var myList = new List(); var container = new UnityContainer() .RegisterInstance(myList) .RegisterType, List>(); var result = container.Resolve>(); Assert.IsInstanceOfType(result, typeof(List)); } /// /// have implemented constructor injection of generic type. Pass /// [TestMethod] public void Testmethod_ImplementConstructorInjection() { Refer myRefer = new Refer(); myRefer.Str = "HiHello"; IUnityContainer container = new UnityContainer() .RegisterInstance>(myRefer) .RegisterType>(); Refer result = container.Resolve>(); Assert.AreSame(myRefer, myRefer); } /// /// have implemented constructor injection of generic type. passes /// [TestMethod] public void Testmethod_ConstrucotorInjectionGenerics() { Refer myRefer = new Refer(); myRefer.Str = "HiHello"; IUnityContainer container = new UnityContainer() .RegisterInstance>(myRefer) .RegisterType, MockRespository>(); IRepository result = container.Resolve>(); Assert.IsInstanceOfType(result, typeof(IRepository)); } /// /// Passing a generic class as parameter to List which is generic /// [TestMethod] public void Testmethod_GenericStack() { Stack obj = new Stack(); IUnityContainer uc = new UnityContainer(); uc.RegisterInstance>(obj); Stack obj1 = uc.Resolve>(); Assert.AreSame(obj1, obj); } [TestMethod] public void Testmethod_CheckPropInjection() { IUnityContainer container = new UnityContainer() .RegisterType, MockRespository>(); IRepository result = container.Resolve>(); Assert.IsNotNull(result); } public interface IService { } public class ServiceA : IService { } public class ServiceB : IService { } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void FailedResolveAllTest() { var container = new UnityContainer(); container.RegisterType("1"); container.RegisterFactory("2", c => { throw new System.InvalidOperationException(); }); container.ResolveAll(); } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void FailedResolveEnumerableTest() { var container = new UnityContainer(); container.RegisterType("1"); container.RegisterFactory("2", c => { throw new System.InvalidOperationException(); }); var instance = container.Resolve>().ToArray(); Assert.Fail("Should never reach this line"); } [TestMethod] public void CanResolveOpenGenericCollections() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IService<>), typeof(ServiceA<>), "A") .RegisterType(typeof(IService<>), typeof(ServiceB<>), "B"); List> result = container.Resolve>>().ToList(); Assert.AreEqual(2, result.Count); Assert.IsTrue(result.Any(svc => svc is ServiceA)); Assert.IsTrue(result.Any(svc => svc is ServiceB)); } public class ServiceStruct : IService where T : struct { } [TestMethod] public void CanResolveStructConstraintsCollections() { var container = new UnityContainer() .RegisterType(typeof(IService<>), typeof(ServiceA<>), "A") .RegisterType(typeof(IService<>), typeof(ServiceB<>), "B") .RegisterType(typeof(IService<>), typeof(ServiceStruct<>), "Struct"); var result = container.Resolve>>().ToList(); Assert.AreEqual(3, result.Count); Assert.IsTrue(result.Any(svc => svc is ServiceA)); Assert.IsTrue(result.Any(svc => svc is ServiceB)); Assert.IsTrue(result.Any(svc => svc is ServiceStruct)); List> constrainedResult = container.Resolve>>().ToList(); Assert.AreEqual(2, constrainedResult.Count); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceA)); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceB)); } public class ServiceClass : IService where T : class { } [TestMethod] public void CanResolveClassConstraintsCollections() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IService<>), typeof(ServiceA<>), "A") .RegisterType(typeof(IService<>), typeof(ServiceB<>), "B") .RegisterType(typeof(IService<>), typeof(ServiceClass<>), "Class"); List> result = container.Resolve>>().ToList(); Assert.AreEqual(3, result.Count); Assert.IsTrue(result.Any(svc => svc is ServiceA)); Assert.IsTrue(result.Any(svc => svc is ServiceB)); Assert.IsTrue(result.Any(svc => svc is ServiceClass)); List> constrainedResult = container.Resolve>>().ToList(); Assert.AreEqual(2, constrainedResult.Count); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceA)); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceB)); } public class ServiceNewConstraint : IService where T : new() { } public class TypeWithNoPublicNoArgCtors { public TypeWithNoPublicNoArgCtors(int _) { } private TypeWithNoPublicNoArgCtors() { } } [TestMethod] public void CanResolveDefaultCtorConstraintsCollections() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IService<>), typeof(ServiceA<>), "A") .RegisterType(typeof(IService<>), typeof(ServiceB<>), "B") .RegisterType(typeof(IService<>), typeof(ServiceNewConstraint<>), "NewConstraint"); List> result = container.Resolve>>().ToList(); Assert.AreEqual(3, result.Count); Assert.IsTrue(result.Any(svc => svc is ServiceA)); Assert.IsTrue(result.Any(svc => svc is ServiceB)); Assert.IsTrue(result.Any(svc => svc is ServiceNewConstraint)); List> constrainedResult = container.Resolve>>().ToList(); Assert.AreEqual(2, constrainedResult.Count); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceA)); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceB)); } public class ServiceInterfaceConstraint : IService where T : IEnumerable { } [TestMethod] public void CanResolveInterfaceConstraintsCollections() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IService<>), typeof(ServiceA<>), "A") .RegisterType(typeof(IService<>), typeof(ServiceB<>), "B") .RegisterType(typeof(IService<>), typeof(ServiceInterfaceConstraint<>), "InterfaceConstraint"); List> result = container.Resolve>>().ToList(); Assert.AreEqual(3, result.Count); Assert.IsTrue(result.Any(svc => svc is ServiceA)); Assert.IsTrue(result.Any(svc => svc is ServiceB)); Assert.IsTrue(result.Any(svc => svc is ServiceInterfaceConstraint)); List> constrainedResult = container.Resolve>>().ToList(); Assert.AreEqual(2, constrainedResult.Count); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceA)); Assert.IsTrue(constrainedResult.Any(svc => svc is ServiceB)); } } } ================================================ FILE: tests/Unity.Tests/Generics/GenericsReflectionExperimentsFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Generics { /// /// Experimenting with reflection and generics. /// [TestClass] public class GenericsReflectionExperimentsFixture { // Experiments learning about reflection and generics [TestMethod] public void ConcreteGenericTypes_ReturnConstructorThatTakeGenericsInReflection() { Type t = typeof(LoggingCommand); ConstructorInfo ctor = t.GetTypeInfo().DeclaredConstructors.Where( c => c.GetParameters()[0].ParameterType == typeof(ICommand)).First(); Assert.IsNotNull(ctor); } [TestMethod] public void OpenGenericTypes_GenericPropertiesAreReturnedByReflection() { Type t = typeof(LoggingCommand<>); PropertyInfo[] props = t.GetTypeInfo().DeclaredProperties.ToArray(); Assert.AreEqual(1, props.Length); } [TestMethod] public void GivenGenericConstructorParameters_CanGetConcreteConstructor() { Type openType = typeof(Pathological<,>); Type targetType = typeof(Pathological); Assert.IsTrue(openType.GetTypeInfo().ContainsGenericParameters); Assert.IsFalse(targetType.GetTypeInfo().ContainsGenericParameters); ConstructorInfo ctor = targetType.GetTypeInfo().DeclaredConstructors .Where(c => c.GetParameters().Count() == 2) .Where(c => c.GetParameters()[0].ParameterType == typeof(ICommand<>) && c.GetParameters()[0].ParameterType == typeof(ICommand<>)) .FirstOrDefault(); Assert.IsNull(ctor); ConstructorInfo concreteCtor = targetType.GetTypeInfo().DeclaredConstructors .Where(c => c.GetParameters().Count() == 2) .Where(c => c.GetParameters()[0].ParameterType == typeof(ICommand) && c.GetParameters()[1].ParameterType == typeof(ICommand)) .FirstOrDefault(); Assert.IsNotNull(concreteCtor); ConstructorInfo[] openCtors = openType.GetTypeInfo().DeclaredConstructors.ToArray(); Assert.AreEqual(1, openCtors.Length); ParameterInfo[] ctorParams = openCtors[0].GetParameters(); Assert.AreEqual(2, ctorParams.Length); Assert.IsTrue(ctorParams[0].ParameterType.GetTypeInfo().ContainsGenericParameters); Assert.AreSame(typeof(ICommand<>), ctorParams[0].ParameterType.GetGenericTypeDefinition()); Type[] openTypeArgs = openType.GetTypeInfo().GenericTypeParameters; Type[] ctorParamArgs = ctorParams[0].ParameterType.GenericTypeArguments; Assert.AreSame(openTypeArgs[1], ctorParamArgs[0]); } [TestMethod] public void CanFigureOutOpenTypeDefinitionsForParameters() { Type openType = typeof(Pathological<,>); ConstructorInfo ctor = openType.GetTypeInfo().DeclaredConstructors.ElementAt(0); ParameterInfo param0 = ctor.GetParameters()[0]; Assert.AreNotEqual(typeof(ICommand<>), param0.ParameterType); Assert.AreEqual(typeof(ICommand<>), param0.ParameterType.GetGenericTypeDefinition()); Assert.IsFalse(param0.ParameterType.GetTypeInfo().IsGenericTypeDefinition); Assert.IsTrue(param0.ParameterType.GetTypeInfo().IsGenericType); Assert.IsTrue(typeof(ICommand<>).GetTypeInfo().IsGenericTypeDefinition); Assert.AreEqual(typeof(ICommand<>), typeof(ICommand<>).GetGenericTypeDefinition()); } [TestMethod] public void CanDistinguishOpenAndClosedGenerics() { Type closed = typeof(ICommand); Assert.IsTrue(closed.GetTypeInfo().IsGenericType); Assert.IsFalse(closed.GetTypeInfo().ContainsGenericParameters); Type open = typeof(ICommand<>); Assert.IsTrue(open.GetTypeInfo().IsGenericType); Assert.IsTrue(open.GetTypeInfo().ContainsGenericParameters); } [TestMethod] public void CanFindClosedConstructorFromOpenConstructorInfo() { Type openType = typeof(Pathological<,>); Type closedType = typeof(Pathological); ConstructorInfo openCtor = openType.GetTypeInfo().DeclaredConstructors.ElementAt(0); Assert.AreSame(openCtor.DeclaringType, openType); Type createdClosedType = openType.MakeGenericType(closedType.GenericTypeArguments); // Go through the parameter list of the open constructor and fill in the // type arguments for generic parameters based on the arguments used to // create the closed types. Type[] closedTypeParams = closedType.GenericTypeArguments; List closedCtorParamTypes = new List(); List parameterPositions = new List(); foreach (ParameterInfo openParam in openCtor.GetParameters()) { closedCtorParamTypes.Add(ClosedTypeFromOpenParameter(openParam, closedTypeParams)); Type[] genericParameters = openParam.ParameterType.GenericTypeArguments; foreach (Type gp in genericParameters) { parameterPositions.Add(gp.GenericParameterPosition); } } CollectionAssertExtensions.AreEqual(new int[] { 1, 0 }, parameterPositions); ConstructorInfo targetCtor = closedType.GetMatchingConstructor(closedCtorParamTypes.ToArray()); Assert.AreSame(closedType, createdClosedType); ConstructorInfo closedCtor = closedType.GetMatchingConstructor(Types(typeof(ICommand), typeof(ICommand))); Assert.AreSame(closedCtor, targetCtor); } [TestMethod] public void ConstructorHasGenericArguments() { ConstructorInfo ctor = typeof(LoggingCommand<>).GetTypeInfo().DeclaredConstructors.ElementAt(0); Assert.IsTrue(HasOpenGenericParameters(ctor)); } [TestMethod] public void ConstructorDoesNotHaveGenericArguments() { ConstructorInfo ctor = typeof(LoggingCommand).GetMatchingConstructor(Types(typeof(ICommand))); Assert.IsFalse(HasOpenGenericParameters(ctor)); } private Type ClosedTypeFromOpenParameter(ParameterInfo openGenericParameter, Type[] typeParams) { Type[] genericParameters = openGenericParameter.ParameterType.GenericTypeArguments; Type[] genericTypeParams = new Type[genericParameters.Length]; for (int i = 0; i < genericParameters.Length; ++i) { genericTypeParams[i] = typeParams[genericParameters[i].GenericParameterPosition]; } return openGenericParameter.ParameterType.GetGenericTypeDefinition().MakeGenericType(genericTypeParams); } private bool HasOpenGenericParameters(ConstructorInfo ctor) { foreach (ParameterInfo param in ctor.GetParameters()) { if (param.ParameterType.GetTypeInfo().IsGenericType && param.ParameterType.GetTypeInfo().ContainsGenericParameters) { return true; } } return false; } private static Type[] Types(params Type[] t) { return t; } } } ================================================ FILE: tests/Unity.Tests/Generics/HaveAGenericType.cs ================================================ namespace Unity.Tests.v5.Generics { public class HaveAGenericType : IHaveAGenericType { public HaveAGenericType() { } public HaveAGenericType(T1 t1Value) { PropT1 = t1Value; } private T1 propT1; public T1 PropT1 { get { return propT1; } set { propT1 = value; } } public void Set(T1 value) { PropT1 = value; } } } ================================================ FILE: tests/Unity.Tests/Generics/HaveManyGenericTypes.cs ================================================ namespace Unity.Tests.v5.Generics { public class HaveManyGenericTypes : IHaveManyGenericTypes { public HaveManyGenericTypes() { } public HaveManyGenericTypes(T1 t1Value) { PropT1 = t1Value; } public HaveManyGenericTypes(T2 t2Value) { PropT2 = t2Value; } public HaveManyGenericTypes(T2 t2Value, T1 t1Value) { PropT2 = t2Value; PropT1 = t1Value; } private T1 propT1; public T1 PropT1 { get { return propT1; } set { propT1 = value; } } private T2 propT2; public T2 PropT2 { get { return propT2; } set { propT2 = value; } } private T3 propT3; public T3 PropT3 { get { return propT3; } set { propT3 = value; } } private T4 propT4; public T4 PropT4 { get { return propT4; } set { propT4 = value; } } public void Set(T1 t1Value) { PropT1 = t1Value; } public void Set(T2 t2Value) { PropT2 = t2Value; } public void Set(T3 t3Value) { PropT3 = t3Value; } public void Set(T4 t4Value) { PropT4 = t4Value; } public void SetMultiple(T4 t4Value, T3 t3Value) { PropT4 = t4Value; PropT3 = t3Value; } } } ================================================ FILE: tests/Unity.Tests/Generics/HaveManyGenericTypesClosed.cs ================================================ namespace Unity.Tests.v5.Generics { public class HaveManyGenericTypesClosed : IHaveManyGenericTypesClosed { public HaveManyGenericTypesClosed() { } public HaveManyGenericTypesClosed(GenericA t1Value) { PropT1 = t1Value; } public HaveManyGenericTypesClosed(GenericB t2Value) { PropT2 = t2Value; } public HaveManyGenericTypesClosed(GenericB t2Value, GenericA t1Value) { PropT2 = t2Value; PropT1 = t1Value; } private GenericA propT1; public GenericA PropT1 { get { return propT1; } set { propT1 = value; } } private GenericB propT2; public GenericB PropT2 { get { return propT2; } set { propT2 = value; } } private GenericC propT3; public GenericC PropT3 { get { return propT3; } set { propT3 = value; } } private GenericD propT4; public GenericD PropT4 { get { return propT4; } set { propT4 = value; } } public void Set(GenericA t1Value) { PropT1 = t1Value; } public void Set(GenericB t2Value) { PropT2 = t2Value; } public void Set(GenericC t3Value) { PropT3 = t3Value; } public void Set(GenericD t4Value) { PropT4 = t4Value; } public void SetMultiple(GenericD t4Value, GenericC t3Value) { PropT4 = t4Value; PropT3 = t3Value; } } } ================================================ FILE: tests/Unity.Tests/Generics/IFoo.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IFoo { TEntity Value { get; } } public interface IFoo { } } ================================================ FILE: tests/Unity.Tests/Generics/IGenLogger.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IGenLogger { } } ================================================ FILE: tests/Unity.Tests/Generics/IHaveAGenericType.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IHaveAGenericType { T1 PropT1 { get; set; } void Set(T1 value); } } ================================================ FILE: tests/Unity.Tests/Generics/IHaveManyGenericTypes.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IHaveManyGenericTypes { T1 PropT1 { get; set; } T2 PropT2 { get; set; } T3 PropT3 { get; set; } T4 PropT4 { get; set; } void Set(T1 value); void Set(T2 value); void Set(T3 value); void Set(T4 value); void SetMultiple(T4 t4Value, T3 t3Value); } } ================================================ FILE: tests/Unity.Tests/Generics/IHaveManyGenericTypesClosed.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IHaveManyGenericTypesClosed { GenericA PropT1 { get; set; } GenericB PropT2 { get; set; } GenericC PropT3 { get; set; } GenericD PropT4 { get; set; } void Set(GenericA value); void Set(GenericB value); void Set(GenericC value); void Set(GenericD value); void SetMultiple(GenericD t4Value, GenericC t3Value); } } ================================================ FILE: tests/Unity.Tests/Generics/IRepository.cs ================================================ namespace Unity.Tests.v5.Generics { public interface IRepository { } } ================================================ FILE: tests/Unity.Tests/Generics/MockRespository.cs ================================================ namespace Unity.Tests.v5.Generics { public class MockRespository : IRepository { private Refer obj; [Dependency] public Refer Add { get { return obj; } set { obj = value; } } [InjectionConstructor] public MockRespository(Refer obj) { } } } ================================================ FILE: tests/Unity.Tests/Generics/Refer.cs ================================================ namespace Unity.Tests.v5.Generics { public class Refer { private string str; public string Str { get { return str; } set { str = value; } } public Refer() { str = "Hello"; } } } ================================================ FILE: tests/Unity.Tests/Generics/Refer1.cs ================================================ namespace Unity.Tests.v5.Generics { public class Refer1 { public Refer1() { } } } ================================================ FILE: tests/Unity.Tests/Injection/InjectedMembersFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Injection; namespace Unity.Tests.v5.Injection { [TestClass] public class InjectedMembersFixture { [TestMethod] public void CanConfigureContainerToCallDefaultConstructor() { IUnityContainer container = new UnityContainer() .RegisterType(new InjectionConstructor()); GuineaPig pig = container.Resolve(); Assert.IsTrue(pig.DefaultConstructorCalled); } [TestMethod] public void CanConfigureContainerToCallConstructorWithValues() { int expectedInt = 37; string expectedString = "Hey there"; double expectedDouble = Math.PI; IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor(expectedInt, expectedString, expectedDouble)); GuineaPig pig = container.Resolve(); Assert.IsTrue(pig.ThreeArgumentConstructorCalled); Assert.AreEqual(expectedInt, pig.I); Assert.AreEqual(expectedDouble, pig.D); Assert.AreEqual(expectedString, pig.S); } [TestMethod] public void CanConfigureContainerToInjectProperty() { object expectedObject = new object(); IUnityContainer container = new UnityContainer() .RegisterInstance(expectedObject) .RegisterType( new InjectionConstructor(), new InjectionProperty("ObjectProperty")); GuineaPig pig = container.Resolve(); Assert.IsTrue(pig.DefaultConstructorCalled); Assert.AreSame(expectedObject, pig.ObjectProperty); } [TestMethod] public void CanConfigureContainerToInjectPropertyWithValue() { int expectedInt = 82; IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor(), new InjectionProperty("IntProperty", expectedInt)); GuineaPig pig = container.Resolve(); Assert.IsTrue(pig.DefaultConstructorCalled); Assert.AreEqual(expectedInt, pig.IntProperty); } [TestMethod] public void CanConfigureInjectionByNameWithoutUsingGenerics() { object expectedObjectZero = new object(); object expectedObjectOne = new object(); IUnityContainer container = new UnityContainer() .RegisterType(typeof(GuineaPig), "one", new InjectionConstructor(expectedObjectOne), new InjectionProperty("IntProperty", 35)) .RegisterType(typeof(GuineaPig), new InjectionConstructor(), new InjectionProperty("ObjectProperty", new ResolvedParameter(typeof(object), "zero"))) .RegisterInstance("zero", expectedObjectZero); GuineaPig pigZero = container.Resolve(); GuineaPig pigOne = container.Resolve("one"); Assert.IsTrue(pigZero.DefaultConstructorCalled); Assert.AreSame(expectedObjectZero, pigZero.ObjectProperty); Assert.IsTrue(pigOne.OneArgumentConstructorCalled); Assert.AreSame(expectedObjectOne, pigOne.ObjectProperty); Assert.AreEqual(35, pigOne.IntProperty); } [TestMethod] public void CanConfigureInjectionWithGenericProperty() { IUnityContainer container = new UnityContainer() .RegisterInstance(35) .RegisterType(typeof(GenericGuineaPig<>), new InjectionProperty("GenericProperty")); GenericGuineaPig pig = container.Resolve>(); Assert.AreEqual(35, pig.GenericProperty); } [TestMethod] public void CanConfigureContainerToDoMethodInjection() { string expectedString = "expected string"; IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor(), new InjectionMethod("InjectMeHerePlease", expectedString)); GuineaPig pig = container.Resolve(); Assert.IsTrue(pig.DefaultConstructorCalled); Assert.AreEqual(expectedString, pig.S); } [TestMethod] public void ConfiguringInjectionAfterResolvingTakesEffect() { IUnityContainer container = new UnityContainer() .RegisterType(new InjectionConstructor()); container.Resolve(); container.RegisterType( new InjectionConstructor(new InjectionParameter(typeof(object), "someValue"))); GuineaPig pig2 = container.Resolve(); Assert.AreEqual("someValue", pig2.ObjectProperty.ToString()); } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void ConfiguringInjectionConstructorThatDoesNotExistThrows() { IUnityContainer container = new UnityContainer(); container.RegisterType( new InjectionConstructor(typeof(string), typeof(string))); } [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void RegisterTypeThrowsIfTypeIsNull() { IUnityContainer container = new UnityContainer(); container.RegisterType(null); } public class GuineaPig { public bool DefaultConstructorCalled = false; public bool OneArgumentConstructorCalled = false; public bool ThreeArgumentConstructorCalled = false; public object O; public int I; public string S; public double D; public GuineaPig() { DefaultConstructorCalled = true; } public GuineaPig(object o) { OneArgumentConstructorCalled = true; O = o; } public GuineaPig(int i, string s, double d) { ThreeArgumentConstructorCalled = true; I = i; S = s; D = d; } public int IntProperty { get { return I; } set { I = value; } } public object ObjectProperty { get { return O; } set { O = value; } } public void InjectMeHerePlease(string s) { S = s; } } public class GenericGuineaPig { public T G; public T GenericProperty { get { return G; } set { G = value; } } } } } ================================================ FILE: tests/Unity.Tests/Injection/InjectingArraysFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Injection; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Injection { [TestClass] public class InjectingArraysFixture { [TestMethod] public void CanConfigureContainerToCallConstructorWithArrayParameter() { ILogger o1 = new MockLogger(); ILogger o2 = new SpecialLogger(); IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor(typeof(ILogger[]))) .RegisterInstance("o1", o1) .RegisterInstance("o2", o2); TypeWithArrayConstructorParameter resolved = container.Resolve(); Assert.IsNotNull(resolved.Loggers); Assert.AreEqual(2, resolved.Loggers.Length); Assert.AreSame(o1, resolved.Loggers[0]); Assert.AreSame(o2, resolved.Loggers[1]); } [TestMethod] public void CanConfigureContainerToCallConstructorWithArrayParameterWithNonGenericVersion() { ILogger o1 = new MockLogger(); ILogger o2 = new SpecialLogger(); IUnityContainer container = new UnityContainer() .RegisterType(new InjectionConstructor(typeof(ILogger[]))) .RegisterInstance("o1", o1) .RegisterInstance("o2", o2); TypeWithArrayConstructorParameter resolved = container.Resolve(); Assert.IsNotNull(resolved.Loggers); Assert.AreEqual(2, resolved.Loggers.Length); Assert.AreSame(o1, resolved.Loggers[0]); Assert.AreSame(o2, resolved.Loggers[1]); } [TestMethod] public void CanConfigureContainerToInjectSpecificValuesIntoAnArray() { ILogger logger2 = new SpecialLogger(); IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor( new ResolvedArrayParameter( new ResolvedParameter("log1"), typeof(ILogger), logger2))) .RegisterType() .RegisterType("log1"); TypeWithArrayConstructorParameter result = container.Resolve(); Assert.AreEqual(3, result.Loggers.Length); AssertExtensions.IsInstanceOfType(result.Loggers[0], typeof(SpecialLogger)); AssertExtensions.IsInstanceOfType(result.Loggers[1], typeof(MockLogger)); Assert.AreSame(logger2, result.Loggers[2]); } [TestMethod] public void CanConfigureContainerToInjectSpecificValuesIntoAnArrayWithNonGenericVersion() { ILogger logger2 = new SpecialLogger(); IUnityContainer container = new UnityContainer() .RegisterType( new InjectionConstructor( new ResolvedArrayParameter( typeof(ILogger), new ResolvedParameter("log1"), typeof(ILogger), logger2))) .RegisterType() .RegisterType("log1"); TypeWithArrayConstructorParameter result = container.Resolve(); Assert.AreEqual(3, result.Loggers.Length); AssertExtensions.IsInstanceOfType(result.Loggers[0], typeof(SpecialLogger)); AssertExtensions.IsInstanceOfType(result.Loggers[1], typeof(MockLogger)); Assert.AreSame(logger2, result.Loggers[2]); } [TestMethod] public void CreatingResolvedArrayParameterWithValuesOfNonCompatibleType() { ILogger logger2 = new SpecialLogger(); AssertExtensions.AssertException(() => { new ResolvedArrayParameter( new ResolvedParameter("log1"), typeof(int), logger2); }); } [TestMethod] public void ContainerAutomaticallyResolvesAllWhenInjectingArrays() { ILogger[] expected = new ILogger[] { new MockLogger(), new SpecialLogger() }; IUnityContainer container = new UnityContainer() .RegisterInstance("one", expected[0]) .RegisterInstance("two", expected[1]); TypeWithArrayConstructorParameter result = container.Resolve(); CollectionAssertExtensions.AreEqual(expected, result.Loggers); } [TestMethod] public void ContainerAutomaticallyResolvesAllWhenInjectingGenericArrays() { ILogger[] expected = new ILogger[] { new MockLogger(), new SpecialLogger() }; IUnityContainer container = new UnityContainer() .RegisterInstance("one", expected[0]) .RegisterInstance("two", expected[1]) .RegisterType(typeof(GenericTypeWithArrayProperty<>), new InjectionProperty("Prop")); var result = container.Resolve>(); result.Prop.AssertContainsInAnyOrder(expected[0], expected[1]); } public class TypeWithArrayConstructorParameter { public readonly ILogger[] Loggers; public TypeWithArrayConstructorParameter(ILogger[] loggers) { Loggers = loggers; } } public class GenericTypeWithArrayProperty { public T[] Prop { get; set; } } } } ================================================ FILE: tests/Unity.Tests/Injection/OptionalDependencyAPIConfigurationFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Injection; namespace Unity.Tests.v5.Injection { /// /// Summary description for OptionalDependencyAPIConfigurationFixture /// [TestClass] public class OptionalDependencyAPIConfigurationFixture { private IUnityContainer container; [TestInitialize] public void Setup() { container = new UnityContainer(); } [TestMethod] public void CanConfigureConstructorWithOptionalDependency() { container.RegisterType( new InjectionConstructor(new OptionalParameter())); var result = container.Resolve(); Assert.IsNull(result.Pig); } [TestMethod] public void CanResolveOptionalDependencyWhenConfiguredByAPI() { IGuineaPig mockPig = new GuineaPigImpl(); container.RegisterType( new InjectionConstructor(new OptionalParameter())) .RegisterInstance(mockPig); var result = container.Resolve(); Assert.AreSame(mockPig, result.Pig); } [TestMethod] public void CanResolveOptionalDependenciesByNameWithAPI() { IGuineaPig expected = new GuineaPigImpl(); container.RegisterType( new InjectionConstructor(new OptionalParameter(typeof(IGuineaPig), "named"))) .RegisterInstance("named", expected); var result = container.Resolve(); Assert.AreSame(expected, result.Pig); } [TestMethod] public void CanConfigureOptionalPropertiesViaAPI() { container.RegisterType( new InjectionConstructor(), new InjectionProperty("Pig", new OptionalParameter())); var result = container.Resolve(); Assert.IsNull(result.Pig); } [TestMethod] public void CanConfigureOptionalParameterToInjectionMethod() { IGuineaPig expected = new GuineaPigImpl(); container.RegisterType( new InjectionConstructor(), new InjectionMethod("SetPig", new OptionalParameter("named"))) .RegisterInstance("named", expected); var result = container.Resolve(); Assert.AreSame(expected, result.Pig); } public class GuineaPig { public bool ConstructorWithArgsWasCalled = false; public GuineaPig() { } public GuineaPig(IGuineaPig pig) { Pig = pig; ConstructorWithArgsWasCalled = true; } public IGuineaPig Pig { get; set; } public void SetPig(IGuineaPig pig) { Pig = pig; } } public interface IGuineaPig { } public class GuineaPigImpl : IGuineaPig { } } } ================================================ FILE: tests/Unity.Tests/Injection/OptionalDependencyAttributeFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.Injection { /// /// Summary description for OptionalDependencyAttributeFixture /// [TestClass] public class OptionalDependencyAttributeFixture { public void OptionalDependencyParametersAreInjectedWithNull() { IUnityContainer container = new UnityContainer(); var result = container.Resolve(); Assert.IsNull(result.SomeInterface); } [TestMethod] public void OptionalDependencyParameterIsResolvedIfRegisteredInContainer() { ISomeInterface expectedSomeInterface = new SomeInterfaceMock(); IUnityContainer container = new UnityContainer() .RegisterInstance(expectedSomeInterface); var result = container.Resolve(); Assert.AreSame(expectedSomeInterface, result.SomeInterface); } [TestMethod] public void OptionalDependencyParameterIsResolvedByName() { ISomeInterface namedSomeInterface = new SomeInterfaceMock(); ISomeInterface defaultSomeInterface = new SomeInterfaceMock(); IUnityContainer container = new UnityContainer() .RegisterInstance(defaultSomeInterface) .RegisterInstance("named", namedSomeInterface); var result = container.Resolve(); Assert.AreSame(namedSomeInterface, result.SomeInterface); } [TestMethod] public void OptionalPropertiesGetNullWhenNotConfigured() { IUnityContainer container = new UnityContainer(); var result = container.Resolve(); Assert.IsNull(result.SomeInterface); } [TestMethod] public void OptionalPropertiesAreInjectedWhenRegisteredInContainer() { ISomeInterface expected = new SomeInterfaceMock(); IUnityContainer container = new UnityContainer() .RegisterInstance(expected); var result = container.Resolve(); Assert.AreSame(expected, result.SomeInterface); } [TestMethod] public void OptionalPropertiesAreInjectedByName() { ISomeInterface namedSomeInterface = new SomeInterfaceMock(); ISomeInterface defaultSomeInterface = new SomeInterfaceMock(); IUnityContainer container = new UnityContainer() .RegisterInstance(defaultSomeInterface) .RegisterInstance("named", namedSomeInterface); var result = container.Resolve(); Assert.AreSame(namedSomeInterface, result.SomeInterface); } public class SomeInterfaceMock : ISomeInterface { } public interface ISomeInterface { } public class ObjectWithOptionalConstructorParameter { private ISomeInterface someInterface; public ISomeInterface SomeInterface { get { return someInterface; } } public ObjectWithOptionalConstructorParameter([OptionalDependency] ISomeInterface someInterface) { this.someInterface = someInterface; } } public class ObjectWithNamedOptionalConstructorParameter : ObjectWithOptionalConstructorParameter { public ObjectWithNamedOptionalConstructorParameter([OptionalDependency("named")] ISomeInterface someInterface) : base(someInterface) { } } public class ObjectWithOptionalProperty { [OptionalDependency] public ISomeInterface SomeInterface { get; set; } } public class ObjectWithNamedOptionalProperty { [OptionalDependency("named")] public ISomeInterface SomeInterface { get; set; } } } } ================================================ FILE: tests/Unity.Tests/Injection/OptionalDependencyFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Injection; namespace Unity.Tests.v5.Injection { /// /// Summary description for OptionalDependencyFixture /// [TestClass] public class OptionalDependencyFixture { public class ObjectWithProperty { public string Property { get; set; } } [TestMethod] // https://github.com/unitycontainer/container/issues/292 public void ByType() { // Setup IUnityContainer Container = new UnityContainer() .RegisterInstance("name"); Container.RegisterType( new InjectionProperty(nameof(ObjectWithProperty.Property), typeof(string))); // Act var result = Container.Resolve(); // Verify Assert.IsNotNull(result); Assert.IsNotNull(result.Property); Assert.IsInstanceOfType(result.Property, typeof(string)); } [TestMethod] public void OptionalParametersSetToNullIfNotRegistered() { IUnityContainer container = new UnityContainer(); OptionalConstParameterClass result = container.Resolve(); Assert.IsNull(result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfInstanceRegistered() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance(input); OptionalConstParameterClass result = container.Resolve(); Assert.AreSame(input, result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfInstanceRegisteredWithName() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance("test", input); NamedOptionalConstParameterClass result = container.Resolve(); Assert.AreSame(input, result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfInstanceRegisteredInParent() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); var input = new TestObject(); parent.RegisterInstance(input); OptionalConstParameterClass result = child.Resolve(); Assert.AreSame(input, result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfInstanceRegisteredInParentWithName() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); var input = new TestObject(); parent.RegisterInstance("test", input); NamedOptionalConstParameterClass result = child.Resolve(); Assert.AreSame(input, result.TestObject); } [TestMethod] public void OptionalParametersNotResolvedIfMoreSpecificTypeRegistered() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance(input); OptionalConstParameterClass result = container.Resolve(); Assert.IsNull(result.TestObject); } [TestMethod] public void OptionalParametersNotResolvedIfMoreSpecificTypeRegisteredWithName() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance("test", input); NamedOptionalConstParameterClass result = container.Resolve(); Assert.IsNull(result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfTypeRegistered() { IUnityContainer container = new UnityContainer(); container.RegisterType(); OptionalConstParameterClass1 result = container.Resolve(); Assert.IsNotNull(result.TestObject); } [TestMethod] public void OptionalParametersResolvedIfTypeRegisteredInParent() { IUnityContainer parent = new UnityContainer(); IUnityContainer child = parent.CreateChildContainer(); parent.RegisterType(); OptionalConstParameterClass1 result = child.Resolve(); Assert.IsNotNull(result.TestObject); } [TestMethod] public void OptionalParametersNullIfTypeRegisteredThrowsAtResolve() { IUnityContainer container = new UnityContainer(); container.RegisterType(); OptionalConstParameterThrowsAtResolve result = container.Resolve(); Assert.IsNull(result.TestObject); } [TestMethod] public void CanConfigureInjectionConstWithOptionalParameters() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance(input); container.RegisterType(new InjectionConstructor(new OptionalParameter())); var result = container.Resolve(); Assert.IsNotNull(result.InternalTestObject); } [TestMethod] public void CanConfigureInjectionPropertyWithOptionalParameters() { IUnityContainer container = new UnityContainer(); var input = new TestObject(); container.RegisterInstance(input); container.RegisterType(new InjectionProperty("InternalTestObject", new OptionalParameter())); var result = container.Resolve(); Assert.IsNotNull(result.InternalTestObject); } } public class OptionalConstParameterClass { public ITestObject TestObject; public OptionalConstParameterClass([OptionalDependency()] ITestObject test) { TestObject = test; } } public class OptionalConstParameterClass1 { public TestObject TestObject; public OptionalConstParameterClass1([OptionalDependency()] TestObject test) { TestObject = test; } } public class NamedOptionalConstParameterClass { public ITestObject TestObject; public NamedOptionalConstParameterClass([OptionalDependency("test")] ITestObject test) { TestObject = test; } } public class OptionalConstParameterThrowsAtResolve { public RandomTestObject TestObject; public OptionalConstParameterThrowsAtResolve([OptionalDependency()] RandomTestObject test) { TestObject = test; } } public class OptionalDependencyTestClass { private ITestObject internalTestObject; public OptionalDependencyTestClass() { } public ITestObject InternalTestObject { get { return internalTestObject; } set { internalTestObject = value; } } public OptionalDependencyTestClass(ITestObject obj) { internalTestObject = obj; } } public interface ITestObject { } public class TestObject : ITestObject { } public class RandomTestObject { public RandomTestObject() { throw (new Exception("Test Exception")); } } } ================================================ FILE: tests/Unity.Tests/Injection/OptionalGenericParameterFixture.cs ================================================ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Injection; using Unity.Tests.v5.Generics; namespace Unity.Tests.v5.Injection { /// /// Tests that use the GenericParameter class to ensure that /// generic object injection works. /// [TestClass] public class OptionalGenericParameterFixture { [TestMethod] public void CanCallConstructorTakingGenericParameterWithResolvableOptional() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new OptionalGenericParameter("T"))); Account a = new Account(); container.RegisterInstance(a); ClassWithOneGenericParameter result = container.Resolve>(); Assert.AreSame(a, result.InjectedValue); } [TestMethod] public void CanCallConstructorTakingGenericParameterWithNonResolvableOptional() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new OptionalGenericParameter("T"))); var result = container.Resolve>(); Assert.IsNull(result.InjectedValue); } [TestMethod] public void CanConfiguredNamedResolutionOfOptionalGenericParameter() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ClassWithOneGenericParameter<>), new InjectionConstructor(new OptionalGenericParameter("T", "named"))); Account a = new Account(); container.RegisterInstance(a); Account named = new Account(); container.RegisterInstance("named", named); ClassWithOneGenericParameter result = container.Resolve>(); Assert.AreSame(named, result.InjectedValue); } // Our various test objects public class ClassWithOneGenericParameter { public T InjectedValue; public ClassWithOneGenericParameter(string s, object o) { } public ClassWithOneGenericParameter(T injectedValue) { InjectedValue = injectedValue; } } } } ================================================ FILE: tests/Unity.Tests/Issues/CodeGenBugFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; namespace Unity.Tests.v5.Issues { /// /// Test for dynamic method creation and the CLR bug. This test will only /// fail if run in a release build! /// [TestClass] public class CodeGenBugFixture { [TestMethod] public void ResolvedTypeHasStaticConstructorCalled() { IUnityContainer container = new UnityContainer(); CodeGenBug result = container.Resolve(); } } public class CodeGenBug { public static readonly object TheStaticObject; static CodeGenBug() { TheStaticObject = new object(); } [InjectionConstructor] public CodeGenBug() : this(-12, TheStaticObject) { } public CodeGenBug(int i, object parameter) { if (parameter == null) { throw new ArgumentNullException("Static constructor was not called"); } } } } ================================================ FILE: tests/Unity.Tests/Issues/CodeplexIssuesFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; using Unity.Injection; using Unity.Lifetime; namespace Unity.Tests.v5.Issues { [TestClass] public class CodeplexIssuesFixture { // http://www.codeplex.com/unity/WorkItem/View.aspx?WorkItemId=1307 [TestMethod] public void InjectionConstructorWorksIfItIsFirstConstructor() { UnityContainer container = new UnityContainer(); container.RegisterType(); IBasicInterface result = container.Resolve(); } // https://www.codeplex.com/Thread/View.aspx?ProjectName=unity&ThreadId=25301 [TestMethod] public void CanUseNonDefaultLifetimeManagerWithOpenGenericRegistration() { IUnityContainer container = new UnityContainer(); container.RegisterType(typeof(ISomeInterface<>), typeof(MyTypeImplementingSomeInterface<>), new ContainerControlledLifetimeManager()); ISomeInterface intSomeInterface = container.Resolve>(); ISomeInterface stringObj1 = container.Resolve>(); ISomeInterface stringObj2 = container.Resolve>(); Assert.AreSame(stringObj1, stringObj2); } // https://www.codeplex.com/Thread/View.aspx?ProjectName=unity&ThreadId=25301 [TestMethod] public void CanOverrideGenericLifetimeManagerWithSpecificOne() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(ISomeInterface<>), typeof(MyTypeImplementingSomeInterface<>), new ContainerControlledLifetimeManager()) .RegisterType(typeof(ISomeInterface), typeof(MyTypeImplementingSomeInterface), new TransientLifetimeManager()); ISomeInterface string1 = container.Resolve>(); ISomeInterface string2 = container.Resolve>(); ISomeInterface double1 = container.Resolve>(); ISomeInterface double2 = container.Resolve>(); Assert.AreSame(string1, string2); Assert.AreNotSame(double1, double2); } // https://www.codeplex.com/Thread/View.aspx?ProjectName=unity&ThreadId=26318 [TestMethod] public void RegisteringInstanceInChildOverridesRegisterTypeInParent() { IUnityContainer container = new UnityContainer() .RegisterType(new ContainerControlledLifetimeManager()); IUnityContainer child = container.CreateChildContainer() .RegisterInstance(new MockBasic()); IBasicInterface result = child.Resolve(); Assert.IsInstanceOfType(result, typeof(MockBasic)); } // http://www.codeplex.com/unity/Thread/View.aspx?ThreadId=30292 [TestMethod] public void CanConfigureGenericDictionaryForInjectionUsingRegisterType() { IUnityContainer container = new UnityContainer() .RegisterType(typeof(IDictionary<,>), typeof(Dictionary<,>), new InjectionConstructor()); IDictionary result = container.Resolve>(); } // http://unity.codeplex.com/WorkItem/View.aspx?WorkItemId=6491 [TestMethod] public void CanResolveTimespan() { var container = new UnityContainer() .RegisterType(new InjectionConstructor(0L)); var expected = new TimeSpan(); var result = container.Resolve(); Assert.AreEqual(expected, result); } // http://unity.codeplex.com/WorkItem/View.aspx?WorkItemId=6997 [TestMethod] public void IsRegisteredReturnsCorrectValue() { IUnityContainer container = new UnityContainer(); container.RegisterType(new InjectionConstructor("Name")); var inst = container.Resolve(); Assert.IsTrue(container.IsRegistered()); } // http://unity.codeplex.com/WorkItem/View.aspx?WorkItemId=3392 [TestMethod] public void ResolveAllResolvesOpenGeneric() { IUnityContainer container = new UnityContainer() .RegisterType(typeof (ISomeInterface<>), typeof (MyTypeImplementingSomeInterface<>), "open") .RegisterType, MyTypeImplementingSomeInterfaceOfString>("string"); var results = container.ResolveAll>().ToList(); Assert.AreEqual(2, results.Count()); CollectionAssert.AreEquivalent( new[] { typeof(MyTypeImplementingSomeInterface), typeof(MyTypeImplementingSomeInterfaceOfString) }, results.Select(o => o.GetType()).ToArray()); } // http://unity.codeplex.com/WorkItem/View.aspx?WorkItemId=6999 [TestMethod] public void ContainerControlledOpenGenericInParentResolvesProperlyInChild() { IUnityContainer parentContainer = new UnityContainer() .RegisterType(typeof (ISomeInterface<>), typeof (MyTypeImplementingSomeInterface<>), new ContainerControlledLifetimeManager()); var childOneObject = parentContainer.CreateChildContainer().Resolve>(); var childTwoObject = parentContainer.CreateChildContainer().Resolve>(); Assert.AreSame(childOneObject, childTwoObject); } public interface IBasicInterface { } public class ClassWithDoubleConstructor : IBasicInterface { private string myString = ""; [InjectionConstructor] public ClassWithDoubleConstructor() : this(string.Empty) { } public ClassWithDoubleConstructor(string myString) { this.myString = myString; } } public interface ISomeInterface { } public class MyTypeImplementingSomeInterface : ISomeInterface { } public class MyTypeImplementingSomeInterfaceOfString : ISomeInterface { } public class MockBasic : IBasicInterface { } public class InnerX64Class { } public class OuterX64Class { public static InnerX64Class SomeProperty { get; set; } } public class MyClass { public string Name { get; set; } public MyClass() { } public MyClass(string name) { Name = name; } } } } ================================================ FILE: tests/Unity.Tests/Issues/GitHub.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Diagnostics; using Unity.Injection; using Unity.Lifetime; using Unity.Resolution; namespace Unity.Tests.v5.Issues { [TestClass] public class GitHubIssues { public interface IFoo { string View { get; } } public class Foo : IFoo { public string View { get; } public Foo(string view) { View = view; } } //[TestMethod] //public void unitycontainer_container_108_without_any_registrations() //{ // var ioc = new UnityContainer(); // var child = ioc.CreateChildContainer(); // var spyStrategy = new TestDoubles.SpyStrategy(); // child.AddExtension(new TestDoubles.SpyExtension(spyStrategy, UnityBuildStage.PreCreation)); // child.Resolve(); // Assert.AreEqual(typeof(EmailService), spyStrategy.BuildKey.Type); //} //[TestMethod] //public void unitycontainer_container_108_with_some_existing_registration() //{ // var ioc = new UnityContainer(); // var child = ioc.CreateChildContainer(); // var spyStrategy = new TestDoubles.SpyStrategy(); // child.AddExtension(new TestDoubles.SpyExtension(spyStrategy, UnityBuildStage.PreCreation)); // child.RegisterType(); // child.Resolve(); // child.Resolve(); // Assert.AreEqual(typeof(EmailService), spyStrategy.BuildKey.Type); //} //[TestMethod] //public void unitycontainer_container_108_with_some_preexisting_registration() //{ // var ioc = new UnityContainer(); // var child = ioc.CreateChildContainer(); // var spyStrategy = new TestDoubles.SpyStrategy(); // child.RegisterType(); // child.AddExtension(new TestDoubles.SpyExtension(spyStrategy, UnityBuildStage.PreCreation)); // child.Resolve(); // child.Resolve(); // Assert.AreEqual(typeof(EmailService), spyStrategy.BuildKey.Type); //} //[TestMethod] //public void unitycontainer_container_108_for_dependencies() //{ // var child = new UnityContainer().CreateChildContainer(); // var spyStrategy = new TestDoubles.SpyStrategy(); // child.AddExtension(new TestDoubles.SpyExtension(spyStrategy, UnityBuildStage.PreCreation)); // child.RegisterType(); // child.Resolve(); // var innerDependencyType = typeof(object); // Assert.AreEqual(innerDependencyType, spyStrategy.BuildKey.Type); //} [TestMethod] public void unitycontainer_container_88() { var str1 = "s1"; var str2 = "s2"; IUnityContainer ioc = new UnityContainer(); ioc.RegisterType(new HierarchicalLifetimeManager()); var ch1 = ioc.CreateChildContainer(); var ch2 = ioc.CreateChildContainer(); var value1 = ch1.Resolve(new ParameterOverride("view", str1).OnType()); var value2 = ch2.Resolve(new ParameterOverride("view", str2).OnType()); Assert.IsNotNull(value1); Assert.IsNotNull(value2); Assert.AreEqual(value1.View, str1); Assert.AreEqual(value2.View, str2); } [TestMethod] public void unitycontainer_container_92() { var ioc = new UnityContainer(); ioc.RegisterFactory( string.Empty, c => { throw new InvalidOperationException(); }, new SingletonLifetimeManager()); Assert.ThrowsException(() => ioc.Resolve()); } [TestMethod] public void unitycontainer_unity_204_1() { var container = new UnityContainer(); container.RegisterType(typeof(ContextFactory), new PerResolveLifetimeManager()); container.RegisterType(); container.RegisterType(); container.RegisterType(); container.RegisterType(); var service1 = container.Resolve(); Assert.AreEqual(service1.Repository1.Factory.Identity, service1.Repository2.Factory.Identity, "case1"); var service2 = container.Resolve(); Assert.AreEqual(service2.Service.Repository1.Factory.Identity, service2.Service.Repository2.Factory.Identity, "case2"); } [TestMethod] public void unitycontainer_unity_204_2() { var container = new UnityContainer(); container.RegisterType(typeof(ContextFactory), new PerResolveLifetimeManager()); container.RegisterType(typeof(Service1), new PerResolveLifetimeManager()); container.RegisterType(typeof(Service2), new PerResolveLifetimeManager()); container.RegisterType(typeof(Repository1), new PerResolveLifetimeManager()); container.RegisterType(typeof(Repository2), new PerResolveLifetimeManager()); var service1 = container.Resolve(); Assert.AreEqual(service1.Repository1.Factory.Identity, service1.Repository2.Factory.Identity, "case1"); var service2 = container.Resolve(); Assert.AreEqual(service2.Service.Repository1.Factory.Identity, service2.Service.Repository2.Factory.Identity, "case2"); } public class ContextFactory { public string Identity { get; set; } = Guid.NewGuid().ToString(); } public class Repository1 { public Repository1(ContextFactory factory) { Factory = factory; } public ContextFactory Factory { get; } } public class Repository2 { public Repository2(ContextFactory factory) { Factory = factory; } public ContextFactory Factory { get; } } public class Service1 { public Service1(Repository1 repository1, Repository2 repository2) { Repository1 = repository1; Repository2 = repository2; } public Repository1 Repository1 { get; } public Repository2 Repository2 { get; } } public class Service2 { public Service2(Service1 service) { Service = service; } public Service1 Service { get; } } [TestMethod] public void unitycontainer_container_82() { // Create root container and register classes in root IUnityContainer rootContainer = new UnityContainer(); rootContainer.RegisterType(new PerResolveLifetimeManager()); rootContainer.RegisterType(); // Create a child container var childContainer = rootContainer.CreateChildContainer(); var main2 = childContainer.Resolve(); Assert.AreEqual(main2, main2.HelperClass.HostClass); } public class BaselineTestType { [Dependency] public TDependency Field; public object Value { get => Field; protected set => throw new NotSupportedException(); } public object Expected => default(TDependency); } [TestMethod] public void unitycontainer_container_293() { var unnamed = 55; var named = 22; var name = "Name"; // Create root container and register classes in root IUnityContainer container = new UnityContainer(); container.RegisterType(typeof(BaselineTestType<>), new InjectionField("Field", new OptionalGenericParameter("TDependency", name))); var instance = container.Resolve>(); Assert.IsNotNull(instance); Assert.AreEqual(0, instance.Field); container.RegisterInstance(unnamed) .RegisterInstance(name, named); instance = container.Resolve>(); Assert.IsNotNull(instance); Assert.AreEqual(named, instance.Field); } } public class MainClass : IHostClass { public MainClass() { Debug.Print("Inside Constructor"); } [Dependency] public HelperClass HelperClass { get; set; } public void DoSomething() { } } public interface IHostClass { void DoSomething(); } public class HelperClass { [Dependency] public IHostClass HostClass { get; set; } } } ================================================ FILE: tests/Unity.Tests/Lifetime/A.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class A { } } ================================================ FILE: tests/Unity.Tests/Lifetime/AA.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class AA : I1, I2 { } } ================================================ FILE: tests/Unity.Tests/Lifetime/ATTest.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class ATTest : ITTest { public string Strtest = "Hello"; } } ================================================ FILE: tests/Unity.Tests/Lifetime/B.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class B { } } ================================================ FILE: tests/Unity.Tests/Lifetime/BB.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class BB : I1, I2 { } } ================================================ FILE: tests/Unity.Tests/Lifetime/HierarchicalLifetimeFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Lifetime; namespace Unity.Tests.v5.Lifetime { [TestClass] public class WhenUsingHierarchicalLifetimeWithChildContainers { private IUnityContainer child1; private IUnityContainer child2; private IUnityContainer parentContainer; [TestInitialize] public void Setup() { parentContainer = new UnityContainer(); child1 = parentContainer.CreateChildContainer(); child2 = parentContainer.CreateChildContainer(); parentContainer.RegisterType(new HierarchicalLifetimeManager()); } [TestMethod] public void ThenResolvingInParentActsLikeContainerControlledLifetime() { var o1 = parentContainer.Resolve(); var o2 = parentContainer.Resolve(); Assert.AreSame(o1, o2); } [TestMethod] public void ThenParentAndChildResolveDifferentInstances() { var o1 = parentContainer.Resolve(); var o2 = child1.Resolve(); Assert.AreNotSame(o1, o2); } [TestMethod] public void ThenChildResolvesTheSameInstance() { var o1 = child1.Resolve(); var o2 = child1.Resolve(); Assert.AreSame(o1, o2); } [TestMethod] public void ThenSiblingContainersResolveDifferentInstances() { var o1 = child1.Resolve(); var o2 = child2.Resolve(); Assert.AreNotSame(o1, o2); } [TestMethod] public void ThenDisposingOfChildContainerDisposesOnlyChildObject() { var o1 = parentContainer.Resolve(); var o2 = child1.Resolve(); child1.Dispose(); Assert.IsFalse(o1.Disposed); Assert.IsTrue(o2.Disposed); } public class TestClass : IDisposable { public bool Disposed { get; private set; } public void Dispose() { Disposed = true; } } } } ================================================ FILE: tests/Unity.Tests/Lifetime/I1.cs ================================================ namespace Unity.Tests.v5.Lifetime { public interface I1 { } } ================================================ FILE: tests/Unity.Tests/Lifetime/I2.cs ================================================ namespace Unity.Tests.v5.Lifetime { public interface I2 { } } ================================================ FILE: tests/Unity.Tests/Lifetime/ITTest.cs ================================================ namespace Unity.Tests.v5.Lifetime { public interface ITTest { } } ================================================ FILE: tests/Unity.Tests/Lifetime/LifetimeFixture.cs ================================================ using Microsoft.Practices.Unity.Tests.TestObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Unity.Lifetime; using Unity.Tests.TestObjects; namespace Unity.Tests.v5.Lifetime { /// /// Summary description for MyTest /// [TestClass] public class LifetimeFixture { /// /// Registering a type twice with SetSingleton method. once with default and second with name. /// [TestMethod] public void CheckSetSingletonDoneTwice() { IUnityContainer uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()) .RegisterType("hello", new ContainerControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreNotSame(obj, obj1); } [TestMethod] public void CheckSingletonWithDependencies() { var uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()); var result1 = uc.Resolve(); var result2 = uc.Resolve(); Assert.IsNotNull(result1); Assert.IsNotNull(result2); Assert.IsNotNull(result1.InnerObject); Assert.IsNotNull(result2.InnerObject); Assert.AreSame(result1, result2); } [TestMethod] public void CheckSingletonAsDependencies() { var uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()); var result1 = uc.Resolve(); var result2 = uc.Resolve(); Assert.IsNotNull(result1); Assert.IsNotNull(result2); Assert.IsNotNull(result1.OneDep); Assert.IsNotNull(result2.OneDep); Assert.AreNotSame(result1, result2); Assert.AreSame(result1.OneDep, result2.OneDep); } /// /// Registering a type twice with SetSingleton method. once with default and second with name. /// [TestMethod] public void CheckRegisterInstanceDoneTwice() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterInstance(aInstance).RegisterInstance("hello", aInstance); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreSame(obj, aInstance); Assert.AreSame(obj1, aInstance); Assert.AreSame(obj, obj1); } /// /// Registering a type as singleton and handling its lifetime. Using SetLifetime method. /// [TestMethod] public void SetLifetimeTwiceWithLifetimeHandle() { IUnityContainer uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()) .RegisterType("hello", new HierarchicalLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreNotSame(obj, obj1); } /// /// SetSingleton class A. Then register instance of class A twice. once by default second by name. /// [TestMethod] public void SetSingletonRegisterInstanceTwice() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterInstance(aInstance).RegisterInstance("hello", aInstance); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreSame(obj, obj1); } /// /// SetLifetime class A. Then use GetOrDefault method to get the instances, once without name, second with name. /// [TestMethod] public void SetLifetimeGetTwice() { IUnityContainer uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreNotSame(obj, obj1); } /// /// SetSingleton class A. Then register instance of class A twice. once by default second by name. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetSingletonRegisterInstanceTwiceSetLifetimeTwice() { IUnityContainer container = new UnityContainer(); A aInstance = new A(); container.RegisterInstance(aInstance); container.RegisterInstance("hello", aInstance); container.RegisterType(new ContainerControlledLifetimeManager()); container.RegisterType("hello1", new ContainerControlledLifetimeManager()); A obj = container.Resolve(); A obj1 = container.Resolve("hello1"); Assert.AreNotSame(obj, obj1); } /// /// SetSingleton class A. Then register instance of class A once by default second by name and /// again register instance by another name with lifetime control as false. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetSingletonNoNameRegisterInstanceDiffNames() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterInstance(aInstance) .RegisterInstance("hello", aInstance) .RegisterInstance("hi", aInstance, new ExternallyControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); A obj2 = uc.Resolve("hi"); Assert.AreSame(obj, obj1); Assert.AreSame(obj1, obj2); } /// /// SetLifetime class A. Then register instance of class A once by default second by name and /// again register instance by another name with lifetime control as false. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetLifetimeNoNameRegisterInstanceDiffNames() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterType(new ContainerControlledLifetimeManager()) .RegisterInstance(aInstance) .RegisterInstance("hello", aInstance) .RegisterInstance("hi", aInstance, new ExternallyControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); A obj2 = uc.Resolve("hi"); Assert.AreSame(obj, obj1); Assert.AreSame(obj1, obj2); } /// /// SetSingleton class A with name. Then register instance of class A once by default second by name and /// again register instance by another name with lifetime control as false. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetSingletonWithNameRegisterInstanceDiffNames() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterType("set", new ContainerControlledLifetimeManager()) .RegisterInstance(aInstance) .RegisterInstance("hello", aInstance) .RegisterInstance("hi", aInstance, new ExternallyControlledLifetimeManager()); A obj = uc.Resolve("set"); A obj1 = uc.Resolve("hello"); A obj2 = uc.Resolve("hi"); Assert.AreNotSame(obj, obj1); Assert.AreSame(obj1, obj2); Assert.AreSame(aInstance, obj1); } /// /// SetLifetime class A with name. Then register instance of class A once by default second by name and /// again register instance by another name with lifetime control as false. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetLifetimeWithNameRegisterInstanceDiffNames() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterType("set", new ContainerControlledLifetimeManager()) .RegisterInstance(aInstance) .RegisterInstance("hello", aInstance) .RegisterInstance("hi", aInstance, new ExternallyControlledLifetimeManager()); A obj = uc.Resolve("set"); A obj1 = uc.Resolve("hello"); A obj2 = uc.Resolve("hi"); Assert.AreNotSame(obj, obj1); Assert.AreSame(aInstance, obj1); Assert.AreSame(obj1, obj2); } /// /// SetSingleton class A. Then register instance of class A once by default second by name and /// lifetime as true. Then again register instance by another name with lifetime control as true /// then register. /// Then SetLifetime once default and then by name. /// [TestMethod] public void SetSingletonClassARegisterInstanceOfAandBWithSameName() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); B bInstance = new B(); uc.RegisterType(new ContainerControlledLifetimeManager()) .RegisterInstance(aInstance) .RegisterInstance("hello", aInstance) .RegisterInstance("hi", bInstance) .RegisterInstance("hello", bInstance, new ExternallyControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); B obj2 = uc.Resolve("hello"); B obj3 = uc.Resolve("hi"); Assert.AreSame(obj, obj1); Assert.AreNotSame(obj, obj2); Assert.AreNotSame(obj1, obj2); Assert.AreSame(obj2, obj3); } /// defect /// SetSingleton class A with name. then register instance of A twice. Once by name, second by default. /// [TestMethod] public void SetSingletonByNameRegisterInstanceOnit() { IUnityContainer uc = new UnityContainer(); A aInstance = new A(); uc.RegisterType("SetA", new ContainerControlledLifetimeManager()) .RegisterInstance(aInstance) .RegisterInstance("hello", aInstance); A obj = uc.Resolve("SetA"); A obj1 = uc.Resolve(); A obj2 = uc.Resolve("hello"); Assert.AreSame(obj1, obj2); Assert.AreNotSame(obj, obj2); } /// /// Use SetLifetime twice, once with parameter, and without parameter /// [TestMethod] public void TestSetLifetime() { IUnityContainer uc = new UnityContainer(); uc.RegisterType(new ContainerControlledLifetimeManager()) .RegisterType("hello", new ContainerControlledLifetimeManager()); A obj = uc.Resolve(); A obj1 = uc.Resolve("hello"); Assert.AreNotSame(obj, obj1); } /// /// Register class A as singleton then use RegisterInstance to register instance /// of class A. /// [TestMethod] public void SetSingletonDefaultNameRegisterInstance() { IUnityContainer uc = new UnityContainer(); var aInstance = new EmailService(); uc.RegisterType((Type)null, typeof(EmailService), null, new ContainerControlledLifetimeManager(), null); uc.RegisterType((Type)null, typeof(EmailService), "SetA", new ContainerControlledLifetimeManager(), null); uc.RegisterInstance(aInstance); uc.RegisterInstance("hello", aInstance); uc.RegisterInstance("hello", aInstance, new ExternallyControlledLifetimeManager()); var obj = uc.Resolve(); var obj1 = uc.Resolve("SetA"); var obj2 = uc.Resolve("hello"); Assert.AreNotSame(obj, obj1); Assert.AreSame(obj, obj2); } /// /// Registering a type in both parent as well as child. Now trying to Resolve from both /// check if same or diff instances are returned. /// [TestMethod] public void RegisterWithParentAndChild() { //create unity container IUnityContainer parentuc = new UnityContainer(); //register type UnityTestClass parentuc.RegisterType(new ContainerControlledLifetimeManager()); UnityTestClass mytestparent = parentuc.Resolve(); mytestparent.Name = "Hello World"; IUnityContainer childuc = parentuc.CreateChildContainer(); childuc.RegisterType(new ContainerControlledLifetimeManager()); UnityTestClass mytestchild = childuc.Resolve(); Assert.AreNotSame(mytestparent.Name, mytestchild.Name); } /// /// Verify WithLifetime managers. When registered using container controlled and freed, even then /// same instance is returned when asked for Resolve. /// [TestMethod] public void UseContainerControlledLifetime() { UnityTestClass obj1 = new UnityTestClass(); obj1.Name = "InstanceObj"; UnityContainer parentuc = new UnityContainer(); parentuc.RegisterType(new ContainerControlledLifetimeManager()); UnityTestClass parentinstance = parentuc.Resolve(); parentinstance.Name = "Hello World Ob1"; parentinstance = null; GC.Collect(); UnityTestClass parentinstance1 = parentuc.Resolve(); Assert.AreSame("Hello World Ob1", parentinstance1.Name); } /// /// The Resolve method returns the object registered with the named mapping, /// or raises an exception if there is no mapping that matches the specified name. Testing this scenario /// Bug ID : 16371 /// [TestMethod] public void TestResolveWithName() { IUnityContainer uc = new UnityContainer(); UnityTestClass obj = uc.Resolve("Hello"); Assert.IsNotNull(obj); } } } ================================================ FILE: tests/Unity.Tests/Lifetime/PerResolveLifetimeFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Lifetime; namespace Unity.Tests.v5.Lifetime { /// /// Summary description for PerResolveLifetimeFixture /// [TestClass] public class PerResolveLifetimeFixture { [TestMethod] public void ContainerCanBeConfiguredForPerBuildSingleton() { var container = new UnityContainer() .RegisterType() .RegisterType(new PerResolveLifetimeManager()); } [TestMethod] public void ViewIsReusedAcrossGraph() { var container = new UnityContainer() .RegisterType() .RegisterType(new PerResolveLifetimeManager()); var view = container.Resolve(); var realPresenter = (MockPresenter)view.Presenter; Assert.AreSame(view, realPresenter.View); } [TestMethod] public void ViewsAreDifferentInDifferentResolveCalls() { var container = new UnityContainer() .RegisterType() .RegisterType(new PerResolveLifetimeManager()); var view1 = container.Resolve(); var view2 = container.Resolve(); Assert.AreNotSame(view1, view2); } [TestMethod] public void PerBuildLifetimeIsHonoredWhenUsingFactory() { var container = new UnityContainer() .RegisterFactory(c => new SomeService(), new PerResolveLifetimeManager()); var rootService = container.Resolve(); Assert.AreSame(rootService.SomeService, rootService.OtherService.SomeService); } // A small object graph to verify per-build configuration works public interface IPresenter { } public class MockPresenter : IPresenter { public IView View { get; set; } public MockPresenter(IView view) { View = view; } } public interface IView { IPresenter Presenter { get; set; } } public class View : IView { [Dependency] public IPresenter Presenter { get; set; } } public class SomeService { } public class SomeOtherService { public SomeService SomeService { get; set; } public SomeOtherService(SomeService someService) { this.SomeService = someService; } } public class AService { public AService(SomeOtherService otherService) { this.OtherService = otherService; } [Dependency] public SomeService SomeService { get; set; } public SomeOtherService OtherService { get; set; } } } } ================================================ FILE: tests/Unity.Tests/Lifetime/UnityTestClass.cs ================================================ namespace Unity.Tests.v5.Lifetime { public class UnityTestClass { private string name = "Hello"; public string Name { get { return name; } set { name = value; } } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/BuildPlanAndChildContainerFixture.cs ================================================ using Microsoft.Practices.Unity.Tests.TestObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Injection; using Unity.Tests.v5.TestObjects; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.ObjectBuilder { /// /// Summary description for BuildPlanAndChildContainerFixture /// [TestClass] public class BuildPlanAndChildContainerFixture { private IUnityContainer parentContainer; private IUnityContainer childContainer; private const int ValueInjectedFromParent = 3; private const int ValueInjectedFromChild = 5; [TestInitialize] public void Setup() { parentContainer = new UnityContainer() .RegisterType(new InjectionConstructor(ValueInjectedFromParent)) .RegisterType(); childContainer = parentContainer.CreateChildContainer() .RegisterType(new InjectionConstructor(ValueInjectedFromChild)); } public class TestObject { public int Value { get; private set; } public TestObject(int value) { Value = value; } } [TestMethod] public void ValuesInjectedAreCorrectWhenResolvingFromParentFirst() { // Be aware ordering is important here - resolve through parent first // to elicit the buggy behavior var fromParent = parentContainer.Resolve(); var fromChild = childContainer.Resolve(); Assert.AreEqual(ValueInjectedFromParent, fromParent.Value); Assert.AreEqual(ValueInjectedFromChild, fromChild.Value); } [TestMethod] public void ChildContainersForUnconfiguredTypesPutConstructorParamResolversInParent() { childContainer.Resolve(); parentContainer.CreateChildContainer().Resolve(); // No exception means we're good. } [TestMethod] public void ChildContainersForUnconfiguredTypesPutPropertyResolversInParent() { childContainer.Resolve(); parentContainer.CreateChildContainer().Resolve(); } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/LifetimeContainerTest.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Threading.Tasks; using Unity.Lifetime; namespace Unity.Tests.v5.ObjectBuilder { [TestClass] public class LifetimeContainerTest { [TestInitialize] public void Setup() { DisposeOrderCounter.ResetCount(); } [TestMethod] public void CanDetermineIfLifetimeContainerContainsObject() { ILifetimeContainer container = new LifetimeContainer(); object obj = new object(); container.Add(obj); Assert.IsTrue(container.Contains(obj)); } [TestMethod] public void CanEnumerateItemsInContainer() { ILifetimeContainer container = new LifetimeContainer(); DisposableObject mdo = new DisposableObject(); container.Add(mdo); int count = 0; bool foundMdo = false; foreach (object obj in container) { count++; if (ReferenceEquals(mdo, obj)) { foundMdo = true; } } Assert.AreEqual(1, count); Assert.IsTrue(foundMdo); } [TestMethod] public void ContainerEnsuresObjectsWontBeCollected() { ILifetimeContainer container = new LifetimeContainer(); DisposableObject mdo = new DisposableObject(); WeakReference wref = new WeakReference(mdo); container.Add(mdo); mdo = null; GC.Collect(); Assert.AreEqual(1, container.Count); mdo = wref.Target as DisposableObject; Assert.IsNotNull(mdo); Assert.IsFalse(mdo.WasDisposed); } [TestMethod] public void DisposingContainerDisposesOwnedObjects() { ILifetimeContainer container = new LifetimeContainer(); DisposableObject mdo = new DisposableObject(); container.Add(mdo); container.Dispose(); Assert.IsTrue(mdo.WasDisposed); } [TestMethod] public void DisposingItemsFromContainerDisposesInReverseOrderAdded() { ILifetimeContainer container = new LifetimeContainer(); DisposeOrderCounter obj1 = new DisposeOrderCounter(); DisposeOrderCounter obj2 = new DisposeOrderCounter(); DisposeOrderCounter obj3 = new DisposeOrderCounter(); container.Add(obj1); container.Add(obj2); container.Add(obj3); container.Dispose(); Assert.AreEqual(1, obj3.DisposePosition); Assert.AreEqual(2, obj2.DisposePosition); Assert.AreEqual(3, obj1.DisposePosition); } [TestMethod] public void RemovingItemsFromContainerDoesNotDisposeThem() { ILifetimeContainer container = new LifetimeContainer(); DisposableObject mdo = new DisposableObject(); container.Add(mdo); container.Remove(mdo); container.Dispose(); Assert.IsFalse(mdo.WasDisposed); } [TestMethod] public void RemovingNonContainedItemDoesNotThrow() { ILifetimeContainer container = new LifetimeContainer(); container.Remove(new object()); } [TestMethod] public void ShouldDisposeAsManyAsPossibleWhenTaskExeptionIsThrown() { var obj1 = new DisposableObject(); var obj3 = new DisposableObject(); try { using (var container = new UnityContainer()) { container.RegisterInstance(nameof(obj1), obj1); var obj2 = Task.Run(async () => await Task.Delay(10000)); container.RegisterInstance(nameof(obj2), obj2); container.RegisterInstance(nameof(obj3), obj3); } Assert.Fail("Exceptions should be thrown"); } catch (InvalidOperationException e) when (e.Message.Contains("A task may only be disposed if it is in a completion state")) { } Assert.IsTrue(obj1.WasDisposed); Assert.IsTrue(obj3.WasDisposed); } [TestMethod] public void ShouldDisposeAsManyAsPossibleWhenSingleExeptionIsThrown() { var obj1 = new DisposableObject(); var obj2 = new DisposableObjectThatThrowsOnDispose(); var obj3 = new DisposableObject(); try { using (var container = new UnityContainer()) { container.RegisterInstance(nameof(obj1), obj1); container.RegisterInstance(nameof(obj2), obj2); container.RegisterInstance(nameof(obj3), obj3); } Assert.Fail("Exceptions should be thrown"); } catch (NotImplementedException) { } Assert.IsTrue(obj1.WasDisposed); Assert.IsTrue(obj2.WasDisposed); Assert.IsTrue(obj3.WasDisposed); } [TestMethod] public void ShouldDisposeAsManyAsPossibleWhenExeptionsAreThrown() { var obj1 = new DisposableObject(); var obj2 = new DisposableObjectThatThrowsOnDispose(); var obj3 = new DisposableObject(); var obj4 = new DisposableObjectThatThrowsOnDispose(); try { using (var container = new UnityContainer()) { container.RegisterInstance(nameof(obj1), obj1); container.RegisterInstance(nameof(obj2), obj2); container.RegisterInstance(nameof(obj3), obj3); container.RegisterInstance(nameof(obj4), obj4); } Assert.Fail("Exceptions should be thrown"); } catch (AggregateException e) { Assert.AreEqual(2, e.InnerExceptions.Count); } Assert.IsTrue(obj1.WasDisposed); Assert.IsTrue(obj2.WasDisposed); Assert.IsTrue(obj3.WasDisposed); Assert.IsTrue(obj4.WasDisposed); } private class DisposableObject : IDisposable { public bool WasDisposed = false; public virtual void Dispose() { WasDisposed = true; } } private class DisposeOrderCounter : IDisposable { private static int count = 0; public int DisposePosition; public static void ResetCount() { count = 0; } public void Dispose() { DisposePosition = ++count; } } private class DisposableObjectThatThrowsOnDispose : DisposableObject { public override void Dispose() { base.Dispose(); throw new NotImplementedException(); } } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/StagedStrategyChainTest.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using Unity.Storage; using Unity.Strategies; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.ObjectBuilder { [TestClass] public class StagedStrategyChainTest { private static void AssertOrder(IEnumerable chain, params FakeStrategy[] strategies) { List strategiesInChain = new List(chain); CollectionAssertExtensions.AreEqual(strategies, strategiesInChain); } [TestMethod] public void InnerStrategiesComeBeforeOuterStrategiesInStrategyChain() { StagedStrategyChain innerChain = new StagedStrategyChain(); StagedStrategyChain outerChain = new StagedStrategyChain(innerChain); FakeStrategy innerStrategy = new FakeStrategy(); FakeStrategy outerStrategy = new FakeStrategy(); innerChain.Add(innerStrategy, FakeStage.Stage1); outerChain.Add(outerStrategy, FakeStage.Stage1); var chain = outerChain.ToArray(); AssertOrder(chain, innerStrategy, outerStrategy); } [TestMethod] public void OrderingAcrossStagesForStrategyChain() { StagedStrategyChain innerChain = new StagedStrategyChain(); StagedStrategyChain outerChain = new StagedStrategyChain(innerChain); FakeStrategy innerStage1 = new FakeStrategy { Name = "innerStage1" }; FakeStrategy innerStage2 = new FakeStrategy { Name = "innerStage2" }; FakeStrategy outerStage1 = new FakeStrategy { Name = "outerStage1" }; FakeStrategy outerStage2 = new FakeStrategy { Name = "outerStage2" }; innerChain.Add(innerStage1, FakeStage.Stage1); innerChain.Add(innerStage2, FakeStage.Stage2); outerChain.Add(outerStage1, FakeStage.Stage1); outerChain.Add(outerStage2, FakeStage.Stage2); var chain = outerChain.ToArray(); AssertOrder(chain, innerStage1, outerStage1, innerStage2, outerStage2); } [TestMethod] public void MultipleChildContainers() { StagedStrategyChain innerChain = new StagedStrategyChain(); StagedStrategyChain outerChain = new StagedStrategyChain(innerChain); StagedStrategyChain superChain = new StagedStrategyChain(outerChain); FakeStrategy innerStrategy = new FakeStrategy { Name = "innerStrategy" }; FakeStrategy outerStrategy = new FakeStrategy { Name = "outerStrategy" }; FakeStrategy superStrategy = new FakeStrategy { Name = "superStrategy" }; innerChain.Add(innerStrategy, FakeStage.Stage1); outerChain.Add(outerStrategy, FakeStage.Stage1); superChain.Add(superStrategy, FakeStage.Stage1); var chain = superChain.ToArray(); AssertOrder(chain, innerStrategy, outerStrategy, superStrategy); } private enum FakeStage { Stage1, Stage2, } private class FakeStrategy : BuilderStrategy { public string Name { get; set; } } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/Utility/ActivatorCreationStrategy.cs ================================================ using System; using Unity.Builder; using Unity.Strategies; namespace Unity.Tests.v5.ObjectBuilder.Utility { internal class ActivatorCreationStrategy : BuilderStrategy { /// /// Called during the chain of responsibility for a build operation. The /// PreBuildUp method is called when the chain is being executed in the /// forward direction. /// /// Context of the build operation. public override void PreBuildUp(ref BuilderContext context) { if (context.Existing == null) { context.Existing = Activator.CreateInstance(context.Type); } } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/Utility/AssertActualExpectedException.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.ObjectBuilder.Utility { internal class AssertActualExpectedException : AssertFailedException { private readonly string actual; private readonly string differencePosition = String.Empty; private readonly string expected; public AssertActualExpectedException(object actual, object expected, string userMessage) : this(actual, expected, userMessage, false) { } public AssertActualExpectedException(object actual, object expected, string userMessage, bool skipPositionCheck) : base(userMessage) { if (!skipPositionCheck) { IEnumerable enumerableActual = actual as IEnumerable; IEnumerable enumerableExpected = expected as IEnumerable; if (enumerableActual != null && enumerableExpected != null) { IEnumerator enumeratorActual = enumerableActual.GetEnumerator(); IEnumerator enumeratorExpected = enumerableExpected.GetEnumerator(); int position = 0; while (true) { bool actualHasNext = enumeratorActual.MoveNext(); bool expectedHasNext = enumeratorExpected.MoveNext(); if (!actualHasNext || !expectedHasNext) { break; } if (!Object.Equals(enumeratorActual.Current, enumeratorExpected.Current)) { break; } position++; } this.differencePosition = "Position: First difference is at position " + position + Environment.NewLine; } } this.actual = actual == null ? null : ConvertToString(actual); this.expected = expected == null ? null : ConvertToString(expected); } public string Actual { get { return this.actual; } } public string Expected { get { return this.expected; } } public override string Message { get { return string.Format("{0}{4}{1}Expected: {2}{4}Actual: {3}", base.Message, this.differencePosition, FormatMultiLine(this.Expected ?? "(null)"), FormatMultiLine(this.Actual ?? "(null)"), Environment.NewLine); } } private static string ConvertToString(object value) { Array valueArray = value as Array; if (valueArray == null) { return value.ToString(); } List valueStrings = new List(); foreach (object valueObject in valueArray) { valueStrings.Add(valueObject.ToString()); } return value.GetType().FullName + " { " + String.Join(", ", valueStrings.ToArray()) + " }"; } private static string FormatMultiLine(string value) { return value.Replace(Environment.NewLine, Environment.NewLine + " "); } } } ================================================ FILE: tests/Unity.Tests/ObjectBuilder/Utility/AssertHelper.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections; using System.Collections.Generic; namespace Unity.Tests.v5.ObjectBuilder.Utility { internal class AssertHelper { public static void Contains(T expected, IEnumerable collection) { Contains(expected, collection, GetComparer(), null); } public static void Contains(T expected, IEnumerable collection, string userMessage) { Contains(expected, collection, GetComparer(), userMessage); } public static void Contains(T expected, IEnumerable collection, IComparer comparer) { Contains(expected, collection, comparer, null); } public static void Contains(T expected, IEnumerable collection, IComparer comparer, string userMessage) { foreach (T item in collection) { if (comparer.Compare(expected, item) == 0) { return; } } throw new AssertFailedException(string.Format("Not found: {0}", expected)); } public static void Contains(string expectedSubString, string actualString, string userMessage) { Contains(expectedSubString, actualString, StringComparison.CurrentCulture, userMessage); } public static void Contains(string expectedSubString, string actualString, StringComparison comparisonType) { Contains(expectedSubString, actualString, comparisonType, null); } public static void Contains(string expectedSubString, string actualString, StringComparison comparisonType, string userMessage) { if (actualString.IndexOf(expectedSubString, comparisonType) < 0) { throw new AssertFailedException(string.Format("Not found: {0}", expectedSubString)); } } public static IComparer GetComparer() { return new AssertComparer(); } public static T IsType(object @object) { IsType(typeof(T), @object, null); return (T)@object; } public static void IsType(Type expectedType, object @object) { IsType(expectedType, @object, null); } public static T IsType(object @object, string userMessage) { IsType(typeof(T), @object, userMessage); return (T)@object; } public static void IsType(Type expectedType, object @object, string userMessage) { if (!expectedType.Equals(@object.GetType())) { throw new AssertActualExpectedException(@object, expectedType, userMessage); } } public static void NotEmpty(IEnumerable collection) { NotEmpty(collection, null); } public static void NotEmpty(IEnumerable collection, string userMessage) { if (collection == null) { throw new ArgumentNullException("collection", "cannot be null"); } #pragma warning disable 168 foreach (object @object in collection) { return; } #pragma warning restore 168 throw new AssertFailedException(userMessage); } private class AssertComparer : IComparer { public int Compare(T x, T y) { // Compare against null if (Object.Equals(x, default(T))) { if (Object.Equals(y, default(T))) { return 0; } return -1; } if (Object.Equals(y, default(T))) { return -1; } // Are they the same type? if (x.GetType() != y.GetType()) { return -1; } // Are they arrays? if (x.GetType().IsArray) { Array arrayX = x as Array; Array arrayY = y as Array; if (arrayX != null && arrayY != null) { if (arrayX.Rank != 1) { throw new ArgumentException("Multi-dimension array comparison is not supported"); } if (arrayX.Length != arrayY.Length) { return -1; } for (int index = 0; index < arrayX.Length; index++) { if (!Object.Equals(arrayX.GetValue(index), arrayY.GetValue(index))) { return -1; } } } return 0; } // Compare with IComparable IComparable comparable1 = x as IComparable; if (comparable1 != null) { return comparable1.CompareTo(y); } // Compare with IComparable IComparable comparable2 = x as IComparable; if (comparable2 != null) { return comparable2.CompareTo(y); } // Compare with IEquatable IEquatable equatable1 = x as IEquatable; if (equatable1 != null && equatable1.Equals(y)) { return 0; } // Last case, rely on Object.AreEquals return Object.Equals(x, y) ? 0 : -1; } } } } ================================================ FILE: tests/Unity.Tests/Override/IForToUndergoeInject.cs ================================================ namespace Unity.Tests.v5.Override { public interface IForToUndergoeInject { IForTypeToInject IForTypeToInject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/IForTypeToInject.cs ================================================ namespace Unity.Tests.v5.Override { public interface IForTypeToInject { int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/IInterfaceForTypesToInject.cs ================================================ namespace Unity.Tests.v5.Override { public interface IInterfaceForTypesToInject { int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/IInterfaceForTypesToInjectForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public interface IInterfaceForTypesToInjectForPropertyOverride { int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/ISubjectTypeToInject.cs ================================================ namespace Unity.Tests.v5.Override { public interface ISubjectTypeToInject { int X { get; set; } string Y { get; set; } IInterfaceForTypesToInject InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/ISubjectTypeToInjectForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public interface ISubjectTypeToInjectForPropertyOverride { int X { get; set; } string Y { get; set; } [Dependency] IInterfaceForTypesToInjectForPropertyOverride InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/MultiThreadedPropertyOverrideFixture.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using System.Threading; using Unity.Injection; using Unity.Lifetime; using Unity.Resolution; namespace Unity.Tests.v5.Override { [TestClass] public class MultiThreadedPropertyOverrideTests { private static IUnityContainer container = new UnityContainer(); private static List defaultInjectedObjectList = new List(); private static List override1InjectedObjectList = new List(); private static List override2InjectedObjectList = new List(); private static int iterationCount = 200; [TestMethod] public void CanOverrideWithPerThreadLifetimeManagerWithDifferentOverridesInDifferenThreads() { var defaultObject = new TypeToInjectForPropertyOverride1(123); container.RegisterType( new PerThreadLifetimeManager(), new InjectionProperty(nameof(SubjectType1ToInjectForPropertyOverride.InjectedObject), defaultObject)); var threadStartDefault = new ThreadStart(ResolveWithDefault); var threadStartOverride1 = new ThreadStart(ResolveWithOverride1); var threadStartOverride2 = new ThreadStart(ResolveWithOverride2); var threadList = new Thread[3]; threadList[0] = new Thread(threadStartDefault); threadList[1] = new Thread(threadStartOverride1); threadList[2] = new Thread(threadStartOverride2); for (int i = 0; i < 3; i++) { threadList[i].Start(); } for (int i = 0; i < 3; i++) { threadList[i].Join(); } var result1 = defaultInjectedObjectList[0]; for (int i = 1; i < iterationCount; i++) { Assert.IsInstanceOfType(defaultInjectedObjectList[i].InjectedObject, typeof(TypeToInjectForPropertyOverride1)); Assert.AreEqual(result1, defaultInjectedObjectList[i]); } var result2 = override1InjectedObjectList[0]; for (int i = 1; i < iterationCount; i++) { Assert.IsInstanceOfType(override1InjectedObjectList[i].InjectedObject, typeof(TypeToInjectForPropertyOverride2)); Assert.AreEqual(result2, override1InjectedObjectList[i]); } var result3 = override2InjectedObjectList[0]; for (int i = 1; i < iterationCount; i++) { Assert.IsInstanceOfType(override2InjectedObjectList[i].InjectedObject, typeof(TypeToInjectForPropertyOverride3)); Assert.AreEqual(result3, override2InjectedObjectList[i]); } } private static void ResolveWithDefault() { var result = container.Resolve(); for (int i = 0; i < iterationCount; i++) { defaultInjectedObjectList.Add(result); } } private static void ResolveWithOverride1() { for (int i = 0; i < iterationCount; i++) { TypeToInjectForPropertyOverride2 overrideObject = new TypeToInjectForPropertyOverride2(222); var result = container.Resolve( new PropertyOverride(nameof(SubjectType1ToInjectForPropertyOverride.InjectedObject), overrideObject)); override1InjectedObjectList.Add(result); } } private static void ResolveWithOverride2() { for (int i = 0; i < iterationCount; i++) { TypeToInjectForPropertyOverride3 overrideObject = new TypeToInjectForPropertyOverride3(333); var result = container.Resolve( new PropertyOverride(nameof(SubjectType1ToInjectForPropertyOverride.InjectedObject), overrideObject)); override2InjectedObjectList.Add(result); } } } } ================================================ FILE: tests/Unity.Tests/Override/MySimpleType.cs ================================================ namespace Unity.Tests.v5.Override { public class MySimpleType { [Dependency] public int X { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/MySimpleTypeForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class MySimpleTypeForPropertyOverride { [Dependency] public int X { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType1ToInject.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType1ToInject : ISubjectTypeToInject { [InjectionConstructor] public SubjectType1ToInject(IInterfaceForTypesToInject injectedObject) { InjectedObject = injectedObject; } public SubjectType1ToInject(int x, string y) { X = x; Y = y; } public int X { get; set; } public string Y { get; set; } public IInterfaceForTypesToInject InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType1ToInjectForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType1ToInjectForPropertyOverride : ISubjectTypeToInjectForPropertyOverride { public int X { get; set; } public string Y { get; set; } [Dependency] public IInterfaceForTypesToInjectForPropertyOverride InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType2ToInject.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType2ToInject : ISubjectTypeToInject { [InjectionConstructor] public SubjectType2ToInject(IInterfaceForTypesToInject injectedObject) { InjectedObject = injectedObject; } public SubjectType2ToInject(int x, string y) { X = x; Y = y; } public int X { get; set; } public string Y { get; set; } public IInterfaceForTypesToInject InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType2ToInjectForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType2ToInjectForPropertyOverride : ISubjectTypeToInjectForPropertyOverride { public int X { get; set; } public string Y { get; set; } public IInterfaceForTypesToInjectForPropertyOverride InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType3ToInject.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType3ToInject : ISubjectTypeToInject { public SubjectType3ToInject(int x, string y) { X = x; Y = y; } public int X { get; set; } public string Y { get; set; } public IInterfaceForTypesToInject InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/SubjectType3ToInjectForPropertyOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class SubjectType3ToInjectForPropertyOverride : ISubjectTypeToInjectForPropertyOverride { public int X { get; set; } public string Y { get; set; } public IInterfaceForTypesToInjectForPropertyOverride InjectedObject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TestTypeInConfig.cs ================================================ namespace Unity.Tests.v5.Override { public class TestTypeInConfig { public TestTypeInConfig(int value) { Value = value; } public TestTypeInConfig() { Value = 1; } public int Value { get; set; } public int X { get; set; } public string Y { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeBasedOverrideFixture.cs ================================================ using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Exceptions; using Unity.Injection; using Unity.Resolution; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.Override { #pragma warning disable 618 /// /// Summary description for TypeBasedOverrideFixture /// [TestClass] public class TypeBasedOverrideFixture { [TestMethod] public void OverrideComparison() { var name = "name"; var instance = this; Assert.AreEqual(new ParameterOverride(name, instance), new ParameterOverride(name, instance)); Assert.AreEqual(new PropertyOverride(name, instance), new PropertyOverride(name, instance)); Assert.AreNotEqual(new ParameterOverride(name, instance), new PropertyOverride(name, instance)); } [TestMethod] public void TypeBasedOverrideWithConstructorExactTypeMatch() { TypeToInject2ForTypeOverride defaultValue = new TypeToInject2ForTypeOverride(111); TypeToInject2ForTypeOverride overrideValue = new TypeToInject2ForTypeOverride(222); ParameterOverride overrideParam = new ParameterOverride("injectedObject", overrideValue); TypeBasedOverride overrideDecorator = new TypeBasedOverride(typeof(TypeToToUndergoeTypeBasedInject2), overrideParam); IUnityContainer container = new UnityContainer(); container.RegisterType(new InjectionConstructor(defaultValue)); var result = container.Resolve(overrideDecorator); Assert.AreEqual(222, result.IForTypeToInject.Value); } [TestMethod] public void TypeBasedOverrideWithBuildUp() { MySimpleType instance = new MySimpleType(); instance.X = 111; PropertyOverride overrideParam = new PropertyOverride("X", 222); TypeBasedOverride overrideDecorator = new TypeBasedOverride(typeof(MySimpleType), overrideParam); UnityContainer container = new UnityContainer(); var result = container.BuildUp(instance, overrideDecorator); Assert.AreEqual(222, result.X); } [TestMethod] public void TypeBasedOverrideInjectsDependentTypeProperty() { ParameterOverride overrideParam = new ParameterOverride("value", 222); PropertyOverride overrideProp = new PropertyOverride("PropertyToInject", "TestOverrideProp"); TypeBasedOverride typeOverrideConstructor = new TypeBasedOverride(typeof(TypeToInject3ForTypeOverride), overrideParam); TypeBasedOverride typeOverrideProp = new TypeBasedOverride(typeof(TypeToInject3ForTypeOverride), overrideProp); IUnityContainer container = new UnityContainer(); container.RegisterType() .RegisterType(new InjectionConstructor(111), new InjectionProperty("PropertyToInject", "DefaultValue")); var result = container.Resolve(typeOverrideConstructor, typeOverrideProp); var overriddenProperty = (TypeToInject3ForTypeOverride)result.IForTypeToInject; Assert.AreEqual(222, overriddenProperty.Value); Assert.AreEqual("TestOverrideProp", overriddenProperty.PropertyToInject); } [TestMethod] public void WhenResolvingAnOpenGenericType() { var container = new UnityContainer(); try { container.Resolve(typeof(List<>)); } catch (ResolutionFailedException ex) { Assert.AreEqual(typeof(ArgumentException), ex.InnerException.GetType()); } } [TestMethod] public void WhenTryingToResolveAPrimitiveType() { Type[] primitive = new Type[] { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float), typeof(double), typeof(bool), typeof(decimal), typeof(string) }; var container = new UnityContainer(); foreach (Type t in primitive) { try { container.Resolve(t); Assert.Fail("Cannot resolve a primitive type"); } catch (ResolutionFailedException ex) { Assert.AreEqual(typeof(InvalidOperationException), ex.InnerException.GetType()); } } } [TestMethod] public void TypeBasedOverrideCollectionInCompositeOverrideInjectionTest() { ParameterOverride overrideParam = new ParameterOverride("value", 222); PropertyOverride overrideProp = new PropertyOverride("PropertyToInject", "TestOverrideProp"); TypeBasedOverride typeOverrideConstructor = new TypeBasedOverride(typeof(TypeToInject3ForTypeOverride), overrideParam); TypeBasedOverride typeOverrideProp = new TypeBasedOverride(typeof(TypeToInject3ForTypeOverride), overrideProp); IUnityContainer container = new UnityContainer(); container.RegisterType().RegisterType(new InjectionConstructor(111), new InjectionProperty("PropertyToInject", "DefaultValue")); var result = container.Resolve(typeOverrideConstructor, typeOverrideProp); TypeToInject3ForTypeOverride overriddenProperty = (TypeToInject3ForTypeOverride)result.IForTypeToInject; Assert.AreEqual(222, overriddenProperty.Value); Assert.AreEqual("TestOverrideProp", overriddenProperty.PropertyToInject); } [TestMethod] public void TypeBasedOverrideNullCheckForResolverOverride() { AssertHelper.ThrowsException(() => new TypeBasedOverride(typeof(TypeToInject2ForTypeOverride), null)); } [TestMethod] public void TypeBasedOverrideInjectsDependentTypeConstructor() { ParameterOverride overrideParam = new ParameterOverride("value", 222); TypeBasedOverride overrideDecorator = new TypeBasedOverride(typeof(TypeToInject2ForTypeOverride), overrideParam); IUnityContainer container = new UnityContainer(); container.RegisterType().RegisterType(new InjectionConstructor(111)); var result = container.Resolve(overrideDecorator); Assert.AreEqual(222, result.IForTypeToInject.Value); } [TestMethod] public void TypeBasedOverrideWithResolveAll() { IForTypeToInject defaultValue = new TypeToInject1ForTypeOverride(111); IForTypeToInject overrideValue = new TypeToInject1ForTypeOverride(222); ParameterOverride overrideParam = new ParameterOverride("injectedObject", overrideValue); TypeBasedOverride overrideDecorator = new TypeBasedOverride(typeof(TypeToUndergoeTypeBasedInject1), overrideParam); IUnityContainer container = new UnityContainer(); container.RegisterType(new InjectionConstructor(defaultValue)).RegisterType("Named", new InjectionConstructor(defaultValue)); var resultList = container.ResolveAll(overrideDecorator); foreach (var result in resultList) { Assert.AreEqual(222, result.IForTypeToInject.Value); } } [TestMethod] public void TypeBasedOverrideConstructorWithNoTypeMatch() { IForTypeToInject defaultValue = new TypeToInject1ForTypeOverride(111); IForTypeToInject overrideValue = new TypeToInject2ForTypeOverride(222); ParameterOverride overrideParam = new ParameterOverride("injectedObject", overrideValue); TypeBasedOverride overrideDecorator = new TypeBasedOverride(typeof(int), overrideParam); IUnityContainer container = new UnityContainer(); container.RegisterType(new InjectionConstructor(defaultValue)); var result = container.Resolve(overrideDecorator); Assert.AreEqual(111, result.IForTypeToInject.Value); } } #pragma warning restore 618 } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject1.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject1 : IInterfaceForTypesToInject { public TypeToInject1(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject1ForTypeOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject1ForTypeOverride : IForTypeToInject { public TypeToInject1ForTypeOverride(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject2.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject2 : IInterfaceForTypesToInject { public TypeToInject2(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject2ForTypeOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject2ForTypeOverride : IForTypeToInject { public TypeToInject2ForTypeOverride(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject3.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject3 : IInterfaceForTypesToInject { public TypeToInject3(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInject3ForTypeOverride.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInject3ForTypeOverride : IForTypeToInject { public TypeToInject3ForTypeOverride(int value) { Value = value; } public int Value { get; set; } public string PropertyToInject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInjectForPropertyOverride1.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInjectForPropertyOverride1 : IInterfaceForTypesToInjectForPropertyOverride { public TypeToInjectForPropertyOverride1(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInjectForPropertyOverride2.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInjectForPropertyOverride2 : IInterfaceForTypesToInjectForPropertyOverride { public TypeToInjectForPropertyOverride2(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToInjectForPropertyOverride3.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToInjectForPropertyOverride3 : IInterfaceForTypesToInjectForPropertyOverride { public TypeToInjectForPropertyOverride3(int value) { Value = value; } public int Value { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToToUndergoeTypeBasedInject2.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToToUndergoeTypeBasedInject2 : IForToUndergoeInject { public TypeToToUndergoeTypeBasedInject2(TypeToInject2ForTypeOverride injectedObject) { IForTypeToInject = injectedObject; } public IForTypeToInject IForTypeToInject { get; set; } public TypeToInject2ForTypeOverride TypeToInject2ForTypeOverride { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToToUndergoeTypeBasedInject3.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToToUndergoeTypeBasedInject3 : IForToUndergoeInject { public IForTypeToInject IForTypeToInject { get; set; } } } ================================================ FILE: tests/Unity.Tests/Override/TypeToUndergoeTypeBasedInject1.cs ================================================ namespace Unity.Tests.v5.Override { public class TypeToUndergoeTypeBasedInject1 : IForToUndergoeInject { public TypeToUndergoeTypeBasedInject1(IForTypeToInject injectedObject) { IForTypeToInject = injectedObject; } public IForTypeToInject IForTypeToInject { get; set; } public TypeToInject1ForTypeOverride TypeToInject1ForTypeOverride { get; set; } } } ================================================ FILE: tests/Unity.Tests/Storage/RegistrationSetTests.cs ================================================ using System; using System.Collections.Generic; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Registration; using Unity.Storage; using Unity.Tests.TestObjects; namespace Unity.Tests.v5.Storage { [TestClass] public class RegistrationSetTests { [TestMethod] public void ShouldHandleCollisions() { Tuple s = MakeCollision(); var registrationSet = new RegistrationSet(); var registration1 = new InternalRegistration(); var registration2 = new InternalRegistration(); var registration3 = new InternalRegistration(); registrationSet.Add(typeof(IService), s.Item1, registration1); Assert.AreEqual(1, registrationSet.Count); registrationSet.Add(typeof(IService), s.Item2, registration2); Assert.AreEqual(2, registrationSet.Count); registrationSet.Add(typeof(IService), s.Item1, registration3); Assert.AreEqual(2, registrationSet.Count); } private static Tuple MakeCollision() { var strings = new Dictionary(); var random = new Random(); var size = 10; var builder = new StringBuilder(size); while (true) { for (var j = 0; j < size; j++) builder.Append((char) random.Next('a', 'z' + 1)); var str = builder.ToString(); var hash = str.GetHashCode(); if (strings.TryGetValue(hash, out var other)) return new Tuple (str, other); strings[hash] = str; builder.Clear(); } } } } ================================================ FILE: tests/Unity.Tests/TestDoubles/DependencyAttribute.cs ================================================ using System; namespace Unity.Tests.v5.TestDoubles { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)] public class DependencyAttribute : Attribute { } } ================================================ FILE: tests/Unity.Tests/TestDoubles/InjectionConstructorAttribute.cs ================================================ using System; namespace Unity.Tests.v5.TestDoubles { [AttributeUsage(AttributeTargets.Constructor)] public class InjectionConstructorAttribute : Attribute { } } ================================================ FILE: tests/Unity.Tests/TestDoubles/InjectionMethodAttribute.cs ================================================ using System; namespace Unity.Tests.v5.TestDoubles { [AttributeUsage(AttributeTargets.Method)] public class InjectionMethodAttribute : Attribute { } } ================================================ FILE: tests/Unity.Tests/TestDoubles/MockContainerExtension.cs ================================================ using Unity.Extension; namespace Unity.Tests.v5.TestDoubles { internal class MockContainerExtension : UnityContainerExtension, IMockConfiguration { private bool initializeWasCalled = false; public bool InitializeWasCalled { get { return this.initializeWasCalled; } } public new ExtensionContext Context { get { return base.Context; } } protected override void Initialize() { this.initializeWasCalled = true; } } internal interface IMockConfiguration : IUnityContainerExtensionConfigurator { } } ================================================ FILE: tests/Unity.Tests/TestDoubles/MockContainerExtensionWithNonDefaultConstructor.cs ================================================ using Unity.Extension; namespace Unity.Tests.v5.TestDoubles { public class ContainerExtensionWithNonDefaultConstructor : UnityContainerExtension { public ContainerExtensionWithNonDefaultConstructor(IUnityContainer container) { } protected override void Initialize() { } } } ================================================ FILE: tests/Unity.Tests/TestDoubles/SpyExtension.cs ================================================ using System; using Unity.Builder; using Unity.Extension; using Unity.Strategies; namespace Unity.Tests.v5.TestDoubles { /// /// A simple extension that puts the supplied strategy into the /// chain at the indicated stage. /// internal class SpyExtension : UnityContainerExtension { private BuilderStrategy strategy; private UnityBuildStage stage; private object policy; private Type policyType; public SpyExtension(BuilderStrategy strategy, UnityBuildStage stage) { this.strategy = strategy; this.stage = stage; } public SpyExtension(BuilderStrategy strategy, UnityBuildStage stage, object policy, Type policyType) { this.strategy = strategy; this.stage = stage; this.policy = policy; this.policyType = policyType; } protected override void Initialize() { Context.Strategies.Add(this.strategy, this.stage); if (this.policy != null) { Context.Policies.Set(null, null, this.policyType, this.policy); } } } } ================================================ FILE: tests/Unity.Tests/TestDoubles/SpyPolicy.cs ================================================ using Unity.Policy; namespace Unity.Tests.v5.TestDoubles { /// /// A sample policy that gets used by the SpyStrategy /// if present to mark execution. /// internal class SpyPolicy { private bool wasSpiedOn; public bool WasSpiedOn { get { return wasSpiedOn; } set { wasSpiedOn = value; } } } } ================================================ FILE: tests/Unity.Tests/TestDoubles/SpyStrategy.cs ================================================ using Unity.Builder; using Unity.Strategies; namespace Unity.Tests.v5.TestDoubles { /// /// A small snoop strategy that lets us check afterwards to /// see if it ran in the strategy chain. /// internal class SpyStrategy : BuilderStrategy { private object existing = null; private bool buildUpWasCalled = false; public override void PreBuildUp(ref BuilderContext context) { this.buildUpWasCalled = true; this.existing = context.Existing; this.UpdateSpyPolicy(ref context); } public override void PostBuildUp(ref BuilderContext context) { this.existing = context.Existing; } public object Existing { get { return this.existing; } } public bool BuildUpWasCalled { get { return this.buildUpWasCalled; } } private void UpdateSpyPolicy(ref BuilderContext context) { SpyPolicy policy = (SpyPolicy)context.Get(null, null, typeof(SpyPolicy)); if (policy != null) { policy.WasSpiedOn = true; } } } } ================================================ FILE: tests/Unity.Tests/TestObjects/DisposableObject.cs ================================================  using System; namespace Microsoft.Practices.Unity.Tests.TestObjects { public class DisposableObject : IDisposable { private bool wasDisposed = false; public bool WasDisposed { get { return wasDisposed; } set { wasDisposed = value; } } public void Dispose() { wasDisposed = true; } } } ================================================ FILE: tests/Unity.Tests/TestObjects/EmailService.cs ================================================ using System; namespace Unity.Tests.TestObjects { // A dummy class to support testing type mapping public class EmailService : IService, IDisposable { public string Id { get; } = Guid.NewGuid().ToString(); public bool Disposed = false; public void Dispose() { Disposed = true; } } // A dummy class to support testing type mapping public class OtherEmailService : IService, IOtherService, IDisposable { public string Id = Guid.NewGuid().ToString(); [InjectionConstructor] public OtherEmailService() { } public OtherEmailService(IUnityContainer container) { } public bool Disposed = false; public void Dispose() { Disposed = true; } } } ================================================ FILE: tests/Unity.Tests/TestObjects/FileLogger.cs ================================================  namespace Microsoft.Practices.ObjectBuilder2.Tests.TestObjects { public class FileLogger { private string logFile; public FileLogger(string logFile) { this.logFile = logFile; } public string LogFile { get { return logFile; } } } } ================================================ FILE: tests/Unity.Tests/TestObjects/IBase.cs ================================================ using System; namespace Unity.Tests.TestObjects { public interface IBase { IService Service { get; set; } } public interface ILazyDependency { Lazy Service { get; set; } } public class Base : IBase { [Dependency] public IService Service { get; set; } } public class LazyDependency : ILazyDependency { [Dependency] public Lazy Service { get; set; } } public class LazyDependencyConstructor { private Lazy service = null; public LazyDependencyConstructor(Lazy s) { service = s; } } } ================================================ FILE: tests/Unity.Tests/TestObjects/IService.cs ================================================ namespace Unity.Tests.TestObjects { // A dummy interface to support testing type mapping public interface IService { } public interface IOtherService { } } ================================================ FILE: tests/Unity.Tests/TestObjects/NullLogger.cs ================================================  namespace Microsoft.Practices.ObjectBuilder2.Tests.TestObjects { /// /// A simple class with only default constructor. A test /// target for the dynamic method build plan. /// public class NullLogger { } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithAmbiguousConstructors.cs ================================================ using System; namespace Unity.Tests.TestObjects { public class ObjectWithAmbiguousConstructors { public const string One = "1"; public const string Two = "2"; public const string Three = "3"; public const string Four = "4"; public const string Five = "5"; public string Signature { get; } public ObjectWithAmbiguousConstructors() { Signature = One; } public ObjectWithAmbiguousConstructors(int first, string second, float third) { Signature = Two; } public ObjectWithAmbiguousConstructors(Type first, Type second, Type third) { Signature = Three; } public ObjectWithAmbiguousConstructors(string first, string second, string third) { Signature = first; } public ObjectWithAmbiguousConstructors(string first, [Dependency(Five)]string second, IUnityContainer third) { Signature = second; } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithAmbiguousMarkedConstructor.cs ================================================  using Unity.Tests.v5.TestDoubles; namespace Unity.Tests.v5.TestObjects { internal class ObjectWithAmbiguousMarkedConstructor { public ObjectWithAmbiguousMarkedConstructor() { } public ObjectWithAmbiguousMarkedConstructor(int first, string second, float third) { } [InjectionConstructor] public ObjectWithAmbiguousMarkedConstructor(string first, string second, int third) { } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithExplicitInterface.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.TestObjects { public interface ISomeCommonProperties { [Dependency] ILogger Logger { get; set; } [Dependency] object SyncObject { get; set; } } public class ObjectWithExplicitInterface : ISomeCommonProperties { private ILogger logger; private object syncObject; private object somethingElse; [Dependency] public object SomethingElse { get { return somethingElse; } set { somethingElse = value; } } [Dependency] ILogger ISomeCommonProperties.Logger { get { return logger; } set { logger = value; } } [Dependency] object ISomeCommonProperties.SyncObject { get { return syncObject; } set { syncObject = value; } } public void ValidateInterface() { Assert.IsNotNull(logger); Assert.IsNotNull(syncObject); } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithInjectionConstructor.cs ================================================ using Unity; namespace Microsoft.Practices.Unity.Tests.TestObjects { public class ObjectWithInjectionConstructor { private object constructorDependency; public ObjectWithInjectionConstructor(object constructorDependency) { this.constructorDependency = constructorDependency; } [InjectionConstructor] public ObjectWithInjectionConstructor(string s) { constructorDependency = s; } public object ConstructorDependency { get { return constructorDependency; } } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithLotsOfDependencies.cs ================================================ using Microsoft.Practices.Unity.Tests.TestObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity.Tests.v5.TestSupport; namespace Unity.Tests.v5.TestObjects { // An object that has constructor, property, and method injection dependencies. public class ObjectWithLotsOfDependencies { private ILogger ctorLogger; private ObjectWithOneDependency dep1; private ObjectWithTwoConstructorDependencies dep2; private ObjectWithTwoProperties dep3; public ObjectWithLotsOfDependencies(ILogger logger, ObjectWithOneDependency dep1) { this.ctorLogger = logger; this.dep1 = dep1; } [Dependency] public ObjectWithTwoConstructorDependencies Dep2 { get { return dep2; } set { dep2 = value; } } [InjectionMethod] public void InjectMe(ObjectWithTwoProperties dep3) { this.dep3 = dep3; } public void Validate() { Assert.IsNotNull(ctorLogger); Assert.IsNotNull(dep1); Assert.IsNotNull(dep2); Assert.IsNotNull(dep3); dep1.Validate(); dep2.Validate(); dep3.Validate(); } public ILogger CtorLogger { get { return ctorLogger; } } public ObjectWithOneDependency Dep1 { get { return dep1; } } public ObjectWithTwoProperties Dep3 { get { return dep3; } } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithMarkedConstructor.cs ================================================  using Unity.Tests.v5.TestDoubles; namespace Unity.Tests.v5.TestObjects { internal class ObjectWithMarkedConstructor { public ObjectWithMarkedConstructor(int notTheInjectionConstructor) { } [InjectionConstructor] public ObjectWithMarkedConstructor(string theInjectionConstructor) { } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithMultipleConstructors.cs ================================================  namespace Unity.Tests.TestObjects { public class ObjectWithMultipleConstructors { public ObjectWithMultipleConstructors() { } public ObjectWithMultipleConstructors(int first, string second) { } public ObjectWithMultipleConstructors(int first) { } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithOneDependency.cs ================================================  using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.Practices.Unity.Tests.TestObjects { public class ObjectWithOneDependency { private object inner; public ObjectWithOneDependency(object inner) { this.inner = inner; } public object InnerObject { get { return inner; } } public void Validate() { Assert.IsNotNull(inner); } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithStaticAndInstanceProperties.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; using Unity; namespace Microsoft.Practices.Unity.Tests.TestObjects { public class ObjectWithStaticAndInstanceProperties { [Dependency] public static object StaticProperty { get; set; } [Dependency] public object InstanceProperty { get; set; } public void Validate() { Assert.IsNull(StaticProperty); Assert.IsNotNull(this.InstanceProperty); } } } ================================================ FILE: tests/Unity.Tests/TestObjects/ObjectWithTwoConstructorDependencies.cs ================================================  using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.Practices.Unity.Tests.TestObjects { // A class that contains another one which has another // constructor dependency. Used to validate recursive // buildup of constructor dependencies. public class ObjectWithTwoConstructorDependencies { private ObjectWithOneDependency oneDep; public ObjectWithTwoConstructorDependencies(ObjectWithOneDependency oneDep) { this.oneDep = oneDep; } public ObjectWithOneDependency OneDep { get { return oneDep; } } public void Validate() { Assert.IsNotNull(oneDep); oneDep.Validate(); } } } ================================================ FILE: tests/Unity.Tests/TestObjects/OptionalLogger.cs ================================================  using Unity.Tests.v5.TestDoubles; namespace Unity.Tests.v5.TestObjects { internal class OptionalLogger { private string logFile; public OptionalLogger([Dependency] string logFile) { this.logFile = logFile; } public string LogFile { get { return logFile; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/AssertExtensions.cs ================================================ using System; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.TestSupport { public static class AssertExtensions { public static void AssertException(Action action) where TException : Exception { AssertException(action, (e) => { }); } public static void AssertException(Action action, Action callback) where TException : Exception { try { action(); Assert.Fail("Expected exception of type {0}", typeof(TException).GetTypeInfo().Name); } catch (TException e) { callback(e); } } public static void IsInstanceOfType(object value, Type expectedType) { Assert.IsNotNull(value, "value should not be null"); Assert.IsNotNull(value, "expectedType should not be null"); Assert.IsTrue(expectedType.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo())); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/AssertHelper.cs ================================================ using System; using System.Globalization; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.TestSupport { /// /// Used because Microsoft.VisualStudio.TestTools.UnitTesting does not support Assert.ThrowsException and /// Microsoft.VisualStudio.TestPlatform.UnitTestFramework does not support ExpectedExceptionAttribute /// public static class AssertHelper { public static T ThrowsException(Action action) where T : Exception { return ThrowsException(action, string.Empty, null); } public static T ThrowsException(Action action, string message) where T : Exception { return ThrowsException(action, message, null); } public static T ThrowsException(Func action) where T : Exception { return ThrowsException(action, string.Empty, null); } public static T ThrowsException(Func action, string message) where T : Exception { return ThrowsException(action, message, null); } public static T ThrowsException(Func action, string message, params object[] parameters) where T : Exception { return ThrowsException(delegate { action.Invoke(); }, message, parameters); } public static T ThrowsException(Action action, string message, params object[] parameters) where T : Exception { string message2 = string.Empty; if (action == null) { throw new ArgumentNullException(nameof(action)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } try { action.Invoke(); } catch (Exception ex) { if (typeof(T) != ex.GetType()) { message2 = string.Format(CultureInfo.CurrentCulture, @"Threw Exception {2}, but exception {1} was expected.{0} Exception Message: {3} Stack Trace : {4}", new object[] { message ?? string.Empty, typeof(T).Name, ex.GetType().Name, ex.Message, ex.StackTrace }); Assert.Fail("Assert.ThrowsException", message2, parameters); } return (T)((object)ex); } message2 = string.Format(CultureInfo.CurrentCulture, "No exception thrown. {1} was expected. {0}", new object[] { message ?? string.Empty, typeof(T).Name }); Assert.Fail("Assert.ThrowsException", message2, parameters); return default(T); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/CollectionAssertExtensions.cs ================================================ using System.Collections; using System.Globalization; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.TestSupport { public static class CollectionAssertExtensions { public static void AreEqual(ICollection expected, ICollection actual) { CollectionAssertExtensions.AreEqual(expected, actual, new DefaultComparer()); } public static void AreEqual(ICollection expected, ICollection actual, IComparer comparer) { CollectionAssertExtensions.AreEqual(expected, actual, comparer, string.Empty); } public static void AreEqual(ICollection expected, ICollection actual, string message) { CollectionAssertExtensions.AreEqual(expected, actual, new DefaultComparer(), message); } public static void AreEqual(ICollection expected, ICollection actual, IComparer comparer, string message) { string reason; if (!CollectionAssertExtensions.AreCollectionsEqual(expected, actual, comparer, out reason)) { throw new AssertFailedException(string.Format(CultureInfo.CurrentCulture, "{0}({1})", message, reason)); } } public static void AreEquivalent(ICollection expected, ICollection actual) { if (expected == actual) { return; } if (expected.Count != actual.Count) { throw new AssertFailedException("collections differ in size"); } var expectedCounts = expected.Cast().GroupBy(e => e).ToDictionary(g => g.Key, g => g.Count()); var actualCounts = actual.Cast().GroupBy(e => e).ToDictionary(g => g.Key, g => g.Count()); foreach (var kvp in expectedCounts) { int actualCount = 0; if (actualCounts.TryGetValue(kvp.Key, out actualCount)) { if (actualCount != kvp.Value) { throw new AssertFailedException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "collections have different count for element {0}", kvp.Key)); } } else { throw new AssertFailedException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "actual does not contain element {0}", kvp.Key)); } } } private static bool AreCollectionsEqual(ICollection expected, ICollection actual, IComparer comparer, out string reason) { if (expected == actual) { reason = null; return true; } if (expected.Count != actual.Count) { reason = "collections differ in size"; return false; } var expectedEnum = expected.GetEnumerator(); var actualEnum = actual.GetEnumerator(); for (int i = 0; expectedEnum.MoveNext() && actualEnum.MoveNext(); i++) { if (comparer.Compare(expectedEnum.Current, actualEnum.Current) != 0) { reason = string.Format(CultureInfo.CurrentCulture, "collections differ at index {0}", i); return false; } } reason = null; return true; } private class DefaultComparer : IComparer { public int Compare(object x, object y) { return x.Equals(y) ? 0 : -1; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/EnumerableAssertionExtensions.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.TestSupport { public static class EnumerableAssertionExtensions { public static void AssertContainsExactly(this IEnumerable items, params TItem[] expected) { CollectionAssertExtensions.AreEqual(expected, items.ToArray()); } public static void AssertContainsInAnyOrder(this IEnumerable items, params TItem[] expected) { CollectionAssertExtensions.AreEquivalent(expected, items.ToArray()); } public static void AssertTrueForAll(this IEnumerable items, Func predicate) { Assert.IsTrue(items.All(predicate)); } public static void AssertTrueForAny(this IEnumerable items, Func predicate) { Assert.IsTrue(items.Any(predicate)); } public static void AssertFalseForAll(this IEnumerable items, Func predicate) { Assert.IsFalse(items.All(predicate)); } public static void AssertFalseForAny(this IEnumerable items, Func predicate) { Assert.IsFalse(items.Any(predicate)); } public static void AssertHasItems(this IEnumerable items) { Assert.IsTrue(items.Any()); } public static void AssertHasNoItems(this IEnumerable items) { Assert.IsFalse(items.Any()); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/EnumerableExtensions.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Unity.Tests.v5.TestSupport { /// /// The almost inevitable collection of extra helper methods on /// to augment the rich set of what /// LINQ already gives us. /// public static class EnumerableExtensions { /// /// Execute the provided on every item in . /// /// Type of the items stored in /// Sequence of items to process. /// Code to run over each item. public static void ForEach(this IEnumerable sequence, Action action) { Guard.ArgumentNotNull(sequence, "sequence"); foreach (var item in sequence) { action(item); } } /// /// Create a single string from a sequence of items, separated by the provided , /// and with the conversion to string done by the given . /// /// This method does basically the same thing as , /// but will work on any sequence of items, not just arrays. /// Type of items in the sequence. /// Sequence of items to convert. /// Separator to place between the items in the string. /// The conversion function to change TItem -> string. /// The resulting string. public static string JoinStrings(this IEnumerable sequence, string separator, Func converter) { var sb = new StringBuilder(); sequence.Aggregate(sb, (builder, item) => { if (builder.Length > 0) { builder.Append(separator); } builder.Append(converter(item)); return builder; }); return sb.ToString(); } /// /// Create a single string from a sequence of items, separated by the provided , /// and with the conversion to string done by the item's method. /// /// This method does basically the same thing as , /// but will work on any sequence of items, not just arrays. /// Type of items in the sequence. /// Sequence of items to convert. /// Separator to place between the items in the string. /// The resulting string. public static string JoinStrings(this IEnumerable sequence, string separator) { return sequence.JoinStrings(separator, item => item.ToString()); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/ExtensibilityTestExtension.cs ================================================  using Unity.Extension; namespace Unity.Tests.v5.TestSupport { public interface IConfigOne : IUnityContainerExtensionConfigurator { IConfigOne SetText(string text); } public interface IConfigTwo : IUnityContainerExtensionConfigurator { IConfigTwo SetMessage(string text); } public class ExtensibilityTestExtension : UnityContainerExtension, IConfigOne, IConfigTwo { public string ConfigOneText { get; private set; } public string ConfigTwoText { get; private set; } protected override void Initialize() { } public IConfigOne SetText(string text) { this.ConfigOneText = text; return this; } public IConfigTwo SetMessage(string text) { this.ConfigTwoText = text; return this; } } } ================================================ FILE: tests/Unity.Tests/TestSupport/Guard.cs ================================================ using System; using System.Globalization; using System.Reflection; namespace Unity.Tests.v5.TestSupport { /// /// A static helper class that includes various parameter checking routines. /// internal static partial class Guard { /// /// Throws if the given argument is null. /// /// if tested value if null. /// Argument value to test. /// Name of the argument being tested. public static void ArgumentNotNull(object argumentValue, string argumentName) { if (argumentValue == null) { throw new ArgumentNullException(argumentName); } } /// /// Throws an exception if the tested string argument is null or the empty string. /// /// Thrown if string value is null. /// Thrown if the string is empty /// Argument value to check. /// Name of argument being checked. public static void ArgumentNotNullOrEmpty(string argumentValue, string argumentName) { if (argumentValue == null) { throw new ArgumentNullException(argumentName); } if (argumentValue.Length == 0) { throw new ArgumentException("The provided string argument must not be empty.", argumentName); } } /// /// Verifies that an argument type is assignable from the provided type (meaning /// interfaces are implemented, or classes exist in the base class hierarchy). /// /// The argument type that will be assigned to. /// The type of the value being assigned. /// Argument name. public static void TypeIsAssignable(Type assignmentTargetType, Type assignmentValueType, string argumentName) { if (assignmentTargetType == null) { throw new ArgumentNullException("assignmentTargetType"); } if (assignmentValueType == null) { throw new ArgumentNullException("assignmentValueType"); } if (!assignmentTargetType.GetTypeInfo().IsAssignableFrom(assignmentValueType.GetTypeInfo())) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, "The type {1} cannot be assigned to variables of type {0}.", assignmentTargetType, assignmentValueType), argumentName); } } /// /// Verifies that an argument instance is assignable from the provided type (meaning /// interfaces are implemented, or classes exist in the base class hierarchy, or instance can be /// assigned through a runtime wrapper, as is the case for COM Objects). /// /// The argument type that will be assigned to. /// The instance that will be assigned. /// Argument name. public static void InstanceIsAssignable(Type assignmentTargetType, object assignmentInstance, string argumentName) { if (assignmentTargetType == null) { throw new ArgumentNullException("assignmentTargetType"); } if (assignmentInstance == null) { throw new ArgumentNullException("assignmentInstance"); } if (!assignmentTargetType.GetTypeInfo().IsAssignableFrom(assignmentInstance.GetType().GetTypeInfo())) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, "The type {1} cannot be assigned to variables of type {0}.", assignmentTargetType, GetTypeName(assignmentInstance)), argumentName); } } private static string GetTypeName(object assignmentInstance) { string assignmentInstanceType; try { assignmentInstanceType = assignmentInstance.GetType().FullName; } catch (Exception) { assignmentInstanceType = ""; } return assignmentInstanceType; } } } ================================================ FILE: tests/Unity.Tests/TestSupport/IAdditionalInterface.cs ================================================ namespace Unity.Tests.v5.TestSupport { public interface IAdditionalInterface { int DoNothing(); } } ================================================ FILE: tests/Unity.Tests/TestSupport/ILogger.cs ================================================  namespace Unity.Tests.v5.TestSupport { public interface ILogger { } } ================================================ FILE: tests/Unity.Tests/TestSupport/MockContainerExtension.cs ================================================  using Unity.Extension; namespace Unity.Tests.v5.TestSupport { public class MockContainerExtension : UnityContainerExtension, IMockConfiguration { private bool initializeWasCalled = false; public bool InitializeWasCalled { get { return this.initializeWasCalled; } } public new ExtensionContext Context { get { return base.Context; } } protected override void Initialize() { this.initializeWasCalled = true; } } public interface IMockConfiguration : IUnityContainerExtensionConfigurator { } } ================================================ FILE: tests/Unity.Tests/TestSupport/MockDatabase.cs ================================================  namespace Unity.Tests.v5.TestSupport { public class MockDatabase { private string connectionString; private bool defaultConstructorCalled; public MockDatabase() { defaultConstructorCalled = true; } public MockDatabase(string connectionString) { this.connectionString = connectionString; } public static MockDatabase Create(string connectionString) { return new MockDatabase(connectionString); } public string ConnectionString { get { return connectionString; } } public bool DefaultConstructorCalled { get { return defaultConstructorCalled; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/MockLogger.cs ================================================  namespace Unity.Tests.v5.TestSupport { public class MockLogger : ILogger { } } ================================================ FILE: tests/Unity.Tests/TestSupport/NegativeTypeConverter.cs ================================================ using System; using System.ComponentModel; using System.Globalization; namespace Unity.Tests.v5.TestSupport { /// /// A faked up type converter that converts integers, then returns the /// negative value. Used to test the instances registration in config. /// internal class NegativeTypeConverter : TypeConverter { /// /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. /// /// /// /// true if this converter can perform the conversion; otherwise, false. /// /// /// An that provides a format context. /// A that represents the type you want to convert from. public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string); } /// /// Returns whether this converter can convert the object to the specified type, using the specified context. /// /// /// /// true if this converter can perform the conversion; otherwise, false. /// /// /// An that provides a format context. /// A that represents the type you want to convert to. public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string); } /// /// Converts the given object to the type of this converter, using the specified context and culture information. /// /// /// /// An that represents the converted value. /// /// /// The to use as the current culture. /// An that provides a format context. /// The to convert. /// The conversion cannot be performed. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { int result = int.Parse(value.ToString()); return -result; } return base.ConvertFrom(context, culture, value); } /// /// Converts the given value object to the specified type, using the specified context and culture information. /// /// /// /// An that represents the converted value. /// /// /// A . If null is passed, the current culture is assumed. /// An that provides a format context. /// The to convert the value parameter to. /// The to convert. /// The conversion cannot be performed. /// The destinationType parameter is null. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { int intValue = (int)value; return (-intValue).ToString(); } return base.ConvertTo(context, culture, value, destinationType); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/ObjectUsingLogger.cs ================================================ namespace Unity.Tests.v5.TestSupport { public class ObjectUsingLogger { private ILogger logger; [Dependency] public ILogger Logger { get { return logger; } set { logger = value; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/ObjectWithOneConstructorDependency.cs ================================================ namespace Unity.Tests.v5.TestSupport { public class ObjectWithOneConstructorDependency { private ILogger logger; public ObjectWithOneConstructorDependency(ILogger logger) { this.logger = logger; } public ILogger Logger { get { return logger; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/ObjectWithTwoConstructorParameters.cs ================================================ namespace Unity.Tests.v5.TestSupport { public class ObjectWithTwoConstructorParameters { private string connectionString; private ILogger logger; public ObjectWithTwoConstructorParameters(string connectionString, ILogger logger) { this.connectionString = connectionString; this.logger = logger; } public string ConnectionString { get { return connectionString; } } public ILogger Logger { get { return logger; } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/ObjectWithTwoProperties.cs ================================================ using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Unity.Tests.v5.TestSupport { public class ObjectWithTwoProperties { private object obj1; private object obj2; [Dependency] public object Obj1 { get { return obj1; } set { obj1 = value; } } [Dependency] public object Obj2 { get { return obj2; } set { obj2 = value; } } public void Validate() { Assert.IsNotNull(obj1); Assert.IsNotNull(obj2); Assert.AreNotSame(obj1, obj2); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/Pair.cs ================================================  namespace Unity.Tests.v5.TestSupport { /// /// A helper class that encapsulates two different /// data items together into a a single item. /// public class Pair { private TFirst first; private TSecond second; /// /// Create a new containing /// the two values give. /// /// First value /// Second value public Pair(TFirst first, TSecond second) { this.first = first; this.second = second; } /// /// The first value of the pair. /// public TFirst First { get { return first; } } /// /// The second value of the pair. /// public TSecond Second { get { return second; } } } /// /// Container for a Pair helper method. /// public static class Pair { /// /// A helper factory method that lets users take advantage of type inference. /// /// Type of first value. /// Type of second value. /// First value. /// Second value. /// A new instance. public static Pair Make(TFirstParameter first, TSecondParameter second) { return new Pair(first, second); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/Sequence.cs ================================================ using System.Collections.Generic; namespace Unity.Tests.v5.TestSupport { /// /// A series of helper methods to deal with sequences - /// objects that implement . /// public static class Sequence { /// /// A function that turns an arbitrary parameter list into an /// . /// /// Type of arguments. /// The items to put into the collection. /// An array that contains the values of the . public static T[] Collect(params T[] arguments) { return arguments; } /// /// Given two sequences, return a new sequence containing the corresponding values /// from each one. /// /// Type of first sequence. /// Type of second sequence. /// First sequence of items. /// Second sequence of items. /// New sequence of pairs. This sequence ends when the shorter of sequence1 and sequence2 does. public static IEnumerable> Zip(IEnumerable sequence1, IEnumerable sequence2) { var enum1 = sequence1.GetEnumerator(); var enum2 = sequence2.GetEnumerator(); while (enum1.MoveNext()) { if (enum2.MoveNext()) { yield return new Pair(enum1.Current, enum2.Current); } else { yield break; } } } } } ================================================ FILE: tests/Unity.Tests/TestSupport/SessionLifetimeManager.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using Unity.Lifetime; namespace Unity.Tests.v5.TestSupport { [TypeConverter(typeof(SessionKeyTypeConverter))] public class SessionLifetimeManager : LifetimeManager { private readonly string sessionKey; public static string LastUsedSessionKey; public SessionLifetimeManager(string sessionKey) { this.sessionKey = sessionKey; } public string SessionKey { get { return this.sessionKey; } } public override object GetValue(ILifetimeContainer container = null) { LastUsedSessionKey = this.sessionKey; return null; } public override void SetValue(object newValue, ILifetimeContainer container = null) { } public override void RemoveValue(ILifetimeContainer container = null) { } protected override LifetimeManager OnCreateLifetimeManager() { throw new NotImplementedException(); } } public class SessionKeyTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType.GetType() == typeof(string); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string); } public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { return new SessionLifetimeManager((string)value); } public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { return ((SessionLifetimeManager)value).SessionKey; } } public class ReversedSessionKeyTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string); } public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { string key = Reverse((string)value); return new SessionLifetimeManager(key); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { string key = Reverse(((SessionLifetimeManager)value).SessionKey); return key; } private static string Reverse(IEnumerable s) { var chars = new Stack(s); return chars.JoinStrings(String.Empty); } } } ================================================ FILE: tests/Unity.Tests/TestSupport/SpecialLogger.cs ================================================ namespace Unity.Tests.v5.TestSupport { public class SpecialLogger : ILogger { } } ================================================ FILE: tests/Unity.Tests/TestSupport/TypeReflectionExtensions.cs ================================================ using System; using System.Linq; using System.Reflection; namespace Unity.Tests.v5.TestSupport { public static class TypeReflectionExtensions { public static ConstructorInfo GetMatchingConstructor(this Type type, Type[] constructorParamTypes) { return type.GetTypeInfo().DeclaredConstructors .Where(c => c.GetParameters().Select(p => p.ParameterType).SequenceEqual(constructorParamTypes)) .FirstOrDefault(); } } } ================================================ FILE: tests/Unity.Tests/Unity.Tests.csproj ================================================  net48 false false