├── .github └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── tasks.json ├── LICENSE ├── README.md ├── api └── index.md ├── appveyor.yml ├── articles ├── application.md ├── changelog.md ├── design.md ├── features.md ├── history.md ├── installation.md ├── introduction.md ├── quickstart.md └── toc.yml ├── docfx.json ├── gulpfile.js ├── images ├── favicon.png ├── logo.svg └── resolver-override.png ├── index.md ├── package.json ├── serve.cmd ├── specs ├── constructor.md ├── field.md ├── hierarchy.md ├── method.md ├── property.md ├── specification.md ├── summary.md ├── toc.yml └── workflow.md ├── src └── Documentation.sln ├── toc.yml └── tutorials ├── Annotation ├── annotation.md ├── constructor.md ├── field.md ├── method.md ├── parameter.md ├── property.md └── toc.yml ├── Composition ├── BuildUp │ ├── buildup.md │ └── toc.yml ├── Generics │ ├── deferred.md │ ├── generics.md │ ├── lazy.md │ ├── metadata.md │ └── toc.yml ├── Mapping │ ├── generic.md │ ├── implementation.md │ ├── mapping.md │ └── toc.yml ├── Overrides │ ├── dependency.md │ ├── field.md │ ├── override.md │ ├── parameter.md │ ├── property.md │ └── toc.yml ├── Resolution │ ├── resolution.md │ ├── toc.yml │ └── type.md ├── Selection │ ├── constructor.md │ ├── selection.md │ └── toc.yml ├── collections.md ├── composition.md └── toc.yml ├── Extensions ├── activation.md ├── compilation.md ├── diagnostic.md ├── extensions.md ├── legacy.md └── toc.yml ├── definitions.md ├── hierarchies.md ├── lifetime ├── container.md ├── container_transient.md ├── disposal.md ├── external.md ├── hierarchical.md ├── lifetime.md ├── managers.md ├── resolve.md ├── singleton.md ├── thread.md ├── toc.yml └── transient.md ├── registration ├── Type │ ├── Constructor │ │ ├── annotation.md │ │ ├── automatic.md │ │ ├── constructor.md │ │ ├── param_count.md │ │ ├── param_none.md │ │ ├── param_types.md │ │ ├── param_values.md │ │ └── toc.yml │ ├── Injection │ │ ├── default.md │ │ ├── injected.md │ │ ├── injection.md │ │ ├── resolved.md │ │ └── toc.yml │ ├── field.md │ ├── method.md │ ├── parameter.md │ ├── property.md │ ├── registration.md │ └── toc.yml ├── factory.md ├── instance.md ├── metadata.md ├── registration.md └── toc.yml └── toc.yml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [ENikS] 2 | open_collective: unity-container 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | /**/.vs/ 10 | /api/*.yml 11 | .manifest 12 | /unitycontainer.github.io 13 | /node_modules 14 | /package-lock.json 15 | /yarn.lock 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/Abstractions"] 2 | path = src/Abstractions 3 | url = https://github.com/unitycontainer/abstractions.git 4 | [submodule "src/Container"] 5 | path = src/Container 6 | url = https://github.com/unitycontainer/container.git 7 | [submodule "src/SpecificationTests"] 8 | path = src/SpecificationTests 9 | url = https://github.com/unitycontainer/specification-tests.git 10 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Gulp", 11 | "program": "${file}" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "build", 8 | "command": "docfx docfx.json", 9 | "type": "shell", 10 | "group": "build", 11 | "presentation": { 12 | "reveal": "silent" 13 | }, 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "serve", 18 | "command": "browser-sync unitycontainer.github.io -w", 19 | "type": "shell", 20 | "group": "build", 21 | "presentation": { 22 | "reveal": "silent" 23 | }, 24 | "problemMatcher": "$msCompile" 25 | } 26 | 27 | ] 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 .NET Foundation and Contributors 190 | All Rights Reserved 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/50hjsoi3gqu1becr?svg=true)](https://ci.appveyor.com/project/unitycontainer/documentation) 2 | 3 | # Unity Documentation 4 | 5 | This repository hosts source files and instructions for building Unity documentation site: https://unitycontainer.github.io 6 | 7 | If you'd like to contribute documentation or report an issue please do it in [this repository](https://github.com/unitycontainer/documentation). -------------------------------------------------------------------------------- /api/index.md: -------------------------------------------------------------------------------- 1 | # API Documentation Section 2 | 3 | This documentation is generated by DocFX 4 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2017 2 | 3 | environment: 4 | access_token: 5 | secure: JMhbKA4Bre9ZaQ8No630DmjhmLGfRY1uaNBjqvKCewFK0Jn2BBva3TzHebfUwt5H 6 | 7 | init: 8 | - git config --global credential.helper store 9 | - ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n" 10 | - git config --global user.email "unity@eniks.com" 11 | - git config --global user.name "Build Job" 12 | 13 | install: 14 | - git submodule --quiet update --init --recursive 15 | - git clone https://github.com/unitycontainer/unitycontainer.github.io.git unitycontainer.github.io 16 | - cmd: nuget restore src\Abstractions\src\Unity.Abstractions.csproj -Verbosity quiet 17 | - cmd: nuget restore src\Container\src\Unity.Container.csproj -Verbosity quiet 18 | - cmd: nuget install docfx.console -ExcludeVersion 19 | 20 | before_build: 21 | - ps: | 22 | if(-Not $env:APPVEYOR_PULL_REQUEST_TITLE) 23 | { 24 | # This hack is required at the moment 25 | $VisualStudioVersion = "15.0"; 26 | $DotnetSDKVersion = "2.0.0"; 27 | 28 | # Get dotnet paths 29 | $MSBuildExtensionsPath = "C:\Program Files\dotnet\sdk\" + $DotnetSDKVersion; 30 | $MSBuildSDKsPath = $MSBuildExtensionsPath + "\SDKs"; 31 | 32 | # Get Visual Studio install path 33 | $VSINSTALLDIR = $(Get-ItemProperty "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7").$VisualStudioVersion; 34 | 35 | # Add Visual Studio environment variables 36 | $env:VisualStudioVersion = $VisualStudioVersion; 37 | $env:VSINSTALLDIR = $VSINSTALLDIR; 38 | 39 | # Add dotnet environment variables 40 | $env:MSBuildExtensionsPath = $MSBuildExtensionsPath; 41 | $env:MSBuildSDKsPath = $MSBuildSDKsPath; 42 | 43 | # Build our docs 44 | Write-Host "`n[Build our docs]" -ForegroundColor Green 45 | } 46 | 47 | build_script: 48 | - cmd: .\docfx.console\tools\docfx docfx.json 49 | 50 | on_success: 51 | - cmd: cd unitycontainer.github.io 52 | - git config --global credential.helper store 53 | - git config --global core.autocrlf false 54 | - ps: Add-Content "$HOME\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n" 55 | - git add -A 56 | - git commit --all --message="%APPVEYOR_BUILD_VERSION%" 57 | - git push --force origin master 58 | -------------------------------------------------------------------------------- /articles/application.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Application.Design 3 | --- 4 | 5 | # Application Design Concepts with Unity 6 | 7 | Features such as inversion of control, dependency injection, interception, factory, and lifetime provide several major advantages when building applications that consist of many individual classes and components. Designing applications that conform to these patterns can provide numerous benefits: 8 | 9 | * Decoupling service providers from service consumers 10 | * Runtime as well as design time configuration of services and dependencies 11 | * Ability to substitute one component for another. 12 | * Centralization and abstraction of crosscutting concerns (logging, authentication, caching, and etc). 13 | * Advanced lifetime management of components and services. 14 | * Simplified testability for individual components and sections of the application. 15 | * Simplified overall design, with faster and less error-prone development. 16 | * Improved reusability of components within other applications. 17 | 18 | Unity provides a comprehensive dependency injection and interception platform, and is easy to incorporate into your applications. However, it does change the way that you design these applications. The following sections of this topic describe areas where dependency injection is useful: 19 | 20 | * Pluggable Architectures 21 | * Managing Crosscutting Concerns 22 | * Service and Component Location 23 | * Policy Injection through Interception 24 | 25 | ## Pluggable Architectures 26 | 27 | By designing applications to use a pluggable architecture, developers and users can add and modify the functionality of an application without changing the core code or processes. ASP.NET is an example of a pluggable architecture, where you can add and remove providers for features such as authentication, caching, and session management. Unity also facilitates a pluggable architecture that allows you to substitute the container for one of your own design and add extensions through the container extensions architecture. 28 | 29 | By using dependency injection mechanisms, such as Unity container, developers can map different components that implement a specific interface (such as a provider interface) or that inherit from a specific base class to the appropriate concrete implementations. Developers can then obtain a reference to the appropriate provider component at run time, without having to specify exactly which implementation of the component is required. The following sections of this topic, Managing Crosscutting Concerns and Service and Component Location, show how you can use dependency injection to create instances of a specific class based on a request for a more general class (such as an interface or base class definition). 30 | 31 | In addition, the providers may require instances of other components. For example, a caching provider may need to use the services of a cryptography component or service. When components require the services of other components, you can use dependency injection to automatically instantiate and inject instances of these components into a component, based on either configuration settings in the container or on code within the application. 32 | 33 | For more information about how you can use dependency injection in this way, see [Using Injection Attributes](http://unitycontainer.org/tutorials/Annotation/annotation.html#using-injection-attributes). 34 | 35 | ## Managing Crosscutting Concerns 36 | 37 | The features and tasks implemented in applications are often referred to as concerns. The tasks specific to the application are core concerns. The tasks that are common across many parts of the application, and even across different applications, are crosscutting concerns. Most large applications require services such as logging, caching, validation, and authorization, and these are crosscutting concerns. 38 | 39 | The simplest way to centralize these features is to build separate components that implement each of the required features, and then use these components wherever the management of that concern is required—in one or more applications. By using dependency injection mechanisms, such as a Unity container, developers can register components that implement crosscutting concerns and then obtain a reference to the component at run time, without having to specify exactly which implementation of the component is required. 40 | 41 | For example, if you have a component named FileLogger that performs logging tasks, your application can instantiate this component using the new operator, as shown in the following code. 42 | 43 | ```C# 44 | FileLogger myLogger = new FileLogger(); 45 | ``` 46 | 47 | If you then want to change the application to use the new component, FastFileLogger, you must change the application code. However, if you have an interface ILogger that all implementations of the logging component uses, you might instead write the code like the following. 48 | 49 | ```C# 50 | ILogger myLogger = new FileLogger(); 51 | ``` 52 | 53 | However, this does not solve the problem because you still must find everywhere in the code where you used new() to create an instance of the specific class. Instead, you can use a dependency injection mechanism to map the ILogger interface to a specific concrete instance of the logging component, or even to multiple implementations, so that the application can specify which one it requires. The following code uses Unity to register a mapping for both a default type of logging component and a named type with the ILogger interface. Alternatively, you can specify these mappings using the Unity configuration file. 54 | 55 | ```C# 56 | // Create container and register types 57 | IUnityContainer myContainer = new UnityContainer(); 58 | myContainer.RegisterType(); // default instance 59 | myContainer.RegisterType("FastLogger"); 60 | ``` 61 | 62 | The application can then obtain a reference to the default logging component using the following code. 63 | 64 | ```C# 65 | ILogger myLogger = myContainer.Resolve(); 66 | ``` 67 | 68 | In addition, the application can use a variable (perhaps set in configuration or at run time) to specify a different implementation of the logging component interface as required, as shown in the following code. 69 | 70 | ```C# 71 | // Retrieve logger type name from configuration 72 | String loggerName = ConfigurationManager.AppSettings["LoggerName"].ToString(); 73 | ILogger myLogger = myContainer.Resolve(loggerName); 74 | ``` 75 | 76 | For more information about registering types, type mappings, and resolving instances, see [Resolving Objects](http://unitycontainer.org/tutorials/Composition/Resolution/resolution.html). 77 | 78 | ## Service and Component Location 79 | 80 | Frequently, applications require the use of services or components that are specific to the application; examples are business logic components, data access components, interface components, and process controllers. In some cases, these services may be instance-based, so that each section of the application or each task requires a separate individual instance of the service. However, it is also common for services to be singleton-based, so that every user of the service references the same single instance of the service. 81 | 82 | A service location facility makes it easy for an application to obtain a reference to a service or component, without having to specify where to look for the specific service or whether it is a singleton-based or an instance-based service. By using dependency injection mechanisms, such as the Unity container, developers can register services in the appropriate way and then obtain a reference to the service at run time, without having to specify exactly which implementation of the service is required or what type of instance it actually is. 83 | 84 | For example, if you have a singleton service class named CustomerData that you interact with to read and update information for any customer, your application obtains a reference to this service usually by calling a static GetInstance method of the service (which ensures that it is a singleton and that only one instance can exist), as shown in the following code. 85 | 86 | ```C# 87 | CustomerData cData = CustomerData.GetInstance(); 88 | ``` 89 | 90 | Instead, you can use the Unity container to set the CustomerData class type with a specific lifetime that ensures it behaves as a singleton so that every request for the service returns the same instance, as shown in the following code. Alternatively, you could specify these mappings using the Unity configuration file. 91 | 92 | ```C# 93 | // Create container and register type as a singleton instance 94 | IUnityContainer myContainer = new UnityContainer(); 95 | myContainer.RegisterType(new ContainerControlledLifetimeManager()); 96 | ``` 97 | 98 | The application can then obtain a reference to the single instance of the CustomerData service using the following code. If the instance does not yet exist, the container creates it. 99 | 100 | ```C# 101 | CustomerData cData = myContainer.Resolve(); 102 | ``` 103 | 104 | In addition, perhaps a new CustomerFile component you decide to use in your application inherits the same base class named CustomerAccessBase as the CustomerData service, but it is not a singleton—instead, it requires that your application instantiate an instance for each customer. In this case, you can specify mapping names when you register one component as a singleton type and one component as an instance type (with the default transient lifetime), and then use the same application code to retrieve the required instance. 105 | 106 | For example, the following code shows how you can register two named mappings for objects that inherit from the same base class, then—at run time—collect a string value from elsewhere in the application configuration that specifies which of the mappings to use. In this case, the value comes from the AppSettings section of the configuration file. If the value with the key CustomerService contains CustomerDataService, the code returns an instance of the CustomerData class. If it contains the value CustomerFileService, the code returns an instance of the CustomerFile class. 107 | 108 | ```C# 109 | IUnityContainer myContainer = new UnityContainer(); 110 | // Register CustomerData type as a singleton instance 111 | myContainer.RegisterType("CustomerDataService", 112 | new ContainerControlledLifetimeManager()); 113 | // Register CustomerFile type with the default transient lifetime 114 | myContainer.RegisterType("CustomerFileService"); 115 | ... 116 | String serviceName = ConfigurationManager.AppSettings["CustomerService"].ToString(); 117 | CustomerAccessBase cData 118 | = (CustomerAccessBase)myContainer.Resolve(serviceName); 119 | ``` 120 | 121 | For more information about registering types, type mappings, and resolving instances, see [Resolving Objects](http://unitycontainer.org/tutorials/Composition/Resolution/resolution.html). For more information about using lifetime managers to control the creation, lifetime, and disposal of objects, see [Understanding Lifetime Managers](http://unitycontainer.org/tutorials/lifetime/lifetime.html). 122 | 123 | ## Policy Injection through Interception 124 | 125 | Unity interception with its built-in policy injection module enables you to effectively capture calls to objects you resolve through the Unity DI container, and apply a policy that adds additional functionality to the target object. Typically, you will use this technique to change the behavior of existing objects, or to implement the management of crosscutting concerns through reusable handlers. You can specify how to match the target object using a wide range of matching rules, and construct a policy pipeline that contains one or more call handlers. 126 | 127 | Calls to the intercepted methods or properties of the target object then pass through the call handlers in the order you add them to the pipeline, and return through them in the reverse order. Your call handlers can access the values in the call, change these values, and control execution of the call. For example, the call handlers might authorize users, validate parameter values, cache the return value, and shortcut execution so that the target method does not actually execute where this is appropriate. 128 | 129 | You can configure Unity for policy injection by using a configuration file at design time, see Configuring Policy Injection Policies, or by using the API at run time, see Registering Policy Injection Components. 130 | 131 | The following example uses the Unity API to demonstrate how you can configure Unity to perform interception on a target object, using a policy that contains a logging handler and a validation handler. Notice that the logging handler is added first, so that it will log calls even if validation fails and the validation handler shortcuts the pipeline instead of calling the method of the target object. You can use the streamlined policy definition API provided by the Unity interception container extension to configure the container at run time or you can specify the same behavior at design time by using a configuration file. For an example using the API, see Registering Policy Injection Components. For a design time example, see Configuration Files for Interception. 132 | 133 | ```C# 134 | // Create a container and add the interception extension. 135 | IUnityContainer myContainer = new UnityContainer(); 136 | myContainer.AddNewExtension(); 137 | 138 | // Configure the container with a policy named MyPolicy 139 | // that uses a TypeMatchingRule to match a custom class 140 | // and adds a logging handler and a validation handler 141 | // to the handler pipeline. You must specify at least one 142 | // matching rule or the policy will not be applied. 143 | myContainer.Configure() 144 | .AddPolicy("MyPolicy") 145 | .AddMatchingRule( 146 | new InjectionConstructor("MyCustomType")) 147 | .AddCallHandler(typeof(MyLoggingCallHandler)) 148 | .AddCallHandler(typeof(MyValidationCallHandler)); 149 | 150 | // Configure the container to intercept calls to the 151 | // custom class using a TransparentProxyInterceptor. 152 | myContainer.RegisterType("myType", 153 | new Interceptor(), 154 | new InterceptionBehavior()); 155 | 156 | 157 | // Resolve the custom type through the container when 158 | // you are ready to use it. When you call a method or 159 | // set a property on it, the call will pass through 160 | // the logging handler and the validation handler. 161 | MyCustomType myNewInstance = myContainer.Resolve("myType"); 162 | ``` 163 | 164 | For more information about interception and policy injection, see Using Interception and Policy Injection. 165 | -------------------------------------------------------------------------------- /articles/changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Change.Log 3 | --- 4 | 5 | # Upgrading Unity Container (Changelog) 6 | 7 | This document contains a list of breaking changes and noteworthy issues. At this time the list is not complete. If you discover an issue while upgrading that is not covered here please open an issue or, preferably, issue a pull request. You can clone the wiki to do that. 8 | 9 | Some breaking changes are currently documented in the issue tracker only. Again, please report any such findings by commenting on the issue. 10 | 11 | ## Upgrading to Unity 5.9.x 12 | 13 | Starting with version 5.9.0 Unity package will only contain Unity.Abstractions and Unity.Container packages. 14 | 15 | All other packages will be available as individual NuGet packages 16 | 17 | ## Breaking change 18 | 19 | Some extension methods have been moved out of the Unity nuget package and have been moved into their own individual packages. 20 | 21 | For example, the following code will no longer work 22 | 23 | ```C# 24 | Container = new UnityContainer(); 25 | Container.LoadConfiguration(); 26 | ``` 27 | 28 | You will receive an error that the namespace **Microsoft.Practices.Unity.Configuration** no longer exists in your using statements. 29 | 30 | ## The Fix 31 | 32 | To fix this and similar problems, add the required nuget packages separately. 33 | 34 | For the example above, add nuget package **Unity.Configuration** 35 | 36 | _This wiki created with help from [quintonn](https://github.com/quintonn)_ 37 | 38 | ## Upgrading to Unity 5.8.x 39 | 40 | Unity 5.8.0 adds support for nesting generic types when resolving collections (arrays and enumerables). 41 | 42 | ### Problem 43 | 44 | Unity has build in support for ``IEnumerable<>``, ``Array`` ( ``type[]`` ), ``Func<>``, and ``Lazy<>``. Theoretically it should be able to recognize these types and properly resolve them individually and in combination. Unfortunately it did not do so. For example if you registered several interfaces like this: 45 | 46 | ```C# 47 | RegisterType("1"); 48 | RegisterType("2"); 49 | RegisterType("3"); 50 | RegisterType(); 51 | ``` 52 | 53 | resolving enumerable in combination with generic will resolve incorrectly: 54 | 55 | ```C# 56 | Resolve>> - resolve correctly 57 | Resolve>> - resolve empty 58 | ``` 59 | 60 | ### The Fix 61 | 62 | Release v5.8.0 fixes resolution of collections of generic and array types and Lazy collections of items. This will now work fine: 63 | 64 | ```C# 65 | Resolve>> 66 | Resolve>> 67 | 68 | Resolve> 69 | Resolve[]> 70 | 71 | Resolve>>>() 72 | Resolve>>>() 73 | 74 | Resolve>[]>() 75 | Resolve>[]>() 76 | ``` 77 | 78 | The logic behind resolving collections is to find type to enumerate and get all registrations for it no matter how deep in generics tree. Enumerated type could be: 79 | 80 | - Non generic (Constructed Generic) type 81 | - Explicitly registered type 82 | 83 | So, in this example 84 | 85 | ```C# 86 | RegisterType("1"); 87 | RegisterType("2"); 88 | RegisterType("3"); 89 | RegisterType(); 90 | 91 | Resolve>>>(); 92 | ``` 93 | 94 | Unity will recognize ``IService`` as registered type and enumerate four instances of ``Func>``. 95 | 96 | But if you look at this example: 97 | 98 | ```C# 99 | RegisterType("1"); 100 | RegisterType("2"); 101 | RegisterType("3"); 102 | RegisterType(); 103 | 104 | RegisterType(typeof(IFoo<>), typeof(Foo<>)); <-- note this registraton 105 | 106 | Resolve>>(); 107 | ``` 108 | 109 | Returned result is different! Adding registration for IFoo changes enumerable type to IFoo. This resolution will only return one item. 110 | 111 | ### Breaking change 112 | 113 | Sometimes you do want Unity to ignore a generic when it resolves collections similar to how it deals with ``Lazy`` and ``Func``. Suppose in example above you want Unity to resolve all four of IService instances wrapped in ``IFoo``. 114 | To do so you would have to make ``IFoo<>`` a **Built-In** type of the container. 115 | 116 | It could be simply done by creating either [IBuildPlanCreatorPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlanCreator/FooBuildPlanCreatorPolicy.cs) or [IBuildPlanPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlan/FooBuildPlanPolicy.cs) factories. 117 | There are just a few steps you need to follow: 118 | 119 | - Create factory for the generic (See example for [IBuildPlanCreatorPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlanCreator/FooBuildPlanCreatorPolicy.cs) or [IBuildPlanPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlan/FooBuildPlanPolicy.cs) ) 120 | - Create and extension to get access to Unity internal policies and register your factory (See example [IBuildPlanCreatorPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlanCreator/FooUnityExtension.cs) or [IBuildPlanPolicy](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlan/FooUnityExtension.cs)) 121 | - Register your extension with ``UnityContainer`` 122 | 123 | For examples of how it should be done please follow [this link](https://github.com/unitycontainer/examples/tree/master/src/Extending%20Unity). 124 | 125 | ## Upgrading to Unity 5.2.1 126 | 127 | This release fundamentally changes how types are registered with Unity. The rationale behind this change is [this issue](https://github.com/unitycontainer/container/issues/35). 128 | 129 | ### The problem 130 | 131 | To explain the problem please look at this example. Prior to this release registering singleton ``ILogger`` service like this: 132 | 133 | ```C# 134 | container.RegisterType(new ContainerControlledLifetimeManager(), new InjectionConstructor()); 135 | ``` 136 | 137 | would create two registrations: 138 | 139 | 1. A mapping between ``ILogger`` to ``MockLogger`` 140 | 2. A singleton registration for ``MockLogger`` with default constructor. 141 | 142 | Calling ``container.Resolve()`` resolves singleton instance of **MockLogger** as expected, and resolving type **MockLogger** ``container.Resolve()`` would resolve **the same** instance of **MockLogger**. Both **ContainerControlledLifetimeManager** and **InjectionConstructor** would be associated with **MockLogger** registration. 143 | 144 | Suppose you want to resolve a new **MockLogger** whenever it is resolved directly like this ``container.Resolve()``. To do so you would create another registration just for the **MockLogger**: 145 | 146 | ```C# 147 | container.RegisterType(new TransientLifetimeManager()); 148 | ``` 149 | 150 | So, now when you call ``container.Resolve()`` it resolves new instance of the **MockLogger** class and uses constructor with longest list of parameters. All is well and as expected. But now if you try to resolve ``container.Resolve()`` it is no longer returns singleton instance of the **MockLogger**. Now it also returns new **MockLogger** created with constructor with longest list of parameters. 151 | The subsequent registration overwritten all information associated with ``ILogger``. 152 | 153 | ### The solution 154 | 155 | Release 5.2.1 fixes this behavior. Now all information passed to Unity during registration is stored with ``FromType`` instead of ``ToType``. So registering type like this: 156 | 157 | ```C# 158 | container.RegisterType(new ContainerControlledLifetimeManager(), new InjectionConstructor()); 159 | ``` 160 | 161 | creates just one registration ``ILogger`` and associates **LifetimeManager** and all provided **InjectionMemebers** with it. At this point **MockLogger** is still unregistered. 162 | 163 | So, think about it as a ``RegisteredType`` and ``MappedTo`` type. If you look at initial example: 164 | 165 | ```C# 166 | container.RegisterType(new ContainerControlledLifetimeManager()); 167 | ``` 168 | 169 | ``ILogger`` - is a registered type and ContainerControlledLifetimeManager is associated with this type, as well as any ``InjectionMembers`` you provide during registration. 170 | 171 | ### Breaking changes 172 | 173 | This release breaks a lot of registrations. Anything relaying on TypeTo being registered in mappings will fail. For example: 174 | 175 | ```C# 176 | container.RegisterType(new ContainerControlledLifetimeManager()); 177 | 178 | Assert.AreSame( container.Resolve(), container.Resolve()) <-- Will fail now 179 | ``` 180 | 181 | This could be easily fixed by slightly modifying how types are registered. If you want TypeTo to be available independently you could register it like this: 182 | 183 | ```C# 184 | container.RegisterType(new ContainerControlledLifetimeManager()); 185 | container.RegisterType(); 186 | 187 | Assert.AreSame( container.Resolve(), container.Resolve()) <-- Passes 188 | ``` 189 | 190 | This applies to anything you registering with the type: factories, injection members, interceptors, etc. 191 | 192 | ### Fixing 193 | 194 | With some creative searching and sorting these breaking registrations could be identified statically, without running the code. The key is to look for registrations with same TypeTo type. If you see multiple registrations registering same type as implementation type and at least one of them has non transient lifetime it is a good indicator that it might fail after update: 195 | 196 | ```C# 197 | container.RegisterType(new ContainerControlledLifetimeManager()); 198 | ... 199 | container.RegisterType(); 200 | ``` 201 | 202 | To fix just add individual registration for implementation type with proper lifetime manager like so: 203 | 204 | ```C# 205 | container.RegisterType(new ContainerControlledLifetimeManager()); 206 | ... 207 | container.RegisterType(); 208 | ... 209 | container.RegisterType(); 210 | ``` 211 | 212 | Make sure it is registered before other mappings. 213 | 214 | ## Upgrading to Unity.Abstractions 4.1.4 215 | 216 | Lifetime managers now support the value `null`. `GetValue` must return `LifetimeManager.NoValue` to indicate that no value has been set. You must upgrade custom lifetime managers to not return `null` inappropriately. Mainly the `GetValue` method must be adjusted. The built-in lifetime managers have been upgraded. If you do not use custom lifetime managers you should not see any changes in behavior. (https://github.com/unitycontainer/abstractions/issues/102) 217 | 218 | Design time validation for `LifetimeManager` was added. The marker interfaces `ITypeLifetimeManager`, `IInstanceLifetimeManager` and `IFactoryLifetimeManager` have been introduced. Various other parts of the framework now refer to these types instead of `LifetimeManager`. The marker interfaces are empty and `LifetimeManager` does not inherit from any of them. This can lead to compiler errors. In general these errors can be fixed through changing the type of variables or through casting. (https://github.com/unitycontainer/abstractions/issues/90) 219 | 220 | ## Upgrading to Unity.Abstractions 4.0.0.350 221 | 222 | The namespace `Unity.Attributes` was removed. These types are now in namespace `Unity`. One common type that is affected is `DependencyAttribute`. Suggested way to upgrade: Mass delete the old namespace reference using the Regex `using Unity.Attributes;\r\n` in Visual Studio. Then, use Resharper to fix missing imports in the entire solution in one action. 223 | 224 | ## Upgrading to Unity.Abstractions 4.0.0.0 225 | 226 | A few breaking changes have been made. For more information see https://github.com/unitycontainer/abstractions/issues/97. 227 | 228 | ### Problem 229 | 230 | Build error `The type or namespace name 'IBuilderContext' could not be found.` 231 | 232 | ### Solution 233 | 234 | `IBuilderContext` has been replaced with: `Unity.Builder.BuilderContext` 235 | 236 | ### Problem 237 | 238 | Build Error `'IBuildPlanCreatorPolicy' is obsolete: 'This interface has been replaced with Unity.Policy.ResolveDelegateFactory delegate'`` 239 | 240 | ### Solution 241 | 242 | See [this example](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlanCreator/FooBuildPlanCreatorPolicy.cs) or [this example](https://github.com/unitycontainer/microsoft-logging/blob/master/src/LoggingExtension.cs) or [this example](https://github.com/unitycontainer/examples/blob/master/src/Extending%20Unity/BuildPlanCreator/FooBuildPlanCreatorPolicy.cs) 243 | 244 | ### Problem 245 | 246 | Build Error in `BuilderStrategy` derived classes: `'MyCustomStrategy.PreBuildUp(BuilderContext)': no suitable method found to override` 247 | 248 | ### Solution 249 | 250 | Adjust the signature of the `PreBuildUp` method to: `public override void PreBuildUp(ref BuilderContext context)` 251 | 252 | ### Problem 253 | 254 | Build Error in `BuilderStrategy` derived classes: `'MyCustomStrategy.PostBuildUp(BuilderContext)': no suitable method found to override` 255 | 256 | ### Solution 257 | 258 | Adjust the signature of the PostBuildUp method to: 259 | public override void PreBuildUp(ref BuilderContext context) 260 | 261 | ### Problem 262 | 263 | Build Error in Builder Strategy derived class: 264 | `'BuilderContext' does not contain a definition for 'AddResolverOverrides' and no accessible extension method 'AddResolverOverrides' accepting a first argument of type 'BuilderContext' could be found` 265 | 266 | ### Solution 267 | 268 | The behaviour can be mimicked by something like: 269 | 270 | ```cs 271 | public static void AddResolverOverrides(ref BuilderContext ctx, ResolverOverride theOverride) 272 | { 273 | var newOverrides = ctx.Overrides; 274 | newOverrides = newOverrides == null 275 | ? new ResolverOverride[]{theOverride} 276 | : newOverrides.Concat(new[] {theOverride}).ToArray(); 277 | 278 | ctx.Overrides = newOverrides; 279 | } 280 | ``` 281 | 282 | ### Problem 283 | 284 | `'BuilderContext' does not contain a definition for 'ParentContext' and no accessible extension method 'ParentContext' accepting a first argument of type 'BuilderContext' could be found` 285 | 286 | I used the `ParentContext` of `IBuilderContext` to determine if anything in the build hierarchy was of a certain type. More specifically I was checking to see if a specific decorator class was being applied as part of the build. 287 | 288 | ### Solution 289 | 290 | There is an `IntPtr Parent` property on the `BuilderContext` struct. Can this be used to find the parent context? 291 | 292 | ### Problem 293 | 294 | There is a build warning: 295 | `'InjectionFactory' is obsolete: 'InjectionFactory has been deprecated and will be removed in next release. Please use IUnityContainer.RegisterFactory(...) method instead.'` 296 | 297 | ### Solution 298 | 299 | The `InjectionFactory` class has been deprecated. Injection factories are now registered directly with the container. 300 | For example: 301 | 302 | **Old code:** 303 | `Container.RegisterType(new ContainerControlledLifetimeManager(), new InjectionFactory(c => MakeEncryptionProvider(c)));` 304 | 305 | **New code:** 306 | `Container.RegisterFactory(c => MakeEncryptionProvider(c), new ContainerControlledLifetimeManager());` 307 | 308 | ### Be Aware 309 | The public key token of the assembly has changed, so you may need to remove redundant assembly bindings from config files. 310 | 311 | For example: 312 | This binding will now be ineffective, and can be removed: 313 | 314 | ```xml 315 | 316 | 317 | 318 | 319 | ``` 320 | 321 | Note: 322 | 323 | - The old public key token value is `6d32ff45e0ccc69f` 324 | - The new public key token is `489b6accfaf20ef0` 325 | 326 | ### Problem 327 | 328 | Build Error in `BuilderStrategy` derived classes: `'MyCustomStrategy.PostBuildUp(BuilderContext)': no suitable method found to override` 329 | 330 | ### Solution 331 | 332 | Adjust the signature of the `PostBuildUp` method to: `public override void PreBuildUp(ref BuilderContext context)` 333 | 334 | ### Problem 335 | 336 | I'm using this code to register my interfaces: 337 | 338 | Containter.RegisterType(new ContainerControlledLifetimeManager(), InjectionConstructor); 339 | 340 | But after the upgrade im getting the following error when resolving: 341 | 342 | ```bash 343 | Exception thrown: 'System.InvalidCastException' in Unity.Abstractions.dll 344 | Unable to cast object of type 345 | ``` 346 | 347 | ### Solution 348 | 349 | Ok I managed to find out what I was doing wrong. 350 | I was reusing the same 'InjectionConstructor' for all my registrations. 351 | After replacing them with a new instance for each my problem went away. 352 | -------------------------------------------------------------------------------- /articles/design.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.Design 3 | --- 4 | 5 | # Design of Unity 6 | 7 | Unity was designed to achieve the following goals: 8 | 9 | * Promote the principles of modular design through aggressive decoupling. 10 | * Maximize testability when designing applications. 11 | * Provide a fast and lightweight dependency injection platform for creating new as well as managing existing objects. 12 | * Expose a compact and intuitive API for developers to work with. 13 | * Support a wide range of languages, and platforms. 14 | * Allow attribute-driven injection for constructors, properties, fields, and methods. 15 | * Provide extensibility through container extensions. 16 | * Provide stability required in enterprise-level line of business (LOB) applications. 17 | 18 | To allow maximum flexibility Unity container split into **core** and **extension** packages. Core packages implement basic [IoC](https://en.wikipedia.org/wiki/Inversion_of_control)/[DI](https://en.wikipedia.org/wiki/Dependency_injection) functionality and extensions provide specific behavior such as configuration, decoration, and etc. 19 | 20 | ## Unity Core 21 | 22 | Unity core consists of two assemblies: 23 | 24 | * `Unity.Abstractions` 25 | * `Unity.Container` 26 | 27 | `Unity.Abstractions` assembly contains all public declarations required to use the container in applications and relatively unchanged from version to version. It defines [IUnityContainer](xref:Unity.IUnityContainer) interface as well as types and interfaces used to register, configure and resolve types and instances. 28 | 29 | `Unity.Container` assembly implements the IoC engine and exposes public members required to extend the container. 30 | 31 | ### Core Packages 32 | 33 | For legacy support and general convenience core library is distributed in two different forms: 34 | 35 | * as composite package [Unity](https://www.nuget.org/packages/Unity/) 36 | * as independent packages [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) and [Unity.Container](https://www.nuget.org/packages/Unity.Container/) 37 | 38 | #### Composite package [Unity](https://www.nuget.org/packages/Unity/) 39 | 40 | This is a convenience package containing both `Unity.Abstractions` as well as `Unity.Container` assemblies. This package is distributed to support legacy applications. 41 | 42 | #### Independent Packages [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) and [Unity.Container](https://www.nuget.org/packages/Unity.Container/) 43 | 44 | To allow easier path to upgrade and maximum decoupling between declarative part and implementation, Unity split into two assemblies: [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) and [Unity.Container](https://www.nuget.org/packages/Unity.Container/) 45 | 46 | When used in libraries it allows linking to Unity.Abstractions and referencing Unity.Container only in bootstrapping project. 47 | 48 | ## Unity Extensions 49 | 50 | Unity project implements and distributes several extensions such as Unity.Configuration, Unity.Interception, [and etc.](https://www.nuget.org/packages?q=unitycontainer) 51 | 52 | ## More Information 53 | 54 | For more information about using packages inside applications see [Application Design](xref:Article.Application.Design) concepts with Unity. 55 | -------------------------------------------------------------------------------- /articles/features.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.Features 3 | --- 4 | 5 | # Features 6 | 7 | ## General Features 8 | 9 | * No registration required for simple POCO types 10 | * Registration/updates at any time (no builder required) 11 | * Support registration metadata 12 | * Support generic types 13 | * Register existing objects 14 | * Custom Type factories 15 | * Register Type 16 | * List all registrations 17 | * Check existing registrations 18 | 19 | ## Setup 20 | 21 | * Registration 22 | * Type mappings 23 | * Register as a `Type` 24 | * Support `Type` polymorphism 25 | * Register as an implemented interface 26 | * Multiple interfaces of the same `Type` 27 | * Register Type 28 | * Constructor selection 29 | * Constructor marked by attribute 30 | * 'Smart' constructor selection 31 | * Longest constructor Unity can satisfy with parameters (dynamic) 32 | * Legacy longest constructor (Extension) 33 | * Specific constructor (Injection Member) 34 | * By types of parameters 35 | * By injected members 36 | * By provided values 37 | * Initializing Properties 38 | * Marked with attribute 39 | * Injected during registration (Injection Member) 40 | * Initializing Fields 41 | * Marked with attribute 42 | * Injected during registration (Injection Member) 43 | * Calling Methods on the object 44 | * Marked with attribute 45 | * Injected during registration (Injection Member) 46 | * By types of parameters 47 | * By injected members 48 | * By provided values 49 | * Registrations Collection 50 | * List registrations of the container 51 | * Support registration hierarchies 52 | * Check if `Type` is registered 53 | * Fast and efficient algorithm 54 | 55 | ## Execution 56 | 57 | ### Initialization of existing objects (BuildUp) 58 | 59 | * Perform initialization on already created objects 60 | * Follow the same pattern as create (Resolve) object 61 | * Compatible with Activator and Compiled pipelines 62 | * Initialize Properties and Fields 63 | * Call Methods and inject parameters 64 | 65 | ### Create Instances (Resolve) 66 | 67 | * Inject constructor with parameters 68 | * Initialize Properties and Fields 69 | * Call Methods and injects parameters 70 | * Support Activator pipelines 71 | * Create optimized (compiled) pipelines 72 | * Seamlessly resolve registered instances or creates new objects 73 | * Built-in support for deferred resolution 74 | * `Func` 75 | * `Lazy` 76 | * Built-in support for collections 77 | * `T[]` 78 | * `IEnumerable` 79 | * Automatic concrete types resolution 80 | * Dependency injection 81 | * Required 82 | * Optional 83 | * Supports Default parameters 84 | * Injects with resolved parameters 85 | * Injects with registered values 86 | * Supports parameter overrides 87 | * Open-generic types 88 | * constraints 89 | * variance 90 | * nested 91 | * recurring generic definitions 92 | 93 | ### Manages lifetime of objects 94 | 95 | * Transient 96 | * Singleton 97 | * Per Container 98 | * Per Container Transient 99 | * Hierarchical 100 | * External 101 | * Per Thread 102 | * Per Resolve 103 | * Other (Extension) 104 | 105 | ### Create child (Scoped) containers 106 | 107 | * Create disposable child containers (scopes) 108 | 109 | ## Extensibility 110 | 111 | ### Diagnostic 112 | 113 | * Registration 114 | * Injection Attribute 115 | * Stack Overflow 116 | * Cyclic reference 117 | 118 | ### Legacy 119 | 120 | * Legacy constructor selection 121 | 122 | ### Functionality 123 | 124 | * Configuration 125 | * Interception 126 | * Logging 127 | * Web 128 | * Etc. -------------------------------------------------------------------------------- /articles/history.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.History 3 | --- 4 | 5 | # The Unity Container History 6 | 7 | | Year | Release | Authors and Contributors | 8 | |:-----| :-----------: | :----- | 9 | | | | | 10 | | October 2017 | Unity 5 | GitHub Community Site | 11 | | October 2015 | Unity 4 | GitHub Community Site | 12 | | April 2014 | [Unity 3.5](https://archive.codeplex.com/?p=unity) | CodePlex Community Site | 13 | | April 2013 | [Unity 3](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn170416(v%3dpandp.10)) | CodePlex Community Site | 14 | | Aug 2012 | [Unity 2.1](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh237492(v%3dpandp.10)) | CodePlex Community Site | 15 | | April 2010 | [Unity 2.0](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff663144(v%3dpandp.10)) | Grigori Melnik, Bob Brumfield, Chris Tavares, Fernando Simonazzi, Nicolas Botto, Olaf Conijn, Carlos Farre, Masashi Narumoto, Rohit Sharma, Lavanya Selvaraj, Magdelene Sona, Mani Krishnaswami, Meenakshi Krishnamoorthi, Santhosh Panneerselvam, Ravindra Varman, Erik Renaud, François Tanguay, Rick Carr, Alex Homer, Dennis DeWitt, RoAnn Corbisier, Steve Elston, Nancy Michel, Patrick Lanfear, Tom Draper, Richard Burte, Jennifer Burch, Tracy Emory | 16 | | October 2008 | [Unity Application Block 1.2](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff647347(v%3dpandp.10)) | Grigori Melnik, Chris Tavares, Fernando Simonazzi, Vijaya Janakiraman, Carlos Farre, Dennis DeWitt, Alex Homer, Nelly Delgado, RoAnn Corbisier, Tina Burden McGrayne, Richard Burte | 17 | | May 2008 | [Unity Application Block 1.1](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff649080(v%3dpandp.10))| Grigori Melnik, Scott Densmore, William Loeffler, Chris Tavares, Fernando Simonazzi, Nicolas Botto, Hanz Zhang, Carlos Farre, Naveen Guda, Pooja Parate, Pravin Pawar, Ronita Acharya, Sai Pasumarthi, Venkata Appaji Sirangi, Vijaya Janakiraman, Alex Homer, Nelly Delgado, RoAnn Corbisier, Tina Burden McGrayne | 18 | 19 | -------------------------------------------------------------------------------- /articles/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.Install 3 | --- 4 | 5 | # Adding Unity to Your Application 6 | 7 | Unity is designed to support a range of common scenarios for resolving instances of objects that, themselves, depend on other objects or services. However, you must first prepare your application to use Unity. The following procedure describes how to include the necessary assemblies and elements in your code. 8 | 9 | ## To prepare your application 10 | 11 | Before you can add Unity to your solution you need to decide if you want to reference packages individually ([Abstractions](https://www.nuget.org/packages/Unity.Abstractions/), [Container](https://www.nuget.org/packages/Unity.Container/)) or use composite [Unity]([Unity](https://www.nuget.org/packages/Unity/)) package. 12 | 13 | ### Referencing composite package 14 | 15 | Referencing single [Unity]([Unity](https://www.nuget.org/packages/Unity/)) package is more appropriate in case of small(ish) project, when everything is contained within one solution. Upgrading such solution is trivial with the help of NuGet Manager. 16 | 17 | ### Referencing individual packages 18 | 19 | Main benefit of referencing [Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) and [Container](https://www.nuget.org/packages/Unity.Container/) packages individually is when it is used in large project spanning multiple solutions, modules, and project files. 20 | 21 | Normally modular systems have one main application/module with boot-loader responsible for initializing environment, and number of modules loaded by it ([Prism library](https://prismlibrary.github.io/) for example). This boot loader is required to reference both [Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) and [Container](https://www.nuget.org/packages/Unity.Container/) packages. 22 | 23 | In such systems modules are created and distributed by various teams and departments and synchronization between these might be a challenge. This is where Unity comes in. 24 | As stated elsewhere on this site [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) contains all declarations required by Unity to operate. Because of that modules could only reference one assembly: [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) 25 | 26 | This separation allows updates of patched container's engine without recompiling all the modules used in the system. Given that specifications change very infrequently and [Unity.Abstractions](https://www.nuget.org/packages/Unity.Abstractions/) package stays the same most of the time it provides big benefit in terms of saved development/testing time and money. 27 | 28 | ## Adding Unity to project 29 | 30 | Unity container is distributed via NuGet and could be added to a project with the help of NuGet manager or by executing command: 31 | 32 | ```bash 33 | Install-Package Unity 34 | 35 | or 36 | 37 | Install-Package Unity.Abstractions 38 | Install-Package Unity.Container 39 | ``` 40 | 41 | If you wish to use [Floating Version references](https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#floating-versions) it is recommended to lock in the minor and major versions and only allow patch version to slide: 42 | 43 | ```js 44 | 45 | ``` 46 | 47 | doing so will guarantee that no breaking change caught you of guard. -------------------------------------------------------------------------------- /articles/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.Introduction 3 | --- 4 | 5 | # Unity Container Introduction 6 | 7 | ## Overview 8 | 9 | Unity Container is a full featured, general-purpose [IoC container](https://en.wikipedia.org/wiki/Inversion_of_control) for use in any type of .NET application. It is [Open Source](https://en.wikipedia.org/wiki/Open_source) and released under [Apache 2.0 license](https://github.com/unitycontainer/unity/blob/master/LICENSE). 10 | 11 | Unity is extensible. Anyone can write an extensions that changes the behavior of the container, or adds new capabilities. For example, the interception feature provided by Unity, which you can use to add policies to objects, is implemented as a container extension. 12 | 13 | ## What Does Unity Do 14 | 15 | Apart from decoupling types, components, services, and separating concerns, Unity crates and manages objects. Think of it as operator [new ...](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-operator) on steroids. 16 | 17 | * [The Types of Objects Unity Can Create](#the-types-of-objects-unity-can-create) 18 | * [Registering Existing Types and Object Instances](#registering-types-and-object-instances) 19 | * [Managing the Lifetime of Objects](#managing-the-lifetime-of-objects) 20 | * [Specifying Values for Injection](#specifying-values-for-injection) 21 | * [Populating collections](#populating-collections) 22 | * [Support for deferred resolution](#support-for-deferred-resolution) 23 | 24 | ## The Types of Objects Unity Can Create 25 | 26 | You can use the Unity container to generate instances of any object that has a public constructor (in other words, objects that you can create using the new operator). During object instantiation Unity can: 27 | 28 | * Select appropriate constructor 29 | * Inject constructor with parameters 30 | * Inject public properties with values 31 | * Inject public fields with values 32 | * Call any public method on the created object 33 | 34 | ### Registering Types and Object Instances 35 | 36 | Unity can resolve any concrete, constructable reference type without registration. For example calling `container.Resolve()` will produce an instance immediately. 37 | 38 | Registrations allow mapping between service types and implementation types. Create a blueprint of how instances instantiated, initialized, and managed. For generic types it creates internal mini factories that used to generate concrete types. Unity supports three ways of registering types: 39 | 40 | #### Instance registration 41 | 42 | Unity exposes a method named [RegisterInstance](xref:Unity.IUnityContainer#Unity_IUnityContainer_RegisterInstance_System_Type_System_String_System_Object_Unity_Lifetime_IInstanceLifetimeManager_) that you can use to register existing instances with the container. The instance could be registered as concrete type, a type of the instance you would get by calling `instance.GetType()`, or it could be registered as any of the interfaces the instance implements. Lifetime of registered instance could be either controlled by container it is registered with or externally, in which case Unity just keeps weak reference to the object. 43 | 44 | #### Factory registration 45 | 46 | Method [RegisterFactory](xref:Unity.IUnityContainer#Unity_IUnityContainer_RegisterFactory_System_Type_System_String_System_Func_Unity_IUnityContainer_System_Type_System_String_System_Object__Unity_Lifetime_IFactoryLifetimeManager_) provides a way to register a factory delegate Unity would call when required to provide the type. 47 | 48 | #### Type registration 49 | 50 | [RegisterType](xref:Unity.IUnityContainer#Unity_IUnityContainer_RegisterType_System_Type_System_Type_System_String_Unity_Lifetime_ITypeLifetimeManager_Unity_Injection_InjectionMember___) is a method where you can instruct Unity how to create and initialize objects from scratch. You can specify: 51 | 52 | * Constructor to call 53 | * Parameters to pass to the constructor or how to resolve them 54 | * Properties to initialize and how to do it 55 | * Fields to inject and with what 56 | * Methods to call on the created object and parameters to pass to these methods 57 | * Specify how lifetime should be managed 58 | 59 | ## Managing the Lifetime of Objects 60 | 61 | Unity allows you to choose the lifetime of the objects it creates. By default, Unity creates a new instance of a type each time you resolve that type. However, you can use different lifetime managers to specify a required lifetime for resolved instances. For example, you can specify that Unity should maintain only a single instance (a singleton). It will create a new instance only if there is no existing instance. If there is an existing instance, it will return a reference to this instead. There are also other lifetime managers you can use. 62 | 63 | ## Specifying Values for Injection 64 | 65 | Unity allows configurations where dependencies are resolved from the container. But it also provides an easy way to configure injection of values at registration. In other words you could provide values for dependencies to be registered and used during subsequent resolutions. 66 | 67 | Unity also allows overriding of any dependency values during resolution. It could override any configured or resolved value during resolution of the type. 68 | 69 | ## Populating collections 70 | 71 | Unity has built-in support for resolving arrays and enumerations of types. For example it would recognize following types as collections and resolve them using proper algorithm: 72 | 73 | * `Resolve()` 74 | * `Resolve>()` 75 | * `Resolve>()` 76 | 77 | ## Support for deferred resolution 78 | 79 | Unity container implements strategies to allow deferred resolution of types. It has two types of deferred resolvers: 80 | 81 | * `Func` - Creates factory method which instantiates type **T** on demand. 82 | * `Lazy` - Creates `Lazy` object and passes it to created type. 83 | 84 | -------------------------------------------------------------------------------- /articles/quickstart.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Article.Unity.Using 3 | --- 4 | 5 | # Using Unity in Applications 6 | 7 | This topic describes how to develop applications using Unity and how to create and build instances of objects. It assumes that you are familiar with dependency injection and separation of concern concepts. 8 | 9 | ## The Container 10 | 11 | Unity exposes a very compact API to operate on the container. Most operations related to registration, resolution and lifetime management is exposed through one interface - **[IUnityContainer](xref:Unity.IUnityContainer)**. 12 | 13 | To start using Unity you need to create an instance of the container and get a reference to the [IUnityContainer](xref:Unity.IUnityContainer) interface: 14 | 15 | ```cs 16 | IUnityContainer container = new UnityContainer(); 17 | ``` 18 | 19 | ## Creating instances 20 | 21 | Once the container is created you can use it immediately: 22 | 23 | ```cs 24 | IUnityContainer container = new UnityContainer(); 25 | var value = container.Resolve(); 26 | 27 | // Calling Resolve() is the same as 28 | value = new object(); 29 | ``` 30 | 31 | It will create any type with an accessible constructor. Consider following example: 32 | 33 | ```cs 34 | // Simple class Foo 35 | public class Foo 36 | { 37 | public Foo() { } 38 | 39 | public Foo(object obj) { } 40 | 41 | public Foo(string id, object obj) { } 42 | } 43 | 44 | // Create container 45 | IUnityContainer container = new UnityContainer(); 46 | 47 | // Resolve Foo 48 | var value = container.Resolve(); 49 | 50 | // value created with constructor 'Foo(object obj)' 51 | ``` 52 | 53 | `Foo` is a simple class with three public constructors. When `Resolve()` is called, Unity will evaluate the available constructors and select one with the longest list of parameters it can satisfy with dependencies. It will create all required dependencies and pass them to the selected constructor during initialization. 54 | 55 | In this particular case Unity will select the second constructor with parameter `obj` of type [Object](xref:System.Object). Although constructor `Foo(string id, object obj)` is longer, it has a parameter of type [String](xref:System.String) which is a primitive type. Unity cannot create primitive types by itself. If you want to make these available for dependency injection you would need to register them with the container. For Unity to select the third constructor `Foo(string id, object obj)` you need to register a string instance with container: 56 | 57 | ```cs 58 | // Register string instance 59 | container.RegisterInstance("xyz"); 60 | 61 | // Resolve Foo 62 | var value = container.Resolve(); 63 | 64 | // value created with constructor 'Foo(string id, object obj)' 65 | ``` 66 | 67 | For more information on how Unity selects members see [Member Selection](xref:Tutorial.Resolution.Selection) 68 | 69 | ## Type Mapping 70 | 71 | In service oriented architecture contracts are represented by interfaces and components implement these contracts to provide services. Consider these types: 72 | 73 | ```cs 74 | // Public service contract 75 | public interface IService 76 | { 77 | // Service API 78 | } 79 | 80 | 81 | // Component implementing the contract 82 | public class Component : IService 83 | { 84 | // Some logic here 85 | } 86 | 87 | 88 | // Service consumer 89 | public class Foo 90 | { 91 | public Foo(IService service) 92 | { 93 | // Some logic here 94 | } 95 | } 96 | ``` 97 | 98 | In this example we have `IService` interface defining an API and class `Component` implementing that API. Type `Foo` is a consumer of the service and should be injected by the container with an instance of the service during initialization. 99 | 100 | If you just call `container.Resolve()` it will throw an exception complaining that it cannot create an interface of type `IService`. You need to register a [Type Mapping](xref:Tutorial.Mapping) to instruct Unity how to create a service of type `IService`: 101 | 102 | ```cs 103 | // Register mapping between IService and Component 104 | container.RegisterType(); 105 | 106 | // Resolve Foo 107 | var value = container.Resolve(); 108 | 109 | // value created with constructor 'Foo(IService service)' 110 | ``` 111 | 112 | During resolution, Unity will try to satisfy dependencies, it will look for a registration for each dependency and find this mapping. It will create `Component` and pass it to the constructor of `Foo` as `IService`. 113 | 114 | For more information see [Type Mapping](xref:Tutorial.Mapping) 115 | 116 | ## Lifetime 117 | 118 | By default Unity creates a new instance every time a type is requested. Instances it create are not tracked or managed by the container. 119 | 120 | ```cs 121 | // Register mapping between IService and Component 122 | container.RegisterType(); 123 | 124 | // Resolve IService 125 | var value1 = container.Resolve(); 126 | var value2 = container.Resolve(); 127 | 128 | // value1 and value2 are not the same 129 | ``` 130 | 131 | To enable lifetime management, a type needs to be registered with one of the compatible [lifetime managers](xref:Unity.Lifetime). Depending on registration type Unity provides three helpers: 132 | 133 | * [TypeLifetime](xref:Unity.TypeLifetime) 134 | * [InstanceLifetime](xref:Unity.InstanceLifetime) 135 | * [FactoryLifetime](xref:Unity.FactoryLifetime) 136 | 137 | For example, to make `IService` a singleton for the entire application and create it only once you would register it like this: 138 | 139 | ```cs 140 | // Register mapping between IService and Component 141 | container.RegisterType(TypeLifetime.Singleton); 142 | 143 | // Resolve IService 144 | var value1 = container.Resolve(); 145 | var value2 = container.Resolve(); 146 | 147 | // value1 and value2 are the same instance of Component 148 | ``` 149 | 150 | For more information see [Lifetime Management](xref:Tutorial.Lifetime) 151 | -------------------------------------------------------------------------------- /articles/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Introduction 2 | uid: Article.Unity.Introduction 3 | - name: Features 4 | uid: Article.Unity.Features 5 | - name: Design of Unity 6 | uid: Article.Unity.Design 7 | - name: Application Design 8 | uid: Article.Application.Design 9 | - name: Adding Unity to application 10 | uid: Article.Unity.Install 11 | - name: Quick Start 12 | uid: Article.Unity.Using 13 | - name: Change Log 14 | uid: Article.Change.Log 15 | -------------------------------------------------------------------------------- /docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "files": [ 7 | "src/Abstractions/src/Unity.Abstractions.csproj" 8 | ] 9 | } 10 | ], 11 | "dest": "api", 12 | "properties": { "TargetFramework": "netstandard2.0" } 13 | } 14 | ], 15 | "build": { 16 | "content": [ 17 | { 18 | "files": [ 19 | "api/**.yml", 20 | "api/index.md" 21 | ] 22 | }, 23 | { 24 | "files": [ 25 | "Articles/**.md", 26 | "Articles/**/toc.yml", 27 | "Specs/**.md", 28 | "Specs/**/toc.yml", 29 | "Tutorials/**.md", 30 | "Tutorials/**/toc.yml", 31 | "toc.yml", 32 | "*.md" 33 | ], 34 | "exclude": [ 35 | "obj/**", 36 | "unitycontainer.github.io/**" 37 | ] 38 | } 39 | ], 40 | "resource": [ 41 | { 42 | "files": [ 43 | "images/**" 44 | ], 45 | "exclude": [ 46 | "obj/**", 47 | "unitycontainer.github.io/**" 48 | ] 49 | } 50 | ], 51 | "xrefService": [ 52 | "https://xref.docs.microsoft.com/query?uid={uid}" 53 | ], 54 | "dest": "unitycontainer.github.io", 55 | "globalMetadataFiles": [], 56 | "fileMetadataFiles": [], 57 | "template": [ 58 | "default" 59 | ], 60 | "postProcessors": [], 61 | "markdownEngineName": "markdig", 62 | "noLangKeyword": false, 63 | "keepFileLink": false, 64 | "cleanupCacheHistory": false, 65 | "disableGitFeatures": false, 66 | "globalMetadata" : 67 | { 68 | "_appTitle" : "Unity Container", 69 | "_appFooter" : "Copyright © 2020 .NET Foundation and Contributors. All Rights Reserved", 70 | "_appLogoPath" : "images/logo.svg", 71 | "_appFaviconPath": "images/favicon.png" 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var gulp = require('gulp'); 3 | var exec = require('gulp-exec'); 4 | var browserSync = require('browser-sync'); 5 | 6 | const config = 'docfx.json'; 7 | const server = browserSync.create(); 8 | 9 | function watched(){ 10 | var content = fs.readFileSync(config); 11 | var json = JSON.parse(content); 12 | return json.build.content.reduce(function(flat, section) { 13 | return flat.concat(section.files); 14 | }, []); 15 | }; 16 | 17 | function reload(done){ 18 | server.reload(); 19 | done(); 20 | } 21 | 22 | function serve(done){ 23 | server.init({ 24 | server: { 25 | baseDir: './unitycontainer.github.io' 26 | } 27 | }) 28 | } 29 | 30 | function build(){ 31 | var reportOptions = { 32 | err: true, 33 | stderr: true, 34 | stdout: true 35 | }; 36 | 37 | return gulp.src(config) 38 | .pipe(exec('docfx <%= file.name %>')) 39 | .pipe(exec.reporter(reportOptions)); 40 | } 41 | 42 | const paths = watched(); 43 | const watch = () => gulp.watch(paths, gulp.series(build, reload)); 44 | 45 | exports.default = gulp.parallel(watch, serve); 46 | exports.serve = serve; 47 | exports.build = build; 48 | exports.develop = exports.default; 49 | -------------------------------------------------------------------------------- /images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycontainer/documentation/c1904e6b2c9bdff42f10f3d4dcdf3f7080d48d9c/images/favicon.png -------------------------------------------------------------------------------- /images/resolver-override.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycontainer/documentation/c1904e6b2c9bdff42f10f3d4dcdf3f7080d48d9c/images/resolver-override.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | # [Make Unity sustainable](https://opencollective.com/unity-container) 2 | 3 | The community support is crucial for the projects to survive and to move forward. 4 | Unity is all about trust and sharing. [Open Collective](https://opencollective.com/unity-container) lets finances to be managed so everyone can see where money comes from and where it goes. It was selected to provide mechanism for the community to support and finance the project. 5 | 6 | If your project depends on [Unity container](https://github.com/unitycontainer) and you want it to be maintained and developed, please **[support](https://opencollective.com/unity-container)** it. Remember, I can have only one full time job, so without proper financial backing there will be no more releases beyond v5.11 7 | 8 | **[Become contributor to Unity project](https://opencollective.com/unity-container)** 9 | 10 | [...continue to site](xref:Article.Unity.Introduction) 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "description": "Unity Container Documentation", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/unitycontainer/documentation.git" 7 | }, 8 | "devDependencies": { 9 | "browser-sync": "^2.26.7", 10 | "gulp": "^4.0.0", 11 | "gulp-exec": "^3.0.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /serve.cmd: -------------------------------------------------------------------------------- 1 | browser-sync unitycontainer.github.io -w -------------------------------------------------------------------------------- /specs/constructor.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Constructor 3 | --- 4 | 5 | # Constructor Invocation Specification -------------------------------------------------------------------------------- /specs/field.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Field 3 | --- 4 | 5 | # Field Injection Specification -------------------------------------------------------------------------------- /specs/hierarchy.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycontainer/documentation/c1904e6b2c9bdff42f10f3d4dcdf3f7080d48d9c/specs/hierarchy.md -------------------------------------------------------------------------------- /specs/method.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Method 3 | --- 4 | 5 | # Method Invocation 6 | 7 | Method invocation is an optional step you can add to the created object's initialization. Any accessible method could be invoked, provided Unity can satisfy all the parameters with appropriate values. 8 | 9 | ## Supported Methods 10 | 11 | Any accessible method of constructed type can be invoked during initialization. 12 | 13 | Multiple methods can be configured for invokation. 14 | 15 | ### Generic methods 16 | 17 | Only closed generic methods can be invoked during initialization. 18 | 19 | ## Restrictions 20 | 21 | ### Static methods cannot be invoked 22 | 23 | Unity does not support invocation of static methods. 24 | 25 | ### Methods with `ref` or `out` parameters cannot be invoked 26 | 27 | Invoking methods containing `ref` or `out` parameters is not supported. 28 | 29 | ### Invoking `private` and `protected` methods is not allowed 30 | 31 | Although it is technically possible to call `private` and `protected` methods of the class, Unity does not support this feature. This restriction is implemented to impose consistency with accessibility principles of `C#` language. 32 | -------------------------------------------------------------------------------- /specs/property.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Property 3 | --- 4 | 5 | # Property Injection Specification -------------------------------------------------------------------------------- /specs/specification.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Unity 3 | title: Unity Container Specification 4 | --- 5 | 6 | # Unity Container Specification 7 | 8 | ## 1 Introduction 9 | 10 | Unity is a full featured, general-purpose container for use in any type of Microsoft® .NET Framework-based application. It provides all of the features commonly found in dependency injection implementations. 11 | 12 | In addition, Unity is extensible. You can write container extensions that change the behavior of the container, or add new capabilities. For example, the interception feature provided by Unity, which you can use to add policies to objects, is implemented as a container extension. 13 | 14 | ## 2 Terms and Definitions 15 | 16 | ### 2.1 Injection 17 | 18 | ### 2.2 Dependency 19 | 20 | ### 2.3 Contract 21 | 22 | * Type 23 | * Name 24 | 25 | ### 2.4 Metadata 26 | 27 | ### 2.5 Lifetime 28 | 29 | ## 3 Workflow 30 | 31 | [!include [Workflow](workflow.md)] 32 | 33 | [!code-csharp [Overrides](../src/Abstractions/src/Dependency/Injection/Abstracts/InjectionMember.cs#Overrides)] 34 | 35 | 36 | [!code-csharp [Implementation](../src/Abstractions/src/Dependency/Injection/Abstracts/InjectionMember.cs#Implementation)] 37 | -------------------------------------------------------------------------------- /specs/summary.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Summary 3 | --- 4 | 5 | # Summary 6 | 7 | 1. Introduction 8 | 1. Terms and Definitions 9 | 1. Injection 10 | 1. Dependency 11 | 1. Contract 12 | * Type 13 | * Name 14 | 1. Metadata 15 | 1. Lifetime 16 | 1. Workflow 17 | 1. Setup 18 | 1. Creating Container 19 | 1. Root 20 | 1. Scopes 21 | 1. Type Contracts 22 | 1. Implicit 23 | 1. Mapping 24 | 1. Explicit 25 | * Instance 26 | * Factory 27 | * Type 28 | 1. Provide Services 29 | 1. Locate Contract 30 | 1. Existing 31 | 1. Hierarchical 32 | 1. None 33 | 1. Create Locally 34 | 1. With the registration 35 | 1. At the root 36 | 1. Execute contract 37 | 1. From lifetime manager 38 | 1. From pipeline 39 | 1. Manage created objects 40 | 41 | -------------------------------------------------------------------------------- /specs/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Introduction 2 | uid: Specification.Unity 3 | #- name: Terms and Definitions 4 | # uid: Specification.Definitions 5 | - name: Method 6 | uid: Specification.Method 7 | - name: Field 8 | uid: Specification.Field 9 | - name: Property 10 | uid: Specification.Property 11 | - name: Specification 12 | uid: Specification.Unity 13 | 14 | -------------------------------------------------------------------------------- /specs/workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Specification.Workflow 3 | title: Workflow 4 | --- 5 | 6 | ### Setup 7 | 8 | Before container could be used it should be prepared for operation. 9 | 10 | #### Creating Container 11 | 12 | ##### Root 13 | 14 | ##### Scopes 15 | 16 | #### Type Contracts 17 | 18 | ##### Implicit 19 | 20 | ##### Mapping 21 | 22 | ##### Explicit 23 | 24 | * Instance 25 | * Factory 26 | * Type 27 | 28 | ### Provide Services 29 | 30 | #### Locate Contract 31 | 32 | ##### Existing 33 | 34 | ##### Hierarchical 35 | 36 | ##### None 37 | 38 | ###### Create Locally 39 | 40 | ###### With the registration 41 | 42 | ###### At the root 43 | 44 | #### Execute contract 45 | 46 | ##### From lifetime manager 47 | 48 | ##### From pipeline 49 | 50 | ### Manage created objects 51 | 52 | ### Teardown 53 | 54 | #### Dispose child scopes 55 | 56 | #### Dispose managed objects -------------------------------------------------------------------------------- /src/Documentation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28407.52 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Container", "Container\src\Unity.Container.csproj", "{EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Specification.Tests", "Container\tests\Unity.Specification\Unity.Specification.Tests.csproj", "{EE6E1971-4752-4444-9211-70BDE3CC4014}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Abstractions", "Abstractions\src\Unity.Abstractions.csproj", "{2A50E743-8817-41DB-BD23-6F9625665EF7}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Specification", "SpecificationTests\src\Unity.Specification.csproj", "{DBEC49D6-88ED-4717-A827-23BADE3DC5E1}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Specification.Diagnostic", "SpecificationTests\diagnostic\Unity.Specification.Diagnostic.csproj", "{510FC085-87EF-4EB8-85EB-6C1E0F629313}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Specification.Tests.Diagnostic", "Container\tests\Unity.Diagnostic\Unity.Specification.Tests.Diagnostic.csproj", "{5F84ACD0-148C-4DE0-ADCA-073B5C66BAD1}" 17 | EndProject 18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Specification", "Specification", "{F8CC6AB5-0A31-4DD5-9926-72CCC64E34F7}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BF3AB5C4-79AF-4A82-8D53-B4DA476D363F}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {EE1F752C-1FAB-41AD-AD63-857D0E62AB6B}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {EE6E1971-4752-4444-9211-70BDE3CC4014}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {EE6E1971-4752-4444-9211-70BDE3CC4014}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {EE6E1971-4752-4444-9211-70BDE3CC4014}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {2A50E743-8817-41DB-BD23-6F9625665EF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {2A50E743-8817-41DB-BD23-6F9625665EF7}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {2A50E743-8817-41DB-BD23-6F9625665EF7}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {2A50E743-8817-41DB-BD23-6F9625665EF7}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {DBEC49D6-88ED-4717-A827-23BADE3DC5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {DBEC49D6-88ED-4717-A827-23BADE3DC5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {DBEC49D6-88ED-4717-A827-23BADE3DC5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {510FC085-87EF-4EB8-85EB-6C1E0F629313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {510FC085-87EF-4EB8-85EB-6C1E0F629313}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {510FC085-87EF-4EB8-85EB-6C1E0F629313}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {5F84ACD0-148C-4DE0-ADCA-073B5C66BAD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {5F84ACD0-148C-4DE0-ADCA-073B5C66BAD1}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {5F84ACD0-148C-4DE0-ADCA-073B5C66BAD1}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(NestedProjects) = preSolution 53 | {EE6E1971-4752-4444-9211-70BDE3CC4014} = {BF3AB5C4-79AF-4A82-8D53-B4DA476D363F} 54 | {DBEC49D6-88ED-4717-A827-23BADE3DC5E1} = {F8CC6AB5-0A31-4DD5-9926-72CCC64E34F7} 55 | {510FC085-87EF-4EB8-85EB-6C1E0F629313} = {F8CC6AB5-0A31-4DD5-9926-72CCC64E34F7} 56 | {5F84ACD0-148C-4DE0-ADCA-073B5C66BAD1} = {BF3AB5C4-79AF-4A82-8D53-B4DA476D363F} 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {5AAFE72A-A2F4-4EE5-B3E2-B8E1E4652456} 60 | EndGlobalSection 61 | GlobalSection(Performance) = preSolution 62 | HasPerformanceSessions = true 63 | EndGlobalSection 64 | GlobalSection(Performance) = preSolution 65 | HasPerformanceSessions = true 66 | EndGlobalSection 67 | GlobalSection(Performance) = preSolution 68 | HasPerformanceSessions = true 69 | EndGlobalSection 70 | GlobalSection(Performance) = preSolution 71 | HasPerformanceSessions = true 72 | EndGlobalSection 73 | GlobalSection(Performance) = preSolution 74 | HasPerformanceSessions = true 75 | EndGlobalSection 76 | GlobalSection(Performance) = preSolution 77 | HasPerformanceSessions = true 78 | EndGlobalSection 79 | GlobalSection(Performance) = preSolution 80 | HasPerformanceSessions = true 81 | EndGlobalSection 82 | GlobalSection(Performance) = preSolution 83 | HasPerformanceSessions = true 84 | EndGlobalSection 85 | GlobalSection(Performance) = preSolution 86 | HasPerformanceSessions = true 87 | EndGlobalSection 88 | GlobalSection(Performance) = preSolution 89 | HasPerformanceSessions = true 90 | EndGlobalSection 91 | EndGlobal 92 | -------------------------------------------------------------------------------- /toc.yml: -------------------------------------------------------------------------------- 1 | - name: Overview 2 | href: Articles/ 3 | #- name: Specification 4 | # href: Specs/ 5 | - name: Tutorials 6 | href: Tutorials/ 7 | - name: Api Reference 8 | href: api/ 9 | homepage: api/index.md 10 | -------------------------------------------------------------------------------- /tutorials/Annotation/annotation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation 3 | title: Attributed Injection Model 4 | --- 5 | 6 | # Attributed Injection Model 7 | 8 | One of the most useful and powerful techniques when using Unity is to take advantage of dependency injection for the parameters of class constructors and methods, and for the values of fields and properties. This approach allows you to resolve and populate the entire hierarchy of objects used in your application based on type registrations and mappings defined in the container, with the subsequent advantages this offers. 9 | 10 | You can specify constructor, field, property, and method call injection information in configuration or by adding registrations to the container at run time. You can also apply attributes to members of your classes to indicate injection targets. When you resolve these classes through the container, Unity will generate instances of the dependent objects and wire up the injection targets with these instances. 11 | 12 | ## Using Injection Attributes 13 | 14 | Normally, Unity performs selection of the constructor automatically by choosing the most complex constructor it can satisfy with dependencies and populating these parameters with resolved values when it constructs the object. In some cases, for various reasons, the constructor could not be selected successfully and container may throw an exception. 15 | 16 | ### Constructor Annotation 17 | 18 | To disambiguate selection or to override automatic behavior you could specify which constructor Unity should use to construct the object by marking it with [InjectionConstructor](xref:Unity.InjectionConstructorAttribute) attribute. 19 | 20 | ### Member Annotation 21 | 22 | Property, field, and method call injections do not occur automatically unless registered with appropriate injection members at run time. To enable automatic member injection for types you can add attributes to the members of your classes to force injection of dependent objects when the target class is resolved. 23 | 24 | #### Required and Optional 25 | 26 | Fields, Properties, and Parameters could be annotated with either [Dependency](xref:Unity.DependencyAttribute) or [OptionalDependency](xref:Unity.OptionalDependencyAttribute) attributes to indicate that these require values to be injected. For annotating methods you wish to be called during initialization you could use [InjectionMethod](xref:Unity.InjectionMethodAttribute) 27 | 28 | For more information, see: 29 | 30 | * [Annotating types for **Constructor** invocation](xref:Tutorial.Annotation.Constructor) 31 | * [Annotating types for **Method** invocation](xref:Tutorial.Annotation.Method) 32 | * [Annotating **Parameter** for injection](xref:Tutorial.Annotation.Parameter) 33 | * [Annotating types for **Field** injection](xref:Tutorial.Annotation.Field) 34 | * [Annotating types for **Property** injection](xref:Tutorial.Annotation.Property) 35 | -------------------------------------------------------------------------------- /tutorials/Annotation/constructor.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation.Constructor 3 | title: Annotating Type for Constructor Injection 4 | --- 5 | 6 | # Selecting Constructor 7 | 8 | To select constructors you create through the Unity container, you can use the following three techniques: 9 | 10 | * [Automatic Constructor Injection](xref:Tutorial.Selection.Constructor). With this technique, you allow the Unity container to select a constructor and to satisfy any constructor dependencies defined in parameters of the constructor automatically. For more information see . 11 | 12 | * [Constructor Injection using explicit registration](xref:Tutorial.Injection.Constructor). With this technique, you register the [Type](xref:System.Type) and apply an [Injection Constructor Member](xref:Unity.Injection.InjectionConstructor) that specifies the dependencies to the registration. For more information see 13 | 14 | * **Annotated Constructor Injection**. With this technique, you apply [InjectionConstructor](xref:Unity.InjectionConstructorAttribute) attribute to one of the class constructors to designate it to be used to instantiate an instance. 15 | 16 | ## Annotated Constructor Injection 17 | 18 | Constructor Injection with Attribute Annotation allows you to apply attributes to the class' constructor designating it for dependency injection. When creating the class, Unity will always (unless explicitly overwritten in Registration) use that constructor. You only need to use this technique when there is more than one constructor in the target type. 19 | 20 | ### Annotating a Constructor 21 | 22 | When a target class contains more than one constructor and the automatic algorithm does not provide desired selection, you may use the [InjectionConstructor](xref:Unity.InjectionConstructorAttribute) attribute to specify the constructor you wish to use for injection. 23 | 24 | Consider the following [Type](xref:System.Type): 25 | 26 | [!code-csharp [class Service](../../src/SpecificationTests/src/Constructor/Attribute/Setup.cs#class_service)] 27 | 28 | In this example type `Service` contains four public constructors. Three of these constructors have one parameter each. A [Type](xref:System.Type) like this creates an ambiguity that Unity could not resolve by itself. 29 | 30 | > [!WARNING] 31 | > During resolution, the container will pick the first constructor it could satisfy with dependencies and will use it. In the example above, it could be any of the three constructors with one parameter. 32 | 33 | The container is not trying to validate all available contractors during normal execution. 34 | 35 | > [!NOTE] 36 | > If [Diagnostic](xref:Tutorial.Extension.Diagnostic) extension is enabled, Unity will throw an exception reporting ambiguous constructors. 37 | 38 | Normally, Unity would select the third constructor with three parameters, but by annotating the second constructor with the attribute you force Unity to use it during resolution. 39 | 40 | ### Multiple Constructor Annotations 41 | 42 | Annotating multiple constructors with injection parameters is not recommended. Unity is not guaranteed to process constructors in certain order. If multiple constructors are annotated, behavior might change from version to version. 43 | 44 | > [!NOTE] 45 | > If [Diagnostic](xref:Tutorial.Extension.Diagnostic) extension is enabled, Unity will throw an exception reporting ambiguous constructor annotations. -------------------------------------------------------------------------------- /tutorials/Annotation/field.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation.Field 3 | title: Annotating types for Field injection 4 | --- 5 | 6 | # Annotating types for Field injection 7 | 8 | By default Unity does not inject any fields of the classes it creates. 9 | 10 | To enable field injection you need to configure Unity during registration of annotate appropriate fields with dependency attributes. Unity supports two types of field injection: 11 | 12 | * Required injection - Unity either satisfies this dependency or throws an exception 13 | * Optional injection - Unity either satisfies this dependency or returns `null` 14 | 15 | ## Field injection 16 | 17 | -------------------------------------------------------------------------------- /tutorials/Annotation/method.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation.Method 3 | --- 4 | 5 | # Annotating types for Method invocation 6 | 7 | Method invocation is an optional step you can add to the created object's initialization. Any accessible method could be invoked, provided Unity can satisfy all the parameters with appropriate values. 8 | 9 | ## Method Invocation 10 | 11 | To enable method invocation during object initialization you could apply [InjectionMethod](xref:Unity.InjectionMethodAttribute) attribute to the method you want to be executed. 12 | 13 | ```cs 14 | public class Service 15 | { 16 | ... 17 | private void PreInitialize(...) 18 | { 19 | ... 20 | } 21 | 22 | [InjectionMethod] 23 | public void Initialize(...) 24 | { 25 | ... 26 | } 27 | 28 | public void PostInitialize(...) 29 | { 30 | ... 31 | } 32 | } 33 | ``` 34 | 35 | In the example above, attribute [InjectionMethod](xref:Unity.InjectionMethodAttribute) is applied to method `Initialize(...)` and the method will be executed immediately after the object is created. 36 | 37 | ## Multiple Method Invocation 38 | 39 | Unity does not place any restrictions on how many methods of the class will be invoked during the initialization. You could mark any and all methods with the attribute and Unity will execute them all: 40 | 41 | ```cs 42 | public class Service 43 | { 44 | ... 45 | 46 | [InjectionMethod] 47 | public void PreInitialize(...) 48 | { 49 | ... 50 | } 51 | 52 | [InjectionMethod] 53 | public void Initialize(...) 54 | { 55 | ... 56 | } 57 | 58 | [InjectionMethod] 59 | public void PostInitialize(...) 60 | { 61 | ... 62 | } 63 | } 64 | ``` 65 | 66 | ## Restrictions 67 | 68 | ### Static methods cannot be invoked 69 | 70 | Unity does not support invocation of static methods. Static methods annotated with [InjectionMethod](xref:Unity.InjectionMethodAttribute) attribute will be ignored. If [Unity Diagnostic](xref:Tutorial.Extension.Diagnostic) is enabled, the container will throw an exception when it encounters such an annotation. 71 | 72 | ### Methods with `ref` or `out` parameters cannot be invoked 73 | 74 | Methods containing `ref` or `out` parameters cannot be invoked during initialization. The container will throw an exception if encountered these. 75 | 76 | ```cs 77 | public class Service 78 | { 79 | [InjectionMethod] // Error 80 | public void Method1(ref object refObject) 81 | { 82 | ... 83 | } 84 | ... 85 | 86 | [InjectionMethod] // Error 87 | public void Method2(out object outObject) 88 | { 89 | ... 90 | } 91 | } 92 | ``` 93 | 94 | In the example above neither `Method1(ref object refObject)` nor `Method2(out object outObject)` should be annotated for invocation. Doing so will create an error condition. 95 | 96 | ### Invoking `private` and `protected` methods is not allowed 97 | 98 | Although it is technically possible to call `private` and `protected` methods of the class, Unity does not support this feature. This restriction is implemented to impose consistency with accessibility principles of `C#` language. 99 | 100 | Unity will ignore attributes on non-accessible methods. 101 | 102 | ```cs 103 | public class Service 104 | { 105 | ... 106 | 107 | [InjectionMethod] // Error 108 | protected void ProtectedMethod(...) 109 | { 110 | ... 111 | } 112 | } 113 | ``` 114 | 115 | In the example above method `ProtectedMethod(...)` will not be called. 116 | 117 | If [Unity Diagnostic](xref:Tutorial.Extension.Diagnostic) is enabled, the container will throw an exception when it encounters this condition. 118 | 119 | For more information see [Unity Diagnostic](xref:Tutorial.Extension.Diagnostic). -------------------------------------------------------------------------------- /tutorials/Annotation/parameter.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation.Parameter 3 | --- 4 | 5 | # Annotating Constructors and Methods for Parameter Injection -------------------------------------------------------------------------------- /tutorials/Annotation/property.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Annotation.Property 3 | title: Property Injection Annotation 4 | --- 5 | 6 | # Annotating Objects for Property Injection -------------------------------------------------------------------------------- /tutorials/Annotation/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Constructor 2 | uid: Tutorial.Annotation.Constructor 3 | - name: Parameter 4 | uid: Tutorial.Annotation.Parameter 5 | - name: Method 6 | uid: Tutorial.Annotation.Method 7 | - name: Field 8 | uid: Tutorial.Annotation.Field 9 | - name: Property 10 | uid: Tutorial.Annotation.Property 11 | -------------------------------------------------------------------------------- /tutorials/Composition/BuildUp/buildup.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.BuildUp 3 | title: Object Build Up 4 | --- 5 | 6 | # Build Up -------------------------------------------------------------------------------- /tutorials/Composition/BuildUp/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Build Up 2 | uid: Tutorial.BuildUp 3 | -------------------------------------------------------------------------------- /tutorials/Composition/Generics/deferred.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Deferred 3 | title: Deferred Resolution 4 | --- 5 | 6 | 7 | # Deferring the Resolution of Objects 8 | Unity provides a technique to facilitate holding a reference to an object you need, but do not want to construct right away. You wish to defer resolution of the object. Instead of creating a factory for the type and injecting the factory into your class, then using it to create the type you want you can use the .NET standard type Func (C#) or Func(Of T) (Visual Basic) with the Resolve method. This returns a delegate that, when invoked, calls into the container and returns an instance of the specified type (in this case, T). 9 | 10 | You can even create a delegate in this way without creating a registration or mapping for the specified type in the container if you wish. Because the resolve action only takes place when you invoke the delegate, subsequent registrations added to the container are available when the target object is resolved. This means that you can manipulate the registrations and mappings in the container at any point before you resolve the target object (although you can obviously register the type before you create the delegate if you prefer). 11 | 12 | For example, you can create a delegate for a component named MyClass, and then register a mapping for it and perform deferred resolution when required using the following code. 13 | ```cs 14 | // Create a Unity container 15 | IUnityContainer myContainer = new UnityContainer(); 16 | 17 | // Create a delegate for the IMyClass interface type 18 | var resolver = myContainer.Resolve>(); 19 | 20 | // ... other code here... 21 | 22 | // Register a mapping for the IMyClass interface to the MyClass type 23 | myContainer.RegisterType(); 24 | 25 | // Resolve the mapped target object 26 | IMyClass myClassInstance = resolver(); 27 | ``` 28 | You can use this approach when you resolve the type using the Resolve method, or you can specify the delegate when you configure constructor, property setter, or method call injection. You can also use named (non-default) registrations by including the registration name in the call to the Resolve method and the RegisterType method, just as you would when using these methods for non-deferred resolution. 29 | 30 | In addition, you can use this feature to perform deferred resolution of multiple named registrations, as an alternative to using the ResolveAll method. For example, if you have multiple named registrations for the IMyClass interface to suitable concrete types, you can obtain a collection of the resolved types. The following code illustrates this. 31 | ```cs 32 | // Create a Unity container 33 | IUnityContainer myContainer = new UnityContainer(); 34 | 35 | // Create an IEnumerable resolver for the IMyClass interface type 36 | var resolver = myContainer.Resolve>>(); 37 | 38 | // ... other code here... 39 | 40 | // Register mappings for the IMyClass interface to appropriate concrete types 41 | myContainer.RegisterType("First"); 42 | myContainer.RegisterType("Second"); 43 | myContainer.RegisterType("Third"); 44 | 45 | // Resolve a collection of the mapped target objects 46 | IEnumerable myClassInstances = resolver(); 47 | ``` 48 | You can also use the deferred resolver to resolve instance registrations. For example, the following code shows how you can resolve an IEnumerable collection of string values. 49 | ```cs 50 | // Create a Unity container 51 | IUnityContainer myContainer = new UnityContainer(); 52 | 53 | // Create an IEnumerable resolver for string instance registrations 54 | var resolver = myContainer.Resolve>>(); 55 | 56 | // ... other code here... 57 | 58 | // Register mappings for the IMyClass interface to appropriate concrete types 59 | myContainer.RegisterInstance("one", "FirstString"); 60 | myContainer.RegisterInstance("two", "SecondString"); 61 | myContainer.RegisterInstance("three", "ThirdString"); 62 | 63 | // Resolve a collection of the strings 64 | IEnumerable myStringInstances = resolver(); 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /tutorials/Composition/Generics/generics.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Generics 3 | title: Generics 4 | --- 5 | 6 | # Generic Types 7 | 8 | You resolve generic types in much the same way as you resolve non-generic types. The primary difference is with unbound types. The specification of the type arguments depend on the definition of the mapped type or the type you are resolving: 9 | 10 | * If the mapped type or the type you are resolving is a **bound** type, you can only resolve an instance of the type using the defined type arguments. For example, if the mapped type has type arguments of type string and DateTime, you must specify these in the call to the Resolve method. 11 | 12 | * If the mapped type or the type you are resolving is an **unbound** type, you can resolve an instance of the type using any types for the type arguments. The target class must be able to process arguments of the type you specify. For example, if one of the type arguments you specify is the type Boolean, the class must be able to handle Boolean values for that argument and not attempt to parse the value into a DateTime instance. -------------------------------------------------------------------------------- /tutorials/Composition/Generics/lazy.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lazy 3 | title: Lazy 4 | --- 5 | 6 | # Lazy -------------------------------------------------------------------------------- /tutorials/Composition/Generics/metadata.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Generics.Metadata 3 | title: Metadata 4 | --- 5 | 6 | # Generic Metadata -------------------------------------------------------------------------------- /tutorials/Composition/Generics/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Metadata 2 | uid: Tutorial.Generics.Metadata 3 | - name: Lazy 4 | uid: Tutorial.Lazy 5 | - name: Deferred 6 | uid: Tutorial.Deferred 7 | -------------------------------------------------------------------------------- /tutorials/Composition/Mapping/generic.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Mapping.Generic 3 | title: Generic Type Mapping 4 | --- 5 | 6 | # Generic Type Mapping 7 | -------------------------------------------------------------------------------- /tutorials/Composition/Mapping/implementation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Mapping.Implementation 3 | title: Service to Implementation Mapping 4 | --- 5 | 6 | # Service to Implementation Mapping 7 | 8 | Service to Implementation Mapping is done during the service registration. 9 | 10 | ## The Service Itself 11 | 12 | The simplest type of registration is when the service is registered by its own type. For Type and Instance registration, you can do so by simply registering the type or the instance: 13 | 14 | ```cs 15 | container.RegisterType(); 16 | container.RegisterInstance(new Foo()); 17 | ``` 18 | 19 | For example, a factory has to specify the type it is registered under: 20 | 21 | ```cs 22 | container.RegisterFactory((c, t, n) => new Foo()); 23 | ``` 24 | 25 | ## Mapping Contract to Implementation 26 | 27 | When you map Registered type to Implementation type, you specify a service type first and then the implementation type: 28 | 29 | ```cs 30 | container.RegisterType(); 31 | container.RegisterInstance(new Foo()); 32 | ``` 33 | 34 | In this case of the factory registration, the container does not care how it is implemented by the factory, but rather how it is registered: 35 | 36 | ```cs 37 | container.RegisterFactory((c, t, n) => new Foo()); 38 | ``` 39 | 40 | ## Building and Mapping to Implementation 41 | 42 | Mapping allows redirection to the existing registrations and services, as well as building new instances of implementation types. 43 | 44 | ### Mapping to Existing Service 45 | 46 | The Unity container supports a scenario where a mapping does not create a type itself but rather references existing services registered with the container. Consider the following: 47 | 48 | ```cs 49 | public class Foo : IFoo1, IFoo2 50 | { 51 | public Foo() 52 | { 53 | } 54 | 55 | public Foo(object _) 56 | { 57 | } 58 | } 59 | 60 | container.RegisterInstance(new Foo(), InstanceLifetime.Singleton); 61 | 62 | container.RegisterType(); 63 | ``` 64 | 65 | The container has a registration for type `Foo`. When the interface `IFoo1` is mapped to `Foo` it instructs the container to resolve the default implementation for the type `Foo`. Because the mapping does not provide any instructions about how the type should be built, the default implementation or existing registration should be used. 66 | 67 | So, when the container is resolving `IFoo1` it will first check if `Foo` is already registered and it will use the registration to satisfy the request. 68 | 69 | If a mapping references a non existing service, the container will try to build the service from the implementation type. 70 | 71 | ### Building an Implementation Type 72 | 73 | If the implementation type points to no existing registration or if an instance has to be created using certain rules, the container will create a new, independent pipeline and execute it. So if you register `IFoo2` it will look like this: 74 | 75 | ```cs 76 | container.RegisterType(Invoke.Constructor()); 77 | ``` 78 | 79 | The Unity container will not redirect to `Foo`. Instead, it will create a new instance of `Foo` and call the default constructor. 80 | -------------------------------------------------------------------------------- /tutorials/Composition/Mapping/mapping.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Mapping 3 | title: Type Mapping 4 | --- 5 | 6 | # Type Mapping 7 | 8 | In service oriented architecture, components expose services through well known contracts. In `C#` terms, the contracts are the abstract classes or interfaces that these components and services are exposing. Service type, in most of the cases, means the interfaces implementing the contract. And the components are called Implementation types. 9 | 10 | Unity allows users to publish these components and make all of the contracts they implement available to clients. This publishing and "advertisement" is done by registering both types and interfaces (contracts) associated with the components. 11 | 12 | ## Registration Type 13 | 14 | Registration type is the type of the "contract" that this service provides. It could be the [Type](xref:System.Type) of the service itself within any of the base types it implements. 15 | 16 | ## Service to Implementation Mapping 17 | 18 | The mapping is done when service is registered. Any type of registration (Type, Factory, Instance) allows users to associate a service with different contracts. 19 | -------------------------------------------------------------------------------- /tutorials/Composition/Mapping/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Service To Implementation 2 | uid: Tutorial.Mapping.Implementation 3 | - name: Generic Mapping 4 | uid: Tutorial.Mapping.Generic 5 | -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/dependency.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Override.Dependency 3 | title: Dependency Override 4 | --- 5 | 6 | # Dependency Override 7 | 8 | [Dependency override](xref:Unity.Resolution.DependencyOverride) is a special kind of override. It does not target any members or parameters. Instead, it overrides a contract that the container would have resolved when requested. In other words, when the dependency is being resolved from the container, if the contract matches, it will provide that value instead. 9 | 10 | ## Injected Members and Dependency overrides 11 | 12 | There are two types of dependency injection the Unity container supports: 13 | 14 | * Value injection 15 | * Value resolution 16 | 17 | To understand how [Dependency Override](xref:Unity.Resolution.DependencyOverride) works you need to remember, it only overrides resolved values. 18 | 19 | ### Injected Values 20 | 21 | Values are injected during [Type](xref:System.Type) registration. At that time you provide instructions on how to initialize the [Type](xref:System.Type) and its members. The members injected with values via Injection Members will not be affected by the [Dependency Override](xref:Unity.Resolution.DependencyOverride). 22 | 23 | ### Resolved Values 24 | 25 | All the dependencies that are not injected with values, or injected with resolve redirection are potential targets for the override. Anything that asks the container to resolve a value can be [Dependency Overridden](xref:Unity.Resolution.DependencyOverride). 26 | 27 | ## Overriding dependencies 28 | 29 | [Dependency Override](xref:Unity.Resolution.DependencyOverride) enables you to specify an override for the specified dependency type contract. It, enables you to pass in an object that will be returned as a dependency, instead of the one resolved from the container. 30 | -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/field.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Override.Field 3 | title: Field Overrides 4 | --- 5 | 6 | # Field Override 7 | 8 | FieldOverride enables you to override the value for a specified field. Only the field value is overridden, not the properties selected. Its behavior is the same as ParameterOverride. The use of the OnType method enables you to specify a type to constrain the override to. -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/override.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Override 3 | title: Resolution Override 4 | --- 5 | 6 | # Overriding dependencies during resolution 7 | 8 | The parameter and dependency overrides, ParameterOverride and DependencyOverride, are ResolverOverride implementations that provide support for overriding the registration information for resolving instances of types. When you call the Resolve method, these classes enable you to override values specified when the type was registered, such as by a RegisterType or RegisterInstance statement. In effect, RegisterType supplied values are overridden by Resolve supplied values. 9 | 10 | Use ParameterOverride to override the specified constructor parameter or parameters. The override applies everywhere the parameter appears unless you use OnType to constrain the override to a specified type. Since the purpose of overrides is to affect the resolution of dependencies for all relevant created objects, not just the object requested in the call to Resolve, unconstrained overrides can produce errors if there are unconstrained ParameterOverride parameters that match parameters with the same name but different types on the selected constructors for objects created in a given resolve operation. 11 | 12 | Use PropertyOverride to override the value of the specified property or properties. The override applies everywhere the property appears unless you use OnType to constrain the override to a specified type. 13 | 14 | Use DependencyOverride to override the value injected whenever there is a dependency of the given type. DependencyOverride overrides all instances where the type matches. Both parameter overrides and dependency overrides support generic types and multiple overrides. 15 | 16 | Overrides work with the constructor that is selected for the type, by attribute or configuration. If the constructor to be used is not identified with an attribute or explicit container configuration, then the default behavior is that the constructor with the most parameters will be used. 17 | 18 | A parameter and property override never affects what element gets selected. They only control the value of the specified parameter or property. You do not change which constructor is called with an override, and you do not change which properties get set with an override. 19 | 20 | * [Parameter Overrides](xref:Tutorial.Resolution.Override.Parameter) 21 | * [Property Overrides](xref:Tutorial.Resolution.Override.Property) 22 | * [Field Overrides](xref:Tutorial.Resolution.Override.Field) 23 | * [Dependency Overrides](xref:Tutorial.Resolution.Override.Dependency) 24 | 25 | ![Resolver Override](/images/resolver-override.png) 26 | -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/parameter.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Override.Parameter 3 | title: Parameter Override 4 | --- 5 | 6 | # Parameter Override 7 | 8 | Unity enables you to pass in values for parameter dependencies to override a parameter passed to a given constructor or method. Only the parameter value is overridden, not the constructor or method selection. -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/property.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Override.Property 3 | title: Property Override 4 | --- 5 | 6 | # Property Override 7 | 8 | PropertyOverride enables you to override the value for a specified property. Only the property value is overridden, not the properties selected. Its behavior is the same as ParameterOverride. The use of the OnType method enables you to specify a type to constrain the override to. -------------------------------------------------------------------------------- /tutorials/Composition/Overrides/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Parameter 2 | uid: Tutorial.Resolution.Override.Parameter 3 | - name: Field 4 | uid: Tutorial.Resolution.Override.Field 5 | - name: Property 6 | uid: Tutorial.Resolution.Override.Property 7 | - name: Dependency 8 | uid: Tutorial.Resolution.Override.Dependency 9 | -------------------------------------------------------------------------------- /tutorials/Composition/Resolution/resolution.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution 3 | title: Object Resolution 4 | --- 5 | 6 | # Resolving Objects 7 | 8 | There are types you can create immediately from the container and there are types that require registration. Generally any primitive type would require registration and all classes are available immediately. 9 | 10 | You can use the Unity container to generate instances of any object that has a public constructor (in other words, objects that you can create using the new operator). When you call the Resolve method and specify the type that is not registered, the container simply generates and returns an instance of that type. However, the only time that this is realistically practical is when the object you are generating does not have ambiguities Unity could not resolve or contains dependency attributes that the container will use to inject dependent objects into the requested object. 11 | 12 | The Unity container identifies type registrations and type mappings in the container using a type and, optionally, a name. The type is an interface or a class (usually an interface or base class) that the desired concrete object type implements or inherits. This identifies the mapping so that the container can retrieve the correct object type in response to a call to the `Resolve` method. Where there is more than one mapping for the same type, the optional name differentiates these mappings and allows code to specify which of the mappings for that type to use. 13 | 14 | The provision of both generic and non-generic overloads of many of the Unity container methods ensures that Unity can be used in languages that do not support generics. You can use either approach (the generic or the non-generic overloads) in your code and mix them as required. 15 | 16 | The following topics describe how you can resolve objects using the Resolve or BuildUp methods: 17 | 18 | * [Resolving an Object by Type](xref:Tutorial.Resolution.Type) 19 | * [Resolving collections of Objects of a Particular Type](xref:Tutorial.Collections) 20 | * [Resolving Generic Types](xref:Tutorial.Generics) 21 | * [Deferring the Resolution of Objects](xref:Tutorial.Deferred) 22 | * [Overrides](xref:Tutorial.Resolution.Override) 23 | 24 | For more information about how you can configure Unity with type registrations and mappings, see Registration. 25 | 26 | For more information about how you can perform dependency injection on existing object instances, see Using BuildUp to Wire Up Objects Not Created by the Container. -------------------------------------------------------------------------------- /tutorials/Composition/Resolution/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Resolution 2 | uid: Tutorial.Resolution 3 | - name: Type 4 | href: type.md 5 | -------------------------------------------------------------------------------- /tutorials/Composition/Resolution/type.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Type 3 | title: Resolution By Type 4 | --- 5 | 6 | # Resolving an Object by Type 7 | 8 | Unity provides a method named [Resolve](xref:Unity.IUnityContainer#Unity_IUnityContainer_Resolve_System_Type_System_String_Unity_Resolution_ResolverOverride___) that you can use to resolve an object by type, and optionally by providing a registration name. Registrations that do not specify a name are referred to as default registrations. This topic describes how to use the [Resolve](xref:Unity.IUnityContainer#Unity_IUnityContainer_Resolve_System_Type_System_String_Unity_Resolution_ResolverOverride___) method to resolve types and mappings registered as default registrations. 9 | 10 | ## The Resolve Method Overloads for Default Registrations 11 | 12 | The following table describes the overloads of the Resolve method that return instances of objects based on the default registrations and mappings with the container. The API for the Unity container contains both generic and non-generic overloads of this method so that you can use it with languages that do not support the generics syntax. 13 | 14 | | Method | Description | 15 | |-----|-----| 16 | | `Resolve()` | Returns an instance of the type registered with the default name as the type T. | 17 | | `Resolve(Type t)` | Returns an instance of the default type registered with the container as the type t. | 18 | | `Resolve(string name)` | Returns an instance of the type registered with the container as the type T and with the specified name. Names are case sensitive. | 19 | | `Resolve(Type t, string name)` | Returns an instance of the type registered with the container as the type t and with the specified name. Names are case sensitive. | 20 | 21 | ## Using the Resolve Method with Default Registrations 22 | 23 | The following examples show how you can use the Resolve method to create or obtain a reference to an object defined in the container configuration. Typically you will register a type mapping between an interface and a concrete type that implements it, or between a base class and a concrete type that inherits it. The examples use the run-time methods of the container to register the types it will resolve. 24 | 25 | ### Resolving Types Registered as Interfaces 26 | 27 | The following code registers a mapping for an interface named IService and specifies that the container should return an instance of the CustomerService class (which implements the IService interface). In this case, the type IService identifies the registration type. Code that requests an instance of the type IService receives an instance of the CustomerService class. The following example uses the generic overloads of the container methods. 28 | 29 | ```cs 30 | IUnityContainer container = new UnityContainer(); 31 | container.RegisterType(); 32 | 33 | var instance = container.Resolve(); 34 | ``` 35 | 36 | Alternatively, you can use the non-generic overloads of the methods. The following code achieves the same result. 37 | 38 | ```cs 39 | IUnityContainer container = new UnityContainer(); 40 | container.RegisterType(); 41 | 42 | var instance = (IService)container.Resolve(typeof(IMyService)); 43 | ``` 44 | 45 | ### Resolving Types Registered as Base Classes 46 | 47 | When you need to register a mapping for a base class or other object type (instead of an interface), you use the overloads of the RegisterType and Resolve methods that accept object type names. The following examples show the use of the overloads of the RegisterType and Resolve methods that accept object type names as the registration identifier. 48 | 49 | The following code registers a mapping for an object named MyBaseService and specifies that the container should return an instance of the CustomerService class (which inherits from the MyBaseService class). In this case, the type MyBaseService identifies the registration. Code that requests an instance of the type MyBaseService receives an instance of the CustomerService class. 50 | 51 | ```cs 52 | IUnityContainer myContainer = new UnityContainer(); 53 | myContainer.RegisterType(); 54 | 55 | MyBaseService myServiceInstance = myContainer.Resolve(); 56 | ``` 57 | 58 | Alternatively, you can use the non-generic overloads of the methods. The following code achieves the same result. 59 | 60 | ```cs 61 | IUnityContainer myContainer = new UnityContainer(); 62 | myContainer.RegisterType(typeof(MyBaseService), typeof(CustomerService)); 63 | 64 | MyBaseService myServiceInstance = (MyBaseService)myContainer.Resolve(typeof(MyBaseService)); 65 | ``` 66 | 67 | ## Using the Resolve Method with Named Registrations 68 | 69 | If you need to create multiple registrations for the same type, you can specify a name to differentiate each registration. Then, to retrieve an object of the appropriate type, you specify the name and the registered type. Following examples demonstrate the technique: 70 | 71 | ```cs 72 | IUnityContainer container = new UnityContainer(); 73 | container.RegisterType(); 74 | container.RegisterType("name"); 75 | container.RegisterType("other name"); 76 | 77 | var instance = container.Resolve("name"); 78 | ``` 79 | 80 | Alternatively, you can use the non-generic overloads of the methods. The following code achieves the same result. 81 | 82 | ```cs 83 | IUnityContainer container = new UnityContainer(); 84 | container.RegisterType(); 85 | container.RegisterType("name"); 86 | container.RegisterType("other name"); 87 | 88 | var instance = (IService)container.Resolve(typeof(IMyService), "other name"); 89 | ``` 90 | 91 | ### Note 92 | 93 | If the target class or object specifies any dependencies of its own, using constructor, property, or method call injection attributes, the instance returned will have these dependent objects injected automatically. 94 | 95 | By default, the RegisterType method registers a type with a transient lifetime, which means that the container will not hold onto a reference to the objects it creates when you call the Resolve method. Each time you call one of these methods, the container generates a new instance of the specified or mapped type. However, you can use lifetime managers to control the creation, lifetime, and disposal of objects if required. -------------------------------------------------------------------------------- /tutorials/Composition/Selection/constructor.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Selection.Constructor 3 | title: Automatic Constructor Selection 4 | --- 5 | 6 | # Selecting Constructor 7 | 8 | Proper selection of the constructor used for type instantiation is one of the most important aspects of the container operation. When creating an object, the container uses one of the following algorithms to select a constructor it will be using to initialize the object: 9 | 10 | * [Constructor Injection using explicit registration](xref:Tutorial.Injection.Constructor). With this technique, you register the [Type](xref:System.Type) and apply an [Injection Constructor](xref:Unity.Injection.InjectionConstructor) that specifies the dependencies to the registration. For more information see 11 | 12 | * [Constructor Annotation](xref:Tutorial.Annotation.Constructor). With this technique, you apply attribute to a class constructor that is used for injection. For more information see 13 | 14 | * **Automatic Constructor Selection**. This technique is used by the Unity container to select a constructor and to satisfy any constructor dependencies defined in parameters of the constructor if no [Annotation](xref:Tutorial.Annotation) or [Registration](xref:Tutorial.Registration) exists. 15 | 16 | ## Automatic Constructor Selection 17 | 18 | Automatic constructor selection is performed if no other information is available on how to create a [Type](xref:System.Type). Unity uses dynamic, real time algorithm to discover and select a constructor. 19 | 20 | The Unity container will try to execute the most complex constructor it can provide with appropriate dependencies. In other words, if the container can resolve and/or inject all parameters of the constructor, it will be selected. 21 | 22 | ### Creating Build Pipeline 23 | 24 | Selection process takes place during the first resolution of a [Type](xref:System.Type) contract. Unity container employs lazy resolution strategy. It will defer pipeline creation until the contract ([RegistrationType and Name](xref:Tutorial.Registration.Metadata)) is requested. 25 | 26 | The lazy approach allows registrations to proceed at random order and do not require dependencies to be registered before dependents. As long as all of these are available at the time of resolution Unity does not care in what order they were registered. 27 | 28 | ### Constructor Selection Steps 29 | 30 | One of the first steps, when creating a pipeline, is a constructor selection. Constructors are selected in the following order: 31 | 32 | * If present, use registered [Injection Constructor](xref:Unity.Injection.InjectionConstructor) 33 | * If present, annotated with an attribute 34 | * Automatically select constructor 35 | * Get all accessible constructors 36 | * Process constructors in ascending order from most complex to the default 37 | * Filter out [restricted](xref:Tutorial.Injection.Constructor#restrictions) constructors 38 | * Loop through parameters and check if 39 | * Is primitive 40 | * Is registered with the container 41 | * Has *default* value 42 | * Is resolvable type 43 | * Is registered with container 44 | * Select the first constructor the container can create 45 | 46 | The Unity container will select the first successful match and use it as a selection. 47 | 48 | > [!WARNING] 49 | > When more than one constructor could be matched at the same time, the order and constructor selection can not be guaranteed. 50 | 51 | During normal operation the container does not perform validation. 52 | 53 | > [!NOTE] 54 | > If [Diagnostic](xref:Tutorial.Extension.Diagnostic) extension is enabled, Unity will perform a selection validation and will throw an exception, reporting ambiguous constructors, if more than one constructor can be successfully selected with current configuration. 55 | 56 | If no constructor could be selected, the container will throw an exception. 57 | 58 | ### Pipeline retention 59 | 60 | Once the pipeline is created, it will be used to satisfy all subsequent requests for that contract. If you need to update or rebuild the pipeline, the contract has to be re-registered. -------------------------------------------------------------------------------- /tutorials/Composition/Selection/selection.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Resolution.Selection 3 | title: Selection 4 | --- -------------------------------------------------------------------------------- /tutorials/Composition/Selection/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Constructor 2 | uid: Tutorial.Selection.Constructor 3 | #- name: Field 4 | # uid: Tutorial.Selection.Field 5 | #- name: Property 6 | # uid: Tutorial.Selection.Properties 7 | #- name: Method 8 | # uid: Tutorial.Selection.Method 9 | -------------------------------------------------------------------------------- /tutorials/Composition/collections.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Collections 3 | title: Collections 4 | --- 5 | 6 | 7 | # Resolving collections of Objects of a Particular Type 8 | Unity supports creating multiple registration of the same type by adding a name to the registration. It is useful if you want to register different services of the same type. For example, if you have multiple printers and you want them all to be available to consumers you would register them like this: 9 | ```cs 10 | container.RegisterInstance(printer); // default printer 11 | container.RegisterInstance(printer1, "Office Printer"); 12 | container.RegisterInstance(printer2, "Printer at the deli on the street corner"); 13 | container.RegisterType("Office printer near me"); 14 | ``` 15 | When you want to obtain a list of all the registered objects of a specific type, `IPrinter` in this case, you can use the array `T[]` or `IEnumerable` of that type. The difference between array and enumerable resolution is that array only returns named (nondefault name) registrations where enumerable always returns all, named and unnamed registrations. 16 | 17 | ## Resolving array `T[]` 18 | When resolving array of a type, Unity will return an array containing only types registered with nondefault (other than `null`) names. In example above call to `Resolve` will return array of only three elements: 19 | ```cs 20 | IPrinter[] printers = container.Resolve(); 21 | Assert(3 == printers.Length) 22 | ``` 23 | Instance **printer** will not be returned because it was registered with no name. 24 | 25 | ## Resolving `IEnumerable` 26 | `IEnumerable` returns an enumerable containing all registrations of type T, including default (with name `null`) registrations. In example above it will return all four registrations: 27 | ```cs 28 | IPrinter[] printers = container.Resolve>(); 29 | Assert(4 == printers.Count()) 30 | ``` 31 | 32 | ## Resolving `List` of types 33 | Unity does not have any special provisions to support `List` but because `List` type's longest exposed constructor is 34 | ```cs 35 | public List(IEnumerable items) 36 | ``` 37 | Unity is able to resolve `List`. Consider this example: 38 | ```cs 39 | var printers = container.Resolve>(); 40 | Assert(4 == printers.Count) 41 | ``` 42 | Unity creates type `List` and during initialization selects longest constructor it can satisfy with dependencies (`List(IEnumerable items)`). It crates the enumeration and passes it to List constructor. Resulting instance is a list of all registrations of that type. 43 | 44 | -------------------------------------------------------------------------------- /tutorials/Composition/composition.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Composition 3 | title: Composition 4 | --- 5 | 6 | # Composition 7 | 8 | Composition is the creation and initialization of an object. During composition an object is created and initialized with all of its dependencies and initialization methods. 9 | 10 | Since each dependency might have its own dependencies an entire dependency graph has to be created and each node has to be initialized in order of priority. 11 | 12 | The Unity container supports two types of composition: 13 | 14 | ## Resolution 15 | 16 | Resolution is a process where an object is built from scratch. In other words, the container is allocating the memory of an object, calls a constructor with all of its dependencies and performs all necessary initialization required by the type. For more information see 17 | 18 | ## Building Up 19 | 20 | Building up is a process where the container does not create an object but initializes an already created object. This is useful when an object is part of an infrastructure and the author does not have access or control of how these are created. 21 | -------------------------------------------------------------------------------- /tutorials/Composition/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Resolution 2 | href: Resolution/toc.yml 3 | topicUid: Tutorial.Resolution 4 | - name: Build-Up 5 | href: BuildUp/toc.yml 6 | topicUid: Tutorial.BuildUp 7 | - name: Type Mapping 8 | href: Mapping/toc.yml 9 | topicUid: Tutorial.Mapping 10 | - name: Selection 11 | href: Selection/toc.yml 12 | topicUid: Tutorial.Resolution.Selection 13 | - name: Generics 14 | href: Generics/toc.yml 15 | topicUid: Tutorial.Generics 16 | - name: Collections 17 | href: collections.md 18 | - name: Overrides 19 | href: Overrides/toc.yml 20 | topicUid: Tutorial.Resolution.Override 21 | -------------------------------------------------------------------------------- /tutorials/Extensions/activation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Extension.Activation 3 | title: Force Activation Extension 4 | --- 5 | 6 | # Force Activation Extension -------------------------------------------------------------------------------- /tutorials/Extensions/compilation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Extension.Compilation 3 | title: Force Compilation Extension 4 | --- 5 | 6 | # Force Compilation Extension -------------------------------------------------------------------------------- /tutorials/Extensions/diagnostic.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Extension.Diagnostic 3 | title: Diagnostic Extension 4 | --- 5 | 6 | # Diagnostic 7 | 8 | Creating and configuring Unity container is a complicated process. A lot of things could go wrong and finding where it was misconfigured could be rather involved. To simplify debugging and to help fix issues Unity offers **Diagnostic** extension. 9 | 10 | ## Performance considerations 11 | 12 | The Unity container uses reflection for most of its operations. It gathers information about types, creates pipelines to create these types, and verifies everything all based on reflected data. Because of that it is rather resource extensive and relatively slow. 13 | 14 | To optimize performance, Unity engine does not do any runtime validation and only performs absolute minimum checks, just enough to be able to run. As result a lot of irregular conditions might go unnoticed. To remedy this, the container exposes **Diagnostic** extension which does thorough examination of all registration data and throws exceptions on any irregularities. 15 | 16 | ## Unity Diagnostic Extension 17 | 18 | **Diagnostic** extension, among other things, verifies the following conditions: 19 | 20 | * Cyclical references (The famous Stack Overflow Exception) 21 | * Validity of provided Injection Members 22 | * Improper referencing to itself 23 | * Invalid parameters in constructors and invoked methods 24 | 25 | ## Enabling Diagnostics 26 | 27 | The extension could be enabled in few different ways: 28 | 29 | ### Add Extension 30 | 31 | The most basic case is when extension is added via `AddExtension(...)` call. It works with either regular or generic methods. 32 | 33 | ```cs 34 | var container = new UnityContainer() 35 | .AddExtension(new Diagnostic()); 36 | ``` 37 | 38 | or 39 | 40 | ```cs 41 | var container = new UnityContainer() 42 | .AddExtension(); 43 | ``` 44 | 45 | The first method, one with `AddExtension(new Diagnostic())` is a bit faster. 46 | 47 | ### Using extension method 48 | 49 | For convenience, Unity container exposes [EnableDiagnostic()](https://github.com/unitycontainer/container/blob/master/src/Extensions/Diagnostic.cs) extension method. This method is equal to adding extension to the container. 50 | 51 | ```cs 52 | var container = new UnityContainer() 53 | .EnableDiagnostic(); 54 | ``` 55 | 56 | ### Enabling extension only in Debug 57 | 58 | The container provides conditional extension [EnableDebugDiagnostic()](https://github.com/unitycontainer/container/blob/master/src/Extensions/Diagnostic.cs). This method will only enable diagnostics in `DEBUG` mode. In this example 59 | 60 | ```cs 61 | var container = new UnityContainer(); 62 | container.EnableDebugDiagnostic(); 63 | ``` 64 | 65 | the extension is enabled only if calling method is compiled in Debug configuration. 66 | 67 | > [!IMPORTANT] 68 | > Extension methods will not work on [IUnityContainer](xref:Unity.IUnityContainer) interface. It is only available on the UnityContainer itself. 69 | -------------------------------------------------------------------------------- /tutorials/Extensions/extensions.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Extensions 3 | title: Unity Extensions 4 | --- 5 | 6 | # Unity Extensions 7 | 8 | Unity container comes prepackaged with several extensions: 9 | 10 | * Diagnostic Extension 11 | * Legacy Constructor Selector Extension 12 | * Force Compilation Extension 13 | * Force Activation Extension -------------------------------------------------------------------------------- /tutorials/Extensions/legacy.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Extension.Legacy 3 | title: Legacy Extension 4 | --- 5 | -------------------------------------------------------------------------------- /tutorials/Extensions/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Diagnostic 2 | uid: Tutorial.Extension.Diagnostic 3 | - name: Legacy 4 | uid: Tutorial.Extension.Legacy 5 | - name: Force Activation 6 | uid: Tutorial.Extension.Activation 7 | - name: Force Compilation 8 | uid: Tutorial.Extension.Compilation 9 | -------------------------------------------------------------------------------- /tutorials/definitions.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Terms 3 | title: Terms and Definitions 4 | --- 5 | 6 | # Terms and Definitions 7 | 8 | [Generics terminology](https://docs.microsoft.com/en-us/dotnet/standard/generics/#generics_terminology) 9 | -------------------------------------------------------------------------------- /tutorials/hierarchies.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Container.Hierarchy 3 | title: Container Hierarchy 4 | --- 5 | 6 | # Container Hierarchies 7 | 8 | Unity container provides a way to create child containers (other systems refer to it as resolution scopes) and allows building sophisticated scope trees of registrations. There are just a few simple rules to follow when dealing with container hierarchies: 9 | 10 | * Types registered in predecessor containers are always available in descendant containers. This is a very simple concept, each registration is like a public virtual declaration in cs types. Every descendant inherits it and can use at will. 11 | 12 | * Types registered in descendant containers override the same registration of predecessors. Following the same analogy with public virtual declarations, each override registration installs its own declaration and hides the one in predecessor containers. 13 | 14 | ## Using Container Hierarchies 15 | 16 | Unity supports nested containers, allowing you to build container hierarchies. Nesting containers enables you to control the scope and lifetime of singleton objects, and register different mappings for specific types. This topic contains the following sections that describe how you can create container hierarchies and use them in your applications: 17 | 18 | * Constructing and Disposing Unity Containers 19 | * Controlling Object Scope and Lifetime 20 | * Overriding registrations 21 | 22 | ### Constructing and Disposing Unity Containers 23 | 24 | The following methods enable you to create a new default UnityContainer, create a child container that has a specified UnityContainer as its parent, and dispose an existing container. 25 | 26 | | Method | Description | 27 | |:-----| ----- | 28 | |`new UnityContainer()`|Creates a root UnityContainer. Returns a reference to the new container.| 29 | |`CreateChildContainer()`|Creates a new nested UnityContainer as a child of the current container. The current container first applies its own settings, and then it checks the parent for additional settings. Returns a reference to the new container.| 30 | |`Dispose()`|Disposes this container instance and any child containers. Also disposes any registered object instances whose lifetimes are managed by the container.| 31 | 32 | ### Controlling Object Scope and Lifetime 33 | 34 | When the container creates singleton objects, it manages the lifetime of these singletons. They remain in scope until you (or the garbage collector) dispose the container. At this point, it disposes the registered singleton instances it contains. In addition, if you dispose the parent container in a nested container hierarchy, it automatically disposes all child containers and the registered singletons they contain. 35 | 36 | Therefore, if you require two separate sets of such objects that must have different lifetimes, you can use hierarchical containers to store and manage each set. Register instances that you want to be able to dispose separately in one or more child containers that you can dispose without disposing the parent container. 37 | 38 | Note that due to possibility of child container disposal, resolution of singletons (registered with `Singleton` or `PerContainer` lifetime) will only be using registrations available in the container they were registered in and its ancestors, but not child containers, to satisfy their dependencies, even if the resolution is requested through a child container. It's Unity's way of making sure it is not storing an instance that references potentially disposed objects. 39 | 40 | The following code demonstrates the use of a child container to manage the lifetime of specific singleton instances while maintaining the singleton instances in the parent container. 41 | 42 | ```cs 43 | 44 | // Create parent container 45 | IUnityContainer parentCtr = new UnityContainer(); 46 | 47 | // Register type in parent container 48 | parentCtr.RegisterType(TypeLifetime.PerContainer); 49 | 50 | // Create nested child container in parent container 51 | IUnityContainer childCtr = parentCtr.CreateChildContainer(); 52 | 53 | // Register type in child container 54 | childCtr.RegisterType(TypeLifetime.PerContainer); 55 | 56 | // Create instance of type stored in parent container 57 | MyParentObject parentObj = parentCtr.Resolve(); 58 | 59 | // Create instance of type stored in child container 60 | MyChildObject childObj = childCtr.Resolve(); 61 | 62 | // ... can use both generated objects here ... 63 | 64 | // Dispose child container 65 | childCtr.Dispose(); 66 | 67 | // ... can use only object in parent container here ... 68 | 69 | // Dispose parent container 70 | parentCtr.Dispose(); 71 | ``` 72 | 73 | ### Overriding registrations 74 | 75 | You can use nested containers when you have slightly different dependency injection requirements for specific objects but want to provide a fallback facility for objects that implement a specific interface or are of a specific type. For example, you may have a general requirement for objects that implement the IMyObject interface to map to the type MyStandardObject. However, in specific parts of the application code, you may want the IMyObject interface to map to the type MySpecialObject. 76 | 77 | In this case, you can register the general mapping in the parent container and register the specific case in a child container. Then, when you want to obtain an instance of the object, you call the Resolve method on the appropriate container. If you call the method on the child container, it returns an object of type MySpecialObject. If you call the method on the parent container, it returns an object of type MyStandardObject. 78 | 79 | However, the advantage with nested containers is that, if the child container cannot locate a mapping for the requested interface or type, it passes the request to its parent container and onward through the hierarchy until it reaches the root or base container. Therefore, for objects not mapped in the child container, the mapping in the parent container (or in an ancestor container where there are more than two levels in the hierarchy) defines the object type returned. 80 | 81 | The following code shows how you can implement the preceding scenario. 82 | 83 | ```cs 84 | // Create parent container 85 | IUnityContainer parentCtr = new UnityContainer(); 86 | 87 | // Register two mappings for types in parent container 88 | parentCtr.RegisterType(); 89 | parentCtr.RegisterType(); 90 | 91 | // Create nested child container in parent container 92 | IUnityContainer childCtr = parentCtr.CreateChildContainer(); 93 | 94 | // Register mapping for specific type in child container 95 | childCtr.RegisterType(); 96 | 97 | // Now retrieve instances of the mapped objects using the child container. 98 | // Using the interface as the type for the returned objects means that it 99 | // does not matter which container returns the actual object. 100 | 101 | // This code returns an object of type MySpecialObject using the mapping 102 | // registered in the child container: 103 | IMyObject specialObject = childCtr.Resolve(); 104 | 105 | // This code returns an object of type MyOtherObject using the mapping 106 | // registered in the parent container because there is no mapping in 107 | // the child container for this type: 108 | IMyOtherObject otherObject = childCtr.Resolve(); 109 | 110 | // Now retrieve instance of the standard object using the parent container. 111 | // This code returns an object of type MyStandardObject using the mapping 112 | // registered in the parent container: 113 | IMyObject standardObject = parentCtr.Resolve(); 114 | 115 | // Dispose parent container and child container 116 | parentCtr.Dispose(); 117 | ``` -------------------------------------------------------------------------------- /tutorials/lifetime/container.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Container 3 | title: Per Container Lifetime 4 | --- 5 | 6 | # Per Container Lifetime 7 | 8 | Per Container lifetime allows a registration of an existing or resolved object as a scoped singleton in the container it was created or registered. In other words this instance is unique within the container it was registered with. Child or parent containers could have their own instances registered for the same contract. 9 | 10 | Unity returns the same instance each time the `Resolve` method is called or when the dependency mechanism injects the instance into other classes. 11 | 12 | ## The Lifetime Manager 13 | 14 | Per container lifetime is controlled by [ContainerControlledLifetimeManager](xref:Unity.Lifetime.ContainerControlledLifetimeManager) type. This lifetime manager effectively implements a singleton behavior for objects registered with a particular container. 15 | 16 | ## Registration 17 | 18 | Per container lifetime is supported by all registration types 19 | 20 | ### Example 21 | 22 | To create a Type registration with per container lifetime: 23 | 24 | ```C# 25 | container.RegisterType(TypeLifetime.PerContainer); 26 | ``` 27 | 28 | to register a factory: 29 | 30 | ```C# 31 | container.RegisterFactory((c, t, n) => new Service(), 32 | FactoryLifetime.PerContainer); 33 | ``` 34 | 35 | or to register an instance: 36 | 37 | ```C# 38 | var instance = new Service(); 39 | 40 | container.RegisterInstance(instance, InstanceLifetime.PerContainer); 41 | ``` 42 | 43 | > [!NOTE] 44 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_PerContainer), [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_PerContainer), and [InstanceLifetime](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_PerContainer) respectively. 45 | 46 | ## See Also 47 | 48 | [!include [Managers List](managers.md)] 49 | -------------------------------------------------------------------------------- /tutorials/lifetime/container_transient.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Container.Transient 3 | title: Container Lifetime 4 | --- 5 | 6 | # Container Transient Lifetime 7 | 8 | This lifetime is similar to with exception how the container holds references to created objects. 9 | 10 | On each call to the `Resolve()` method a container will create a new objects. If the objects implements [IDisposable](xref:System.IDisposable), the container will hold a reference to the interface and will dispose the object when the container goes out of scope. 11 | 12 | This lifetime is particularly useful in session based designs with child containers associated with the session. 13 | 14 | ## The Lifetime Manager 15 | 16 | Per container transient lifetime is controlled by [ContainerControlledTransientManager](xref:Unity.Lifetime.ContainerControlledTransientManager) type. This lifetime manager creates transient objects and holds reference to disposable instance and disposes these when container goes out of scope. 17 | 18 | ## Registration 19 | 20 | Per container transient lifetime is only supported by [Type](xref:Tutorial.Registration.Type) and [Factory](xref:Tutorial.Registration.Factory) registrations. [Instance](xref:Tutorial.Registration.Instance) registration does not support this lifetime. 21 | 22 | ### Example 23 | 24 | To create a Type registration with per container transient lifetime: 25 | 26 | ```C# 27 | container.RegisterType(TypeLifetime.PerContainerTransient); 28 | ``` 29 | 30 | or you could register a factory: 31 | 32 | ```C# 33 | container.RegisterFactory((c, t, n) => new Service(), 34 | FactoryLifetime.PerContainerTransient); 35 | ``` 36 | 37 | > [!NOTE] 38 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_PerContainerTransient) and [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_PerContainerTransient) respectively. 39 | 40 | ## See Also 41 | 42 | [!include [Managers List](managers.md)] 43 | -------------------------------------------------------------------------------- /tutorials/lifetime/disposal.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitycontainer/documentation/c1904e6b2c9bdff42f10f3d4dcdf3f7080d48d9c/tutorials/lifetime/disposal.md -------------------------------------------------------------------------------- /tutorials/lifetime/external.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.External 3 | title: External Lifetime 4 | --- 5 | 6 | # External Lifetime 7 | 8 | This lifetime allows you to register externally created objects with the container to enable them to participate in dependency injection process. Unity maintains only a weak reference to the instances it registers. 9 | 10 | Since the container does not maintain a strong reference to the object, the garbage collector can dispose of the objects if no other code is keeping it alive. 11 | 12 | ## The Lifetime Manager 13 | 14 | External lifetime is controlled by [ExternallyControlledLifetimeManager](xref:Unity.Lifetime.ExternallyControlledLifetimeManager) type and provides basic support for externally managed objects. 15 | 16 | ## Registration 17 | 18 | External lifetime is only supported by [Instance](xref:Tutorial.Registration.Instance) registrations. 19 | 20 | External lifetime is similar to . It is held at the same container it is registered with and could be accessed and overridden in child container. Registrations with external lifetime override singletons with the same contract. 21 | 22 | ### Example 23 | 24 | To create a registration with external lifetime: 25 | 26 | ```C# 27 | var instance = new Service(); 28 | ... 29 | container.RegisterInstance(instance, InstanceLifetime.External); 30 | ``` 31 | 32 | ## See Also 33 | 34 | [!include [Managers List](managers.md)] 35 | -------------------------------------------------------------------------------- /tutorials/lifetime/hierarchical.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Hierarchical 3 | title: Hierarchical Lifetime 4 | --- 5 | 6 | # Hierarchical Lifetime 7 | 8 | The Unity container allows creating hierarchies of child containers. This lifetime creates local singleton for each level of the hierarchy. So, when you resolve a type and this container does not have an instance of that type, the container will create new instance. Next time the type is resolved the same instance will be returned. 9 | 10 | If a child container is created and requested to resolve the type, the child container will create a new instance and store it for subsequent resolutions. Next time the child container requests to resolve the type, it will return the stored instance. 11 | 12 | If you have multiple children, each will resolve its own instance. 13 | 14 | ## The Lifetime Manager 15 | 16 | Hierarchical lifetime is controlled by [HierarchicalLifetimeManager](xref:Unity.Lifetime.HierarchicalLifetimeManager) type. It forces each child container to resolve its own instance of the object and does not share one with the parent or child containers. 17 | 18 | ## Registration 19 | 20 | Hierarchical lifetime is only supported by [Type](xref:Tutorial.Registration.Type) and [Factory](xref:Tutorial.Registration.Factory) registrations. [Instance](xref:Tutorial.Registration.Instance) registration does not support this lifetime. 21 | 22 | ### Example 23 | 24 | To create a Type registration with hierarchical lifetime: 25 | 26 | ```C# 27 | container.RegisterType(TypeLifetime.Hierarchical); 28 | ``` 29 | 30 | or you could register a factory: 31 | 32 | ```C# 33 | container.RegisterFactory((c, t, n) => new Service(), 34 | FactoryLifetime.Hierarchical); 35 | ``` 36 | 37 | > [!NOTE] 38 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_Hierarchical) and [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_Hierarchical) respectively. 39 | 40 | ## See Also 41 | 42 | [!include [Managers List](managers.md)] 43 | -------------------------------------------------------------------------------- /tutorials/lifetime/lifetime.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime 3 | title: Lifetime Management 4 | --- 5 | 6 | # Lifetime 7 | 8 | The Unity container manages the lifetime of objects based on a [Lifetime Manager](xref:Unity.Lifetime) you specify when you register the type. 9 | 10 | The default behavior for the container, if no lifetime is registered, to use a . It creates a new instance of the requested type each time `Resolve` method is called or when the dependency mechanism injects instances into other classes. The container does not store any references to the object. 11 | 12 | Unity uses specific types that inherit from the `LifetimeManager` base class (collectively referred to as lifetime managers) to control how it stores references to object instances and how the container disposes of these instances. 13 | 14 | When you register an existing object using the `RegisterInstance` method, the default behavior is for the container to take over management of the lifetime of the object you pass to this method using the . This means that container maintains strong reference to the object and at the end of the container lifetime, the existing object is disposed. 15 | 16 | ## How registering lifetime works 17 | 18 | When type is registered with a lifetime manager, the creation and life cycle of the created instances is controlled according to that lifetime. 19 | 20 | When a container is requested to produce an instance of the type, it first checks if a lifetime manager is associated with it. If not, or if it is a transient manager, the container simply creates the instance and return it to the caller. 21 | 22 | If registration contains a lifetime manager, the container tries to get the value from that manager. If the manager has nothing stored in it, the container created an instance. But before it returns the instance to the caller it adds it to the lifetime manager for later use. 23 | 24 | Next time the type is requested, the container gets the value previously stored in the manager, if available, and returns it to the caller. 25 | 26 | Each lifetime manager has its own criteria how to store and retrieve object instances. Some only store unique instances in a container, others store unique instances per thread or session. Each algorithm serves particular purpose. 27 | 28 | ## Built-In Lifetimes 29 | 30 | The Unity container implements several lifetime managers that you can use directly in your code. The range covers most common use cases and scenarios. Unity includes the following lifetime implementations: 31 | 32 | [!include [Managers List](managers.md)] 33 | -------------------------------------------------------------------------------- /tutorials/lifetime/managers.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Managers 3 | title: Lifetime Managers 4 | --- 5 | 6 | - [Transient Lifetime](xref:Tutorial.Lifetime.Transient) 7 | - [Singleton Lifetime](xref:Tutorial.Lifetime.Singleton) 8 | - [Per Container Lifetime](xref:Tutorial.Lifetime.Container) 9 | - [Per Container Transient](xref:Tutorial.Lifetime.Container.Transient) 10 | - [Hierarchical Lifetime](xref:Tutorial.Lifetime.Hierarchical) 11 | - [Per Resolve Lifetime](xref:Tutorial.Lifetime.Resolve) 12 | - [Per Thread Lifetime](xref:Tutorial.Lifetime.Thread) 13 | - [External Lifetime](xref:Tutorial.Lifetime.External) 14 | -------------------------------------------------------------------------------- /tutorials/lifetime/resolve.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Resolve 3 | title: Per Resolve Lifetime 4 | --- 5 | 6 | # Per Resolve Lifetime 7 | 8 | This lifetime keeps a reference to an instance only for the duration of one resolution call. This type of lifetime is useful when you need to pass the same instance of the dependency to a different nodes of the resolution graph. Consider this scenario: 9 | 10 | ```cs 11 | 12 | class a {} 13 | 14 | class b 15 | { 16 | b(a arg) 17 | {...} 18 | } 19 | 20 | class c 21 | { 22 | c(a arg1, b arg2) 23 | {...} 24 | } 25 | 26 | ``` 27 | 28 | When you resolve type `c`, it depends on type `b` and type `a`. Type `b`, in turn, also depends on type `a`, and both types, `c` and `b`, require `a` to be the same instance. 29 | 30 | If type `a` is a singleton, the logic is easy. But if you require each instance of `c` to have a unique `a`, you could use per resolve lifetime. The instance of `a` will act as a singleton only during that one resolution. Next call to resolve the dependent type will create a new object. 31 | 32 | In the case of recursion, the singleton behavior is still applies and prevents circular dependency. 33 | 34 | ## The Lifetime Manager 35 | 36 | Per resolve lifetime is controlled by [PerResolveLifetimeManager](xref:Unity.Lifetime.PerResolveLifetimeManager) type. This lifetime manager effectively implements a singleton behavior for objects on a per-resolve basis. 37 | 38 | ## Registration 39 | 40 | Per resolve lifetime is only supported by [Type](xref:Tutorial.Registration.Type) and [Factory](xref:Tutorial.Registration.Factory) registrations. [Instance](xref:Tutorial.Registration.Instance) registration does not support this lifetime. 41 | 42 | ### Example 43 | 44 | To create a Type registration with per resolve lifetime: 45 | 46 | ```C# 47 | container.RegisterType(TypeLifetime.PerResolve); 48 | ``` 49 | 50 | or you could register a factory: 51 | 52 | ```C# 53 | container.RegisterFactory((c, t, n) => new Service(), 54 | FactoryLifetime.PerResolve); 55 | ``` 56 | 57 | > [!NOTE] 58 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_PerResolve) and [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_PerResolve) respectively. 59 | 60 | ## See Also 61 | 62 | [!include [Managers List](managers.md)] 63 | -------------------------------------------------------------------------------- /tutorials/lifetime/singleton.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Singleton 3 | title: Singleton Lifetime 4 | --- 5 | 6 | # Singleton Lifetime 7 | 8 | Singleton lifetime creates globally unique singleton. Any Unity container tree (parent and all the children) is guaranteed to have only one global singleton for the registered type. 9 | 10 | ## The Lifetime Manager 11 | 12 | The singleton lifetime is controlled by [SingletonLifetimeManager](xref:Unity.Lifetime.SingletonLifetimeManager) type. 13 | 14 | ## Registration 15 | 16 | Registering a type with singleton lifetime always places the registration at the root of the container tree and makes it globally available for all the children of that container. It does not matter if registration takes places at the root of child container the destination is always the root node. 17 | 18 | Repeating the registration on any of the child nodes with singleton lifetime will always override the root registration. 19 | 20 | Singleton lifetime is supported by all registration types. 21 | 22 | ### Example 23 | 24 | To create a Type registration with singleton lifetime: 25 | 26 | ```C# 27 | container.RegisterType(TypeLifetime.Singleton); 28 | ``` 29 | 30 | to register a factory: 31 | 32 | ```C# 33 | container.RegisterFactory((c, t, n) => new Service(), 34 | FactoryLifetime.Singleton); 35 | ``` 36 | 37 | or to register an instance: 38 | 39 | ```C# 40 | var instance = new Service(); 41 | 42 | container.RegisterInstance(instance, InstanceLifetime.Singleton); 43 | ``` 44 | 45 | > [!NOTE] 46 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_Singleton), [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_Singleton), and [InstanceLifetime](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_Singleton) respectively. 47 | 48 | ## See Also 49 | 50 | [!include [Managers List](managers.md)] 51 | -------------------------------------------------------------------------------- /tutorials/lifetime/thread.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Thread 3 | title: Per Thread Lifetime 4 | --- 5 | 6 | # Per Thread Lifetime 7 | 8 | Per thread lifetime means a new instance of the registered [Type](xref:System.Type) will be created once per each thread. In other words, if a `Resolve()` method is called on a thread the first time, it will return a new object. Each subsequent call to `Resolve()`, or when the dependency mechanism injects instances of the type into other classes on the same thread, the container will return the same object. 9 | 10 | ## The Lifetime Manager 11 | 12 | Per thread lifetime is controlled by [PerThreadLifetimeManager](xref:Unity.Lifetime.PerThreadLifetimeManager) type. This lifetime manager effectively implements a singleton behavior for objects on a per-thread basis. 13 | 14 | ## Registration 15 | 16 | Per thread lifetime is only supported by [Type](xref:Tutorial.Registration.Type) and [Factory](xref:Tutorial.Registration.Factory) registrations. [Instance](xref:Tutorial.Registration.Instance) registration does not support this lifetime. 17 | 18 | ### Example 19 | 20 | To create a Type registration with per thread lifetime: 21 | 22 | ```C# 23 | container.RegisterType(TypeLifetime.PerThread); 24 | ``` 25 | 26 | or you could register a factory: 27 | 28 | ```C# 29 | container.RegisterFactory((c, t, n) => new Service(), 30 | FactoryLifetime.PerThread); 31 | ``` 32 | 33 | > [!NOTE] 34 | > Please note that registrations use [TypeLifetime](xref:Unity.TypeLifetime#Unity_TypeLifetime_PerThread) and [FactoryLifetime](xref:Unity.FactoryLifetime#Unity_FactoryLifetime_PerThread) respectively. 35 | 36 | ## See Also 37 | 38 | [!include [Managers List](managers.md)] 39 | -------------------------------------------------------------------------------- /tutorials/lifetime/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Transient 2 | uid: Tutorial.Lifetime.Transient 3 | - name: Singleton 4 | uid: Tutorial.Lifetime.Singleton 5 | - name: Container 6 | uid: Tutorial.Lifetime.Container 7 | - name: Container Transient 8 | uid: Tutorial.Lifetime.Container.Transient 9 | - name: Hierarchical 10 | uid: Tutorial.Lifetime.Hierarchical 11 | - name: Per Resolve 12 | uid: Tutorial.Lifetime.Resolve 13 | - name: Per Thread 14 | uid: Tutorial.Lifetime.Thread 15 | - name: External 16 | uid: Tutorial.Lifetime.External 17 | -------------------------------------------------------------------------------- /tutorials/lifetime/transient.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Lifetime.Transient 3 | title: Transient Lifetime 4 | --- 5 | 6 | # Transient Lifetime 7 | 8 | Transient lifetime is a default lifetime of the Unity container. As the name implies it lasts very short period of time, actually, no time at all. In the Unity container terms, having transient lifetime is the same as having no lifetime manager at all. 9 | 10 | For this lifetime manager Unity creates and returns a new instance of the requested type for each call to the **Resolve** method. 11 | 12 | ## The Lifetime Manager 13 | 14 | The transient lifetime is controlled by [TransientLifetimeManager](xref:Unity.Lifetime.TransientLifetimeManager). This lifetime manager is used by default for all types registered using the **RegisterType** method where no specific manager has been provided. 15 | 16 | ## Registration 17 | 18 | When registering a transient [Type](xref:System.Type) it is recommended to not pass an instance of [TransientLifetimeManager](xref:Unity.Lifetime.TransientLifetimeManager) to the registration, but allow Unity to create it explicitly. 19 | 20 | ### Example 21 | 22 | ```C# 23 | RegisterType(); 24 | RegisterType(); 25 | ``` 26 | 27 | In this example a [Type](xref:System.Type) `Foo` and a mapping from `IService` to `Service` both registered with transient lifetime. So every call to `Resolve()` or `Resolve()` will create a new object instance. 28 | 29 | ## See Also 30 | 31 | [!include [Managers List](managers.md)] 32 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/annotation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Annotation 3 | title: Select Constructor By Attribute Annotation 4 | --- 5 | 6 | [!include[file2](../../../Annotation/constructor.md)] 7 | 8 | ### See Also 9 | 10 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 11 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 12 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 13 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 14 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 15 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/automatic.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Implicit 3 | title: Automatic Constructor Injection 4 | --- 5 | 6 | [!include[file2](../../../Composition/Selection/constructor.md)] 7 | 8 | **See Also:** 9 | 10 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 11 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 12 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 13 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 14 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 15 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/constructor.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor 3 | title: Constructor Injection 4 | --- 5 | 6 | # Constructor Injection 7 | 8 | Constructor Injection is a process where Unity selects a constructor, resolves parameter dependencies, and executes the constructor by injecting it with resolved or injected dependencies. 9 | 10 | ## Restrictions 11 | 12 | Unity can be configured to execute any accessible constructor with the following exceptions: 13 | 14 | * `static` constructors are not supported 15 | * `private` and `protected` constructors are not accessible 16 | * Constructors with `ref` and `out` parameters are not supported 17 | 18 | ## Selection Methods 19 | 20 | Selecting a constructor is one of the first steps in creating a resolution pipeline. Unity supports the following selection methods: 21 | 22 | ### Automatic Selection 23 | 24 | Automatic Selection is a default method of selecting constructors. It will be used if no constructor is injected or annotated. 25 | 26 | By default Unity uses 'smart' algorithm to select constructor. It sorts all accessible constructors by number of parameters in ascending order and goes from most complex to the default, checking if it can satisfy its parameters. The container selects the first constructor it can create and executes it. 27 | 28 | > [!WARNING] 29 | > Unity will not check for ambiguities unless [Diagnostic](xref:Tutorial.Extension.Diagnostic) extension is installed. 30 | 31 | > [!TIP] 32 | > Legacy selection algorithm which selects the most complex constructor could be enabled by installing `Legacy` extension. It will replace and disable 'smart' selection. 33 | 34 | ### Constructor Annotation 35 | 36 | Constructor annotated with [InjectionConstructor](xref:Unity.InjectionConstructorAttribute) attribute overrides automatic selection. For more information see 37 | 38 | ### Constructor injection 39 | 40 | Constructor configuration registered for the [Type](xref:System.Type) has highest priority. It will override other selection methods and will always execute the configured constructor. 41 | 42 | As opposed to methods, constructors do not have a name to distinguish one from the other. The only difference between constructors is number and [Type](xref:System.Type) of parameters they take. Because of that constructor selection is based solely on parameters and its types. 43 | 44 | #### Invoking the Constructor 45 | 46 | Invoked constructor and injection of its parameters is configured by registering the [Type](xref:System.Type) with the [InjectionConstructor](xref:Unity.Injection.InjectionConstructor). Creating the [InjectionConstructor](xref:Unity.Injection.InjectionConstructor) with proper injection members or values determines what constructor is selected and how parameters are initialized. Values and resolvers added to [InjectionConstructor](xref:Unity.Injection.InjectionConstructor) will be used to initialize parameters of the constructor of the [Type](xref:System.Type). The following aspects could be configured: 47 | 48 | * Parameter [Type](xref:System.Type) 49 | * Force resolution of parameter 50 | * Specify the Contract/Registration Name to by used when resolving 51 | * Provide a Resolver for the parameter 52 | * Provide value 53 | 54 | > [!TIP] 55 | > As alternative, helper [Invoke.Constructor(...)](xref:Unity.Invoke#Unity_Invoke_Constructor) can be used to configure invoked constructor. 56 | 57 | #### See Also 58 | 59 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 60 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 61 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 62 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 63 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 64 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 65 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/param_count.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Count 3 | title: Select Constructor By Number of Parameters 4 | --- 5 | 6 | # Selecting Constructor 7 | 8 | ## By Number of Parameters 9 | 10 | Selecting constructor by number of parameters is the simplest form of selection. You could use this selection method if the constructor you invoking has unique number of parameters. 11 | 12 | ### Type of Parameter as Contract Type 13 | 14 | This method is useful when you are working on a [Type](xref:System.Type) that takes certain number of parameters but you don't care what these parameter types are. 15 | 16 | #### Parameters 17 | 18 | In a case like this you could use `Resolve.Parameter()` to specify that you want a parameter at this position to be resolved. For example, consider the following [Type](xref:System.Type): 19 | 20 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#class_sample_type)] 21 | 22 | It has several constructors with different number of parameters each. Normally, the container would try to run the most complex constructor, but if you want to invoke the one with just a single parameter you need to register it like this: 23 | 24 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_first_arrange)] 25 | 26 | In this registration you configure the container to invoke a constructor that takes just one parameter. The parameter is resolved using a contract with a type of the parameter and no name. 27 | 28 | Now if you resolve the type, the container will invoke that constructor and inject the parameter: 29 | 30 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_first_ctor_act)] 31 | 32 | #### Generic Parameters 33 | 34 | The same method as above, could be used to invoke constructors with generic parameters. Consider the following class: 35 | 36 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#class_sample_type_generic)] 37 | 38 | To configure the container to invoke the first constructor you would execute the same code with exception of how you pass in a type of the contract. Registration of an open generic requires a conventional method call: 39 | 40 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_first_arrange_generic)] 41 | 42 | When resolved, the container will invoke the first constructor and inject it with created instance of `Object`: 43 | 44 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_first_ctor_act_generic)] 45 | 46 | #### Parameter dependencies with Contract Name 47 | 48 | When configuring constructors with the method described above you should be mindful of parameter annotations and contract names these annotations might provide. 49 | 50 | When implicitly injecting a parameter, the container will recognize all metadata the parameter is annotated with and will properly inject it with correct contract. When you add an [InjectionMember](xref:Unity.Injection.ResolvedParameter) to configure the parameter you override all these annotations. 51 | 52 | If you look at the second constructor of `SampleType` you will notice that the first parameter is marked with [Dependency](xref:Unity.DependencyAttribute) attribute. Normally, when resolving that parameter, Unity will, if present, use Name of the Contract the attribute provides. But when you register it as in the following example, you will override that contract: 53 | 54 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_named_generic)] 55 | 56 | When resolved, Unity will execute the constructor but instead of dependency with contract name `one` it will use contract with no name. 57 | 58 | If you need to, you could override contract name explicitly as in the following example: 59 | 60 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/ByCount.cs#inject_count_name_override_generic)] 61 | 62 | If you'd like to preserve contracts from annotations, you need to use one of the following selection methods instead. 63 | 64 | ### See Also 65 | 66 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 67 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 68 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 69 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 70 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 71 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/param_none.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Default 3 | title: Default Constructor 4 | --- 5 | 6 | # Default Constructors 7 | 8 | A _Default_ called a constructor with no parameters. It could be explicitly defined on a [Type](xref:System.Type) or if [Type](xref:System.Type) has no defined constructors, C# will implicitly create one for you. 9 | 10 | ## Invoking Default Constructor 11 | 12 | To configure resolution of a [Type](xref:System.Type) with a default constructor you need to register that [Type](xref:System.Type) with [Injection Constructor Member](xref:Unity.Injection.InjectionConstructor) which takes no parameters. 13 | 14 | ### Class `Service` 15 | 16 | Consider the following [Type](xref:System.Type): 17 | 18 | [!code-csharp [class Service](../../../../src/SpecificationTests/src/Constructor/Injection/Setup.cs#class_service)] 19 | 20 | Class `Service` is a plain type with three accessible constructors. First constructor is a default constructor with no parameters, second and third constructors take one parameter each. 21 | 22 | ### Registering `Service` 23 | 24 | If you try to resolve this class with no registration, Unity will select one of the constructors with parameter. You can not guarantee which one it will select because both have the same number of parameters and each could be satisfied with dependencies. 25 | 26 | > [!TIP] 27 | > If [Diagnostic](xref:Tutorial.Extension.Diagnostic) is enabled, it will throw an ambiguous constructor exception. 28 | 29 | To prevent ambiguity, or if you need to execute default constructor, you can register this [Type](xref:System.Type) and instruct the container to invoke default constructor during resolution. In simplest form this registration will look like this: 30 | 31 | [!code-csharp [Register Service](../../../../src/SpecificationTests/src/Constructor/Injection/Default.cs#inject_default_ctor_arrange)] 32 | 33 | > [!NOTE] 34 | > Of corse you could add other instructions like mapping, name, etc. to the registration but for simplicity it is omitted in this example. 35 | 36 | ### Resolving `Service` 37 | 38 | Once you register the `Service` with the container, you can resolve it normally: 39 | 40 | [!code-csharp [Resolve Service](../../../../src/SpecificationTests/src/Constructor/Injection/Default.cs#inject_default_ctor_act)] 41 | 42 | At first resolution the container will create a pipeline which invokes a default constructor to create the `Service` and will be using it for all subsequent resolutions. 43 | 44 | ## Default Generic Constructor 45 | 46 | Unity can register and create Generic types. It allows to register Closed and Open Generics and can resolve constructed types based on these. 47 | 48 | ### Class `Service` 49 | 50 | The principle for registering of default constructor is exactly the same as for plain types. Consider the following [Type](xref:System.Type): 51 | 52 | [!code-csharp [class Service{T}](../../../../src/SpecificationTests/src/Constructor/Injection/Setup.cs#class_service_generic)] 53 | 54 | Class `Service` is an open generic type with two constructors. First constructor is a default constructor with no parameters and second takes one parameter. 55 | 56 | ### Registering `Service` 57 | 58 | Normally, Unity will create this [Type](xref:System.Type) by executing most complex constructor. To force Unity to use default constructor you need to register `Service` and instruct the container to invoke it during resolution. You can register constructed generic based on `Service` like this: 59 | 60 | [!code-csharp [Register Service{object}](../../../../src/SpecificationTests/src/Constructor/Injection/Default.cs#inject_default_ctor_closed_generic_arrange)] 61 | 62 | Or you can register Open Generic [Type](xref:System.Type): 63 | 64 | [!code-csharp [Register Service{T arg}](../../../../src/SpecificationTests/src/Constructor/Injection/Default.cs#inject_default_ctor_open_generic_arrange)] 65 | 66 | ### Resolving `Service` 67 | 68 | If you resolve `Service`: 69 | 70 | [!code-csharp [Resolve Service](../../../../src/SpecificationTests/src/Constructor/Injection/Default.cs#inject_default_ctor_closed_generic_act)] 71 | 72 | either registration will invoke the default constructor. 73 | 74 | ### See Also 75 | 76 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 77 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 78 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 79 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 80 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 81 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/param_types.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Types 3 | title: Select Constructor by Parameter Types 4 | --- 5 | 6 | # Selecting Constructor 7 | 8 | 9 | 10 | ## Select Constructor by Parameter types 11 | 12 | ### Exact Match 13 | 14 | ### Compatible Type Match 15 | 16 | ## Contracts with Name 17 | 18 | ### Type Matching exactly 19 | 20 | ### Compatible Implementation 21 | 22 | ### See Also 23 | 24 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 25 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 26 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 27 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 28 | * [Select constructors based on injected values](xref:Tutorial.Injection.Constructor.Values) 29 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/param_values.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Constructor.Values 3 | title: Select Constructor by Parameter Values 4 | --- 5 | 6 | # Selecting Constructor 7 | 8 | ### See Also 9 | 10 | * [Implicit Constructor Registration](xref:Tutorial.Injection.Constructor.Implicit) 11 | * [Constructor Annotation](xref:Tutorial.Injection.Constructor.Annotation) 12 | * [Invoke default constructor](xref:Tutorial.Injection.Constructor.Default) 13 | * [Select constructors by parameters count](xref:Tutorial.Injection.Constructor.Count) 14 | * [Select constructors by parameter types](xref:Tutorial.Injection.Constructor.Types) 15 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Constructor/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Automatic Selection 2 | uid: Tutorial.Injection.Constructor.Implicit 3 | - name: Attribute Annotation 4 | uid: Tutorial.Injection.Constructor.Annotation 5 | - name: Invoking default ctor() 6 | uid: Tutorial.Injection.Constructor.Default 7 | - name: Select By Parameters Count 8 | uid: Tutorial.Injection.Constructor.Count 9 | - name: Select By Parameter Types 10 | uid: Tutorial.Injection.Constructor.Types 11 | -------------------------------------------------------------------------------- /tutorials/registration/Type/Injection/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Default 3 | title: Support for Default Values 4 | --- 5 | 6 | # Support for Default Values -------------------------------------------------------------------------------- /tutorials/registration/Type/Injection/injected.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Injected 3 | title: Injecting Dependency Values 4 | --- 5 | 6 | # Injecting Dependency Values -------------------------------------------------------------------------------- /tutorials/registration/Type/Injection/injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection 3 | title: Dependency Injection 4 | --- 5 | 6 | # Dependency Injection -------------------------------------------------------------------------------- /tutorials/registration/Type/Injection/resolved.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Resolved 3 | title: Resolving Dependency Values 4 | --- 5 | 6 | # Resolving Dependency Values -------------------------------------------------------------------------------- /tutorials/registration/Type/Injection/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Resolved values 2 | uid: Tutorial.Injection.Resolved 3 | - name: Injected values 4 | uid: Tutorial.Injection.Injected 5 | - name: Default values 6 | uid: Tutorial.Injection.Default 7 | -------------------------------------------------------------------------------- /tutorials/registration/Type/field.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Field 3 | title: Field Injection 4 | --- 5 | 6 | # Field Injection -------------------------------------------------------------------------------- /tutorials/registration/Type/method.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Method 3 | title: Method Injection 4 | --- 5 | 6 | # Method Invocation -------------------------------------------------------------------------------- /tutorials/registration/Type/parameter.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Parameter 3 | title: Parameter Injection 4 | --- 5 | 6 | # Parameter Injection 7 | -------------------------------------------------------------------------------- /tutorials/registration/Type/property.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Injection.Property 3 | title: Property Injection 4 | --- 5 | 6 | # Property Injection -------------------------------------------------------------------------------- /tutorials/registration/Type/registration.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Registration.Type 3 | title: Type Registration 4 | --- 5 | 6 | # Type Registration 7 | 8 | Type registration is where all the Unity magic is happening. It provides complete and flexible control of all aspects of type creation and management. 9 | 10 | When a [Type](xref:System.Type) is registered Unity creates a contract (a registration) consisting of a **Type**, a **Name**, and instructions on how this contract should be fulfilled when requested. 11 | 12 | ## Minimum Registration Requirements 13 | 14 | The only required part of the registration is a registered [Type](xref:System.Type) itself. Theoretically you could register a [Type](xref:System.Type) like this: 15 | 16 | ```cs 17 | container.RegisterType(); 18 | ``` 19 | 20 | This would tell the container to use all defaults when creating `Service`. Registrations like this do not make much sense. If creation process does not require any customization, all that time spent on registering such [Type](xref:System.Type) is wasted. It is measurably faster to resolve a plain [Type](xref:System.Type) from the container if it is not registered at all. 21 | 22 | When a [Type](xref:System.Type) is annotated with injection attributes it does not require registration either. If you are satisfied with annotated selections, appropriate constructor and all other members are annotated, and you do not require lifetime management for created instances, the [Type](xref:System.Type) should not be registered. 23 | 24 | You should only register types if at least one of the following is true: 25 | 26 | * Contract/Registration requires a Name 27 | * Require a mapping between service and implementation types 28 | * Require lifetime policy other than transient 29 | * Need to override injection annotated with attribute(s) 30 | * Nondefault constructor should be selected 31 | * Properties or fields should be injected 32 | * Method(s) should be called during initialization 33 | 34 | ## Creating Registration Contracts 35 | 36 | Simplest form of a contract is a registration without a Name ( the Name is `null` ). This type of registration is called `default` and in some cases is used as a prototype during resolution of Generic types (hence name `default`). 37 | 38 | A contract could have a Name. The Name could be any arbitrary string of one or more characters. The simple named contract could be registered like this: 39 | 40 | ```cs 41 | container.RegisterType("Contract Name"); 42 | ``` 43 | 44 | > [!NOTE] 45 | > It is not recommended to use empty strings as names. 46 | 47 | ## Creating Type Mapping 48 | 49 | A mapping instructs Unity on how to satisfy the contract and what implementation [Type](xref:System.Type) should be used to create an object. For example is you want to associate an interface `IService` with implementation `Service` you would register it like this: 50 | 51 | ```cs 52 | container.RegisterType(); 53 | ``` 54 | 55 | Or you could register multiple implementations for the same service: 56 | 57 | ```cs 58 | container.RegisterType("Email"); 59 | container.RegisterType("WebMail"); 60 | container.RegisterType("Encrypted"); 61 | ``` 62 | 63 | For more information see 64 | 65 | ## Lifetime Management 66 | 67 | Unity provides wide variety of lifetime managers [compatible](xref:Unity.TypeLifetime) with type registrations. Each of these managers provide unique algorithm for instance management. 68 | 69 | In example above services are created on each request. In most cases it is desireable to create services only once. To create singleton services appropriate lifetime managers must be added to the registration: 70 | 71 | ```cs 72 | container.RegisterType("Email", TypeLifetime.Singleton); 73 | container.RegisterType("WebMail", TypeLifetime.Singleton); 74 | container.RegisterType("Encrypted", TypeLifetime.Singleton); 75 | ``` 76 | 77 | For more information about lifetime management see 78 | 79 | ## Creation Pipeline 80 | 81 | Unity instantiates an objects by creating a resolver pipeline and executing it with passed in injection values. Each pipeline consists of a several steps with each step performing part of the initialization. 82 | 83 | How the pipeline is assembled and what values are injected is controlled by collection of [Injection Member](xref:Unity.Injection.InjectionMember) objects passed to registration method. The normal steps of the object creation process are: 84 | 85 | ## Injection Instructions 86 | 87 | During the registration you could Configure the container to select certain constructor, initialize properties and fields, call methods, and inject values and instructions for dependencies. All this is done by passing appropriate [Injection Members](xref:Unity.Injection) to the registration. For more information see: 88 | 89 | * [Constructor invocation and injection](xref:Tutorial.Injection.Constructor) 90 | * [Fields injection](xref:Tutorial.Injection.Field) 91 | * [Properties injection](xref:Tutorial.Injection.Property) 92 | * [Method(s) invocation and injection](xref:Tutorial.Injection.Method) 93 | -------------------------------------------------------------------------------- /tutorials/registration/Type/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Constructor 2 | href: Constructor/toc.yml 3 | topicUid: Tutorial.Injection.Constructor 4 | - name: Fields 5 | uid: Tutorial.Injection.Field 6 | - name: Properties 7 | uid: Tutorial.Injection.Property 8 | - name: Method Invocation 9 | uid: Tutorial.Injection.Method 10 | - name: Dependency Injection 11 | href: Injection/toc.yml 12 | topicUid: Tutorial.Injection 13 | -------------------------------------------------------------------------------- /tutorials/registration/factory.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Registration.Factory 3 | title: Factory Registration 4 | --- 5 | 6 | # Factory Registration 7 | 8 | ```cs 9 | container.RegisterFactory(f => new Service()); 10 | ``` 11 | -------------------------------------------------------------------------------- /tutorials/registration/instance.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Registration.Instance 3 | title: Instance Registration 4 | --- 5 | 6 | # Instance Registration 7 | 8 | Registering instances is useful if you already have an instance of an object that you have previously created and want Unity to manage its lifetime, or if you want Unity to inject that object into other objects that it is resolving. 9 | 10 | From container's point of view instance registration is in every way similar to type registration, except that it does not need to create the instance on the first Resolve request. It simply gets the object from lifetime manager and returns it as requested. The LifetimeManager controls the lifetime of the object and disposes it when appropriate. 11 | 12 | ## Registration of an Existing Object Instances 13 | 14 | The [RegisterInstance](xref:Unity.IUnityContainer#Unity_IUnityContainer_RegisterInstance_System_Type_System_String_System_Object_Unity_Lifetime_IInstanceLifetimeManager_) method registers an existing instance with the container. You specify the instance type and optional lifetime in the parameter list. The container will return the specified existing instance for the duration of the specified lifetime. Unity container offers several overloads to simplify registration syntax. The simplest instance registration does not require any additional parameters other than instance itself: 15 | 16 | ```cs 17 | var instance = new Service(); 18 | 19 | container.RegisterInstance(instance); 20 | ``` 21 | 22 | Resolving type **Service** like this `container.Resolve()` will return an instance of the **Service** object we registered. 23 | 24 | ## Metadata 25 | 26 | Instance registration, as any other registration type, supports adding a registration [Name](xref:Tutorial.Registration.Metadata#name). Doing so lets you register multiple instance of the same `Type` for later retrieval as a collection. Using overload you can write it like this: 27 | 28 | ```cs 29 | container.RegisterInstance("Some Name", instance); 30 | ``` 31 | 32 | ## Type mapping 33 | 34 | Any instance can also be registered as any of the ancestral types or any of the interfaces it implements effectively creating a mapping between these types. 35 | 36 | ```cs 37 | var instance = new Service(); 38 | 39 | container.RegisterInstance(instance); 40 | container.RegisterInstance("Some Name", instance); 41 | or 42 | container.RegisterInstance(typeof(IService), instance) 43 | container.RegisterInstance(typeof(IService), "xyz", instance) 44 | ``` 45 | 46 | In this example Unity creates two registrations of type **IService**. When either is resolved it returns the instance of the **Service** object we registered with container. For more information see [Type Mapping](xref:Tutorial.Mapping) 47 | 48 | ## Lifetime 49 | 50 | Due to the fact that container does not create these instances, the instance registration only supports limited number of compatible lifetimes: 51 | 52 | ### [Per Container](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_PerContainer) 53 | 54 | By default Unity uses [Per Container](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_PerContainer) lifetime manager when no manager specified explicitly. So all these examples above will be registered with container scope. Unity will keep these instances referenced and alive until the container is alive. Although it is not necessary to provide container controlled lifetime manager you can still write it like this: 55 | 56 | ```cs 57 | container.RegisterInstance("Some Name", instance, InstanceLifetime.PerContainer); 58 | container.RegisterInstance("Some Name", instance, InstanceLifetime.PerContainer); 59 | ``` 60 | 61 | ### [Singleton](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_Singleton) 62 | 63 | Instances can be registered as global singletons by using [Singleton](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_Singleton) lifetime manager: 64 | 65 | ```cs 66 | container.RegisterInstance("Some Name", instance, InstanceLifetime.Singleton); 67 | container.RegisterInstance("Some Name", instance, InstanceLifetime.Singleton); 68 | ``` 69 | 70 | These instances will be kept alive until root container is disposed. 71 | 72 | ### [External](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_External) 73 | 74 | If Unity is not supposed to control lifetime of the object the [External](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_External) lifetime manager is used: 75 | 76 | ```cs 77 | container.RegisterInstance("Some Name", instance, InstanceLifetime.External); 78 | ``` 79 | 80 | [External](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_External) lifetime manager is also useful when same instance is registered via multiple interfaces. In this case only one registration should use [Per Container](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_PerContainer) or [Singleton](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_Singleton) manager and the rest should be registered with [External](xref:Unity.InstanceLifetime#Unity_InstanceLifetime_External) lifetime manager. This way, when object is disposed, it is not disposed multiple times: 81 | 82 | ```cs 83 | container.RegisterInstance(instance, InstanceLifetime.Singleton); 84 | 85 | container.RegisterInstance( instance, InstanceLifetime.External); 86 | container.RegisterInstance("Name", instance, InstanceLifetime.External); 87 | ``` 88 | -------------------------------------------------------------------------------- /tutorials/registration/metadata.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Registration.Metadata 3 | title: Registration Metadata 4 | --- 5 | 6 | During registration Unity relies on information you provide to properly register types, instances, and factories. This is a description of metadata you could provide to properly declare how the `Type` should be registered and built: 7 | 8 | ## [Registered Type](xref:Unity.IContainerRegistration#Unity_IContainerRegistration_RegisteredType) 9 | 10 | A `Type` that will be requested during resolution is called **Registered Type**. In the example below `SomeType` would be a registered type. 11 | 12 | ```cs 13 | container.RegisterType(); 14 | ... 15 | var value = container.Resolve(); 16 | ``` 17 | 18 | Different container authors call this type by different names, [FromType](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee650974(v%3dpandp.10)), [ServiceType](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicedescriptor.servicetype), etc. The key point to remember is that this is the `Type` container will be referencing in the internal registry and will be looking for when executing the resolve. 19 | 20 | ## [Name](xref:Unity.IContainerRegistration#Unity_IContainerRegistration_Name) 21 | 22 | Each registration must be unique within the scope on a container it is registered with. A registration is identified by two pieces of information: **`Registered Type`** and **`Name`**. 23 | Adding the name to registration allows multiple 'instances' of the same type to be registered with the container. 24 | 25 | For example, if you register the same service with no name multiple times, each subsequent registration will override the last because in each case you are registering the same type `IService` with the same name `null`: 26 | 27 | ```cs 28 | container.RegisterType(); 29 | container.RegisterType(); 30 | container.RegisterType(); 31 | 32 | var enumeration = container.Resolve>(); 33 | var count = enumeration.Count(); 34 | ``` 35 | 36 | The value of variable `count` will be `1`. 37 | 38 | Adding unique names to registrations makes each unique: 39 | 40 | ```cs 41 | container.RegisterType("1"); 42 | container.RegisterType("2"); 43 | container.RegisterType("3"); 44 | 45 | var enumeration = container.Resolve>(); 46 | var count = enumeration.Count(); 47 | ``` 48 | 49 | In this example the value of variable `count` will be `3`. 50 | 51 | ## [Mapped To Type](xref:Unity.IContainerRegistration#Unity_IContainerRegistration_MappedToType) 52 | 53 | Sometimes it is also called [ToType](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee650974(v%3dpandp.10)), [ImplementationType](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicedescriptor.implementationtype), and etc. It describes the type Unity should use to create the instance. `Mapped To Type` must be descendant of, or it should implement the `Registered Type`. In other words, it must be assignable to a variable of `Registered Type`. 54 | 55 | This registration member creates a mapping between service and implementation types. In the following example `IService` is mapped to `Service` and when Unity container is asked to resolve `IService` it will, in turn, create an instance of type `Service` and return it as interface `IService`. 56 | 57 | ```cs 58 | container.RegisterType(); 59 | 60 | var result = container.Resolve(); 61 | 62 | Assert(typeof(Service) == result.GetType()) 63 | ``` 64 | 65 | For more information see [Type Mapping](xref:Tutorial.Mapping). 66 | 67 | ## [Lifetime Manager](xref:Unity.IContainerRegistration#Unity_IContainerRegistration_LifetimeManager) 68 | 69 | This member holds a reference to a lifetime manager that Unity will be using to manage instance(s) of this type. For more information see [Lifetime Management](../lifetime/lifetime.md). 70 | -------------------------------------------------------------------------------- /tutorials/registration/registration.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Tutorial.Registration 3 | title: Registration 4 | --- 5 | 6 | # Registration 7 | 8 | Unity does not require `Type` to be registered to resolve it. 9 | 10 | Any concrete, constructable `Type` could be resolved by Unity without any prior preparation. It will even create and supply parameters if required. In other words, if you can create a `Type` with `new` operator: 11 | 12 | ```cs 13 | var value = new SomeClass(new SomeOtherClass()); 14 | ``` 15 | 16 | you can resolve it from Unity: 17 | 18 | ```cs 19 | var value = container.Resolve(); 20 | ``` 21 | 22 | ## Minimum Registration Requirements 23 | 24 | A lot of times, if type does not require any custom steps, it is faster to resolve `Type` from the container if it is not registered. You should only register a `Type` if one of the following is required: 25 | 26 | * Lifetime policy other than transient 27 | * Nondefault constructor should be selected 28 | * Properties or fields not marked with appropriate attributes should be injected 29 | * Method should be called during initialization on the created object 30 | * Mapping between service and implementation types 31 | 32 | ## What is a Registration and how it works 33 | 34 | Registration is how you control Unity to do it 'Your' way. When you register a `Type`, you are instructing Unity to create and initialize an instance of that `Type` in a very particular way. You also instruct Unity how to deal with the crated instance during its lifetime. 35 | 36 | Once registration is complete, Unity creates a blueprint of the type factory where it stores implementation details (name, to and from types, etc.), information about what members to inject and how, and lifetime manager responsible for managing the instance. 37 | At the later time, when that `Type` is requested, Unity uses this blueprint to create a pipeline (resolver delegate) to be used to create type. 38 | 39 | Each Unity container exposes a [collection](xref:Unity.IUnityContainer#Unity_IUnityContainer_Registrations) of available registrations presented as an enumeration of [IContainerRegistration](xref:Unity.IContainerRegistration) objects. This collection could be used to filter and select certain registrations as well as to [check if the `Type` is registered](xref:Unity.IUnityContainer#Unity_IUnityContainer_IsRegistered_System_Type_System_String_) and how. 40 | 41 | ## Different types of registrations 42 | 43 | Unity recognizes three different scenarios of how instances and types are created and based on these allows three different types of registrations: 44 | 45 | ### Instances created outside of Unity 46 | 47 | A lot of times parts of system's infrastructure require to be available to clients and services of the application. These entities are created and managed outside of the Unity but should be accessible by consumers of the framework during resolution. To enable access to these objects Unity provides a way to register instances. For more information see . 48 | 49 | ### Instances created by Unity using provided Type Factory 50 | 51 | Although Unity is quite capable in creating instances of types, sometimes it is more efficient or desireable to use `Type` factories. Unity provides API to register a special factory delegate. For more information see 52 | 53 | ### Instances created by Unity 54 | 55 | This is the most common scenario where objects are created by the container itself. Creation process is controlled by either `Type` registrations associated with the container or implicit Unity defaults if none registered. For more information how `Type` can be registered see 56 | 57 | ## Container Hierarchies 58 | 59 | Unity container provides a way to create child containers (also referred as creating scopes) and allows building sophisticated hierarchical trees of registrations. There are just a few simple rules to follow when dealing with container hierarchies. For more information see -------------------------------------------------------------------------------- /tutorials/registration/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Metadata 2 | uid: Tutorial.Registration.Metadata 3 | - name: Instance Registration 4 | uid: Tutorial.Registration.Instance 5 | - name: Factory Registration 6 | uid: Tutorial.Registration.Factory 7 | - name: Type Registration 8 | href: Type/toc.yml 9 | topicUid: Tutorial.Registration.Type 10 | -------------------------------------------------------------------------------- /tutorials/toc.yml: -------------------------------------------------------------------------------- 1 | #- name: Terms and Definitions 2 | # uid: Tutorial.Terms 3 | - name: Composition 4 | href: Composition/toc.yml 5 | topicUid: Tutorial.Composition 6 | - name: Attributed Injection Model 7 | href: Annotation/toc.yml 8 | topicUid: Tutorial.Annotation 9 | - name: Registration 10 | href: Registration/toc.yml 11 | topicUid: Tutorial.Registration 12 | - name: Hierarchies 13 | uid: Tutorial.Container.Hierarchy 14 | - name: Lifetime 15 | href: Lifetime/toc.yml 16 | topicUid: Tutorial.Lifetime 17 | - name: Extensions 18 | href: Extensions/toc.yml 19 | topicUid: Tutorial.Extensions 20 | 21 | 22 | --------------------------------------------------------------------------------