Showing preview only (280K chars total). Download the full file or copy to clipboard to get everything.
Repository: autofac/Autofac.Extensions.DependencyInjection
Branch: develop
Commit: 303d9a8194cf
Files: 115
Total size: 249.0 KB
Directory structure:
gitextract_omufirln/
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── build.yml
│ ├── ci.yml
│ ├── dotnet-format.yml
│ ├── pre-commit.yml
│ └── publish.yml
├── .gitignore
├── .markdownlint.json
├── .pre-commit-config.yaml
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── Autofac.Extensions.DependencyInjection.sln
├── Autofac.Extensions.DependencyInjection.sln.DotSettings
├── Autofac.snk
├── Directory.Build.props
├── LICENSE
├── README.md
├── bench/
│ └── Autofac.Extensions.DependencyInjection.Bench/
│ ├── Autofac.Extensions.DependencyInjection.Bench.csproj
│ ├── AutofacWebApplicationFactory.cs
│ ├── BenchWebApplicationFactory.cs
│ ├── BenchmarkConfig.cs
│ ├── Benchmarks.cs
│ ├── DefaultWebApplicationFactory.cs
│ ├── Harness.cs
│ ├── KeyedResolutionBenchmark.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── RequestBenchmark.cs
│ ├── SampleApp/
│ │ ├── Controllers/
│ │ │ └── ValuesController.cs
│ │ ├── DefaultStartup.cs
│ │ ├── Program.cs
│ │ └── Services.cs
│ └── xunit.runner.json
├── build/
│ ├── Coverage.runsettings
│ ├── Source.ruleset
│ ├── Test.ruleset
│ └── stylecop.json
├── codecov.yml
├── default.proj
├── global.json
├── src/
│ └── Autofac.Extensions.DependencyInjection/
│ ├── Autofac.Extensions.DependencyInjection.csproj
│ ├── AutofacChildLifetimeScopeConfigurationAdapter.cs
│ ├── AutofacChildLifetimeScopeServiceProviderFactory.cs
│ ├── AutofacRegistration.cs
│ ├── AutofacServiceProvider.cs
│ ├── AutofacServiceProviderFactory.cs
│ ├── AutofacServiceScope.cs
│ ├── AutofacServiceScopeFactory.cs
│ ├── FromKeyedServicesAttributeExtensions.cs
│ ├── FromKeyedServicesUsageCache.cs
│ ├── KeyTypeConversionException.cs
│ ├── KeyTypeConversionExceptionResources.resx
│ ├── KeyTypeManipulation.cs
│ ├── KeyTypeManipulationResources.resx
│ ├── KeyedServiceMiddleware.cs
│ ├── Polyfills/
│ │ └── NotNullWhenAttribute.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── ServiceCollectionExtensions.cs
│ ├── ServiceDescriptorExtensions.cs
│ ├── ServiceProviderExtensions.cs
│ ├── ServiceProviderExtensionsResources.resx
│ └── TypeExtensions.cs
└── test/
├── Autofac.Extensions.DependencyInjection.Integration.Test/
│ ├── Autofac.Extensions.DependencyInjection.Integration.Test.csproj
│ ├── IntegrationTests.cs
│ └── Properties/
│ └── AssemblyInfo.cs
├── Autofac.Extensions.DependencyInjection.Test/
│ ├── Assertions.cs
│ ├── Autofac.Extensions.DependencyInjection.Test.csproj
│ ├── AutofacChildLifetimeScopeConfigurationAdapterTests.cs
│ ├── AutofacChildLifetimeScopeServiceProviderFactoryTests.cs
│ ├── AutofacRegistrationTests.cs
│ ├── AutofacServiceProviderFactoryTests.cs
│ ├── AutofacServiceProviderTests.cs
│ ├── FromKeyedServicesAttributeExtensionsTests.cs
│ ├── FromKeyedServicesUsageCacheTests.cs
│ ├── KeyTypeManipulationFixture.cs
│ ├── KeyedServiceTests.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── ServiceCollectionExtensionsTests.cs
│ ├── ServiceProviderExtensionsTests.cs
│ ├── Specification/
│ │ ├── AssumedBehaviorTests.cs
│ │ ├── BuilderAssumedBehaviorTests.cs
│ │ ├── BuilderKeyedSpecificationTests.cs
│ │ ├── BuilderSpecificationTests.cs
│ │ ├── ChildScopeFactoryAssumedBehaviorTests.cs
│ │ ├── ChildScopeFactoryKeyedSpecificationTests.cs
│ │ ├── ChildScopeFactorySpecificationTests.cs
│ │ ├── FactoryAssumedBehaviorTests.cs
│ │ ├── FactoryKeyedSpecificationTests.cs
│ │ ├── FactorySpecificationTests.cs
│ │ └── MicrosoftAssumedBehaviorTests.cs
│ ├── TestCulture.cs
│ └── TypeExtensionsTests.cs
├── Integration.Net10/
│ ├── Controllers/
│ │ └── DateController.cs
│ ├── DateProvider.cs
│ ├── IDateProvider.cs
│ ├── Integration.Net10.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
└── Integration.Net8/
├── Controllers/
│ └── DateController.cs
├── DateProvider.cs
├── IDateProvider.cs
├── Integration.Net8.csproj
├── Program.cs
├── Properties/
│ ├── AssemblyInfo.cs
│ └── launchSettings.json
├── Startup.cs
├── appsettings.Development.json
└── appsettings.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
; EditorConfig to support per-solution formatting.
; Use the EditorConfig VS add-in to make this work.
; http://editorconfig.org/
; This is the default for the codeline.
root = true
[*]
indent_style = space
trim_trailing_whitespace = true
insert_final_newline = true
; .NET Code - almost, but not exactly, the same suggestions as corefx
; https://github.com/dotnet/corefx/blob/master/.editorconfig
[*.cs]
indent_size = 4
charset = utf-8-bom
; New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
; Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
; Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:warning
; Avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
; Types: use keywords instead of BCL types, using var is fine.
csharp_style_var_when_type_is_apparent = false:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
; Name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
; Static fields should be _camelCase
dotnet_naming_rule.static_fields_should_be_camel_case.severity = warning
dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
dotnet_naming_rule.static_fields_should_be_camel_case.style = camel_case_underscore_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
; Static readonly fields should be PascalCase
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = static_readonly_fields
dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
dotnet_naming_symbols.static_readonly_fields.applicable_accessibilities = private, internal, private_protected
; Internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = warning
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
; Code style defaults
csharp_using_directive_placement = outside_namespace:suggestion
dotnet_sort_system_directives_first = true
csharp_prefer_braces = true:refactoring
csharp_preserve_single_line_blocks = true:none
csharp_preserve_single_line_statements = false:none
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
; Code quality
dotnet_style_readonly_field = true:suggestion
dotnet_code_quality_unused_parameters = non_public:suggestion
; Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:refactoring
dotnet_style_prefer_conditional_expression_over_return = true:refactoring
csharp_prefer_simple_default_expression = true:suggestion
# Expression-bodied members
csharp_style_expression_bodied_methods = true:refactoring
csharp_style_expression_bodied_constructors = true:refactoring
csharp_style_expression_bodied_operators = true:refactoring
csharp_style_expression_bodied_properties = true:refactoring
csharp_style_expression_bodied_indexers = true:refactoring
csharp_style_expression_bodied_accessors = true:refactoring
csharp_style_expression_bodied_lambdas = true:refactoring
csharp_style_expression_bodied_local_functions = true:refactoring
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
# Null checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Other features
csharp_style_namespace_declarations = file_scoped:suggestion
csharp_style_prefer_index_operator = false:none
csharp_style_prefer_range_operator = false:none
csharp_style_pattern_local_over_anonymous_function = false:none
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = do_not_ignore
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
; .NET project files and MSBuild - match defaults for VS
[*.{csproj,nuspec,proj,projitems,props,shproj,targets,vbproj,vcxproj,vcxproj.filters,vsixmanifest,vsct}]
indent_size = 2
; .NET solution files - match defaults for VS
[*.sln]
end_of_line = crlf
indent_style = tab
; Config - match XML and default nuget.config template
[*.config]
indent_size = 2
; Resources - match defaults for VS
[*.resx]
indent_size = 2
; Static analysis rulesets - match defaults for VS
[*.ruleset]
indent_size = 2
; HTML, XML - match defaults for VS
[*.{cshtml,html,xml}]
indent_size = 4
; JavaScript and JS mixes - match eslint settings; JSON also matches .NET Core templates
[*.{js,json,ts,vue}]
indent_size = 2
; Markdown - match markdownlint settings
[*.{md,markdown}]
indent_size = 2
; PowerShell - match defaults for New-ModuleManifest and PSScriptAnalyzer Invoke-Formatter
[*.{ps1,psd1,psm1}]
indent_size = 4
charset = utf-8-bom
; ReStructuredText - standard indentation format from examples
[*.rst]
indent_size = 2
# YAML - match standard YAML like Kubernetes and GitHub Actions
[*.{yaml,yml}]
indent_size = 2
================================================
FILE: .gitattributes
================================================
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.jpg binary
*.png binary
*.gif binary
*.cs text=auto diff=csharp
*.vb text=auto
*.resx text=auto
*.c text=auto
*.cpp text=auto
*.cxx text=auto
*.h text=auto
*.hxx text=auto
*.py text=auto
*.rb text=auto
*.java text=auto
*.html text=auto
*.htm text=auto
*.css text=auto
*.scss text=auto
*.sass text=auto
*.less text=auto
*.js text=auto
*.lisp text=auto
*.clj text=auto
*.sql text=auto
*.php text=auto
*.lua text=auto
*.m text=auto
*.asm text=auto
*.erl text=auto
*.fs text=auto
*.fsx text=auto
*.hs text=auto
*.csproj text=auto
*.vbproj text=auto
*.fsproj text=auto
*.dbproj text=auto
*.sln text=auto eol=crlf
================================================
FILE: .github/workflows/build.yml
================================================
name: Build and Test
on:
workflow_call:
secrets:
CODECOV_TOKEN:
description: Token for uploading code coverage metrics to CodeCov.io.
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
10.0.x
- name: Build and test
run: dotnet msbuild ./default.proj
- name: Upload coverage
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
files: artifacts/logs/*/coverage.cobertura.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload package artifacts
uses: actions/upload-artifact@v7
with:
name: packages
path: |
artifacts/packages/*.nupkg
artifacts/packages/*.snupkg
================================================
FILE: .github/workflows/ci.yml
================================================
name: Continuous Integration
on:
pull_request:
branches:
- develop
- master
push:
branches:
- develop
- master
- feature/*
tags:
- v[0-9]+.[0-9]+.[0-9]+
# If multiple pushes happen quickly in succession, cancel the running build and
# start a new one.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Linting
dotnet-format:
uses: ./.github/workflows/dotnet-format.yml
pre-commit:
uses: ./.github/workflows/pre-commit.yml
# Build and test
build:
uses: ./.github/workflows/build.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# Publish beta and release packages.
publish:
uses: ./.github/workflows/publish.yml
needs:
- build
- dotnet-format
- pre-commit
if: ${{ github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/v') }}
secrets:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
================================================
FILE: .github/workflows/dotnet-format.yml
================================================
name: dotnet format
on:
workflow_call:
jobs:
dotnet-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup .NET 10
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: dotnet format
run: dotnet format Autofac.Extensions.DependencyInjection.sln --verify-no-changes
================================================
FILE: .github/workflows/pre-commit.yml
================================================
name: pre-commit
on:
workflow_call:
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- uses: pre-commit/action@v3.0.1
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish
on:
workflow_call:
secrets:
NUGET_API_KEY:
description: Token for publishing packages to NuGet.
required: true
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: Download package artifacts
uses: actions/download-artifact@v8
with:
name: packages
path: artifacts/packages
- name: Publish to GitHub Packages
run: |
dotnet nuget add source --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/autofac/index.json"
dotnet nuget push ./artifacts/packages/*.nupkg --skip-duplicate --source github --api-key ${{ secrets.GITHUB_TOKEN }}
dotnet nuget push ./artifacts/packages/*.snupkg --skip-duplicate --source github --api-key ${{ secrets.GITHUB_TOKEN }}
- name: Publish to NuGet
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: |
dotnet nuget push ./artifacts/packages/*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Project specific files
artifacts/
BenchmarkDotNet.Artifacts/
# User-specific files
*.suo
*.user
*.sln.docstates
*.ide
Index.dat
Storage.dat
# Build results
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.dotnet/
.vs/
.cr/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.TestResults.xml
results/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.pubxml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
!stylecop.json
~$*
*~
*.dbmdl
*.pfx
*.publishsettings
node_modules/
bower_components/
wwwroot/
project.lock.json
*.Designer.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
# JetBrains Rider
.idea
================================================
FILE: .markdownlint.json
================================================
{
"MD013": false
}
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "3e8a8703264a2f4a69428a0aa4dcb512790b2c8c" # frozen: v6.0.0
hooks:
- id: check-json
- id: check-yaml
- id: check-merge-conflict
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: "76b3d32d3f4b965e1d6425253c59407420ae2c43" # frozen: v0.47.0
hooks:
- id: markdownlint
args:
- --fix
- repo: https://github.com/tillig/json-sort-cli
rev: "009ab2ab49e1f2fa9d6b9dfc31009ceeca055204" # frozen: v3.0.0
hooks:
- id: json-sort
args:
- --autofix
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"davidanson.vscode-markdownlint",
"editorconfig.editorconfig",
"ms-dotnettools.csdevkit",
"travisillig.vscode-json-stable-stringify"
]
}
================================================
FILE: .vscode/launch.json
================================================
{
"configurations": [
{
"args": [
],
"cwd": "${workspaceFolder}/test/Integration.Net8",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"name": "Launch .NET 8 Integration Site",
"preLaunchTask": "build",
"program": "${workspaceFolder}/test/Integration.Net8/bin/Debug/net8.0/Integration.Net8.dll",
"request": "launch",
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
"uriFormat": "%s/date"
},
"stopAtEntry": false,
"type": "coreclr"
},
{
"args": [
],
"cwd": "${workspaceFolder}/test/Integration.Net10",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"name": "Launch .NET 10 Integration Site",
"preLaunchTask": "build",
"program": "${workspaceFolder}/test/Integration.Net10/bin/Debug/net10.0/Integration.Net10.dll",
"request": "launch",
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
"uriFormat": "%s/date"
},
"stopAtEntry": false,
"type": "coreclr"
}
],
"version": "0.2.0"
}
================================================
FILE: .vscode/settings.json
================================================
{
"cSpell.words": [
"autofac",
"cref",
"diagnoser",
"diagnosers",
"inheritdoc",
"langword",
"paramref",
"seealso",
"typeparam",
"unmanaged",
"xunit"
],
"coverage-gutters.coverageBaseDir": "artifacts/logs",
"coverage-gutters.coverageFileNames": [
"**/coverage.cobertura.xml"
],
"dotnet.defaultSolution": "Autofac.Extensions.DependencyInjection.sln",
"dotnet.unitTestDebuggingOptions": {
"enableStepFiltering": false,
"justMyCode": false,
"requireExactSource": false,
"sourceLinkOptions": {
"*": {
"enabled": true
}
},
"suppressJITOptimizations": true,
"symbolOptions": {
"searchNuGetOrgSymbolServer": true
}
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.resx": "$(capture).*.resx, $(capture).designer.cs, $(capture).designer.vb"
},
"files.watcherExclude": {
"**/target": true
}
}
================================================
FILE: .vscode/tasks.json
================================================
{
"linux": {
"options": {
"shell": {
"args": [
"-NoProfile",
"-Command"
],
"executable": "pwsh"
}
}
},
"osx": {
"options": {
"shell": {
"args": [
"-NoProfile",
"-Command"
],
"executable": "/usr/local/bin/pwsh"
}
}
},
"tasks": [
{
"command": "If (Test-Path ${workspaceFolder}/artifacts/logs) { Remove-Item ${workspaceFolder}/artifacts/logs -Recurse -Force }; New-Item -Path ${workspaceFolder}/artifacts/logs -ItemType Directory -Force | Out-Null",
"label": "create log directory",
"type": "shell"
},
{
"args": [
"build",
"${workspaceFolder}/Autofac.Extensions.DependencyInjection.sln",
"--tl:off",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"command": "dotnet",
"group": {
"isDefault": true,
"kind": "build"
},
"label": "build",
"problemMatcher": "$msCompile",
"type": "shell"
},
{
"args": [
"test",
"${workspaceFolder}/Autofac.Extensions.DependencyInjection.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"--results-directory",
"artifacts/logs",
"--logger:trx",
"--collect:XPlat Code Coverage",
"--settings:build/Coverage.runsettings",
"--filter",
"FullyQualifiedName!~Bench"
],
"command": "dotnet",
"dependsOn": [
"create log directory"
],
"group": {
"isDefault": true,
"kind": "test"
},
"label": "test",
"problemMatcher": "$msCompile",
"type": "process"
}
],
"version": "2.0.0",
"windows": {
"options": {
"shell": {
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command"
],
"executable": "pwsh.exe"
}
}
}
}
================================================
FILE: Autofac.Extensions.DependencyInjection.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29201.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5A54DF18-E3F3-4929-876D-00650A15763E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DEA4A8C6-DE56-4359-A87C-472FB34132E7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6B324E70-6C86-4E09-B150-CAE9DD2BADCC}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
global.json = global.json
codecov.yml = codecov.yml
default.proj = default.proj
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autofac.Extensions.DependencyInjection", "src\Autofac.Extensions.DependencyInjection\Autofac.Extensions.DependencyInjection.csproj", "{513C7F7A-A758-4D48-94F4-891A00F63DA1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autofac.Extensions.DependencyInjection.Test", "test\Autofac.Extensions.DependencyInjection.Test\Autofac.Extensions.DependencyInjection.Test.csproj", "{911AA52A-4E68-41C5-AB24-D1618AFDF753}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bench", "bench", "{C39BE99E-D778-485B-920A-42D4EB3CBA75}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autofac.Extensions.DependencyInjection.Bench", "bench\Autofac.Extensions.DependencyInjection.Bench\Autofac.Extensions.DependencyInjection.Bench.csproj", "{639CD744-1E61-4EF8-9E5A-9920A6BC3891}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{4072A677-5ACA-4CA4-B5EB-9B9DE7D1DD08}"
ProjectSection(SolutionItems) = preProject
build\Analyzers.ruleset = build\Analyzers.ruleset
build\Autofac.Build.psd1 = build\Autofac.Build.psd1
build\Autofac.Build.psm1 = build\Autofac.Build.psm1
build\CodeAnalysisDictionary.xml = build\CodeAnalysisDictionary.xml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autofac.Extensions.DependencyInjection.Integration.Test", "test\Autofac.Extensions.DependencyInjection.Integration.Test\Autofac.Extensions.DependencyInjection.Integration.Test.csproj", "{D6217688-8E4A-4092-8D78-C4D299F27D7B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Net8", "test\Integration.Net8\Integration.Net8.csproj", "{549E4C50-7B8F-4E18-92E1-60F036B3515F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Net10", "test\Integration.Net10\Integration.Net10.csproj", "{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|ARM.ActiveCfg = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|ARM.Build.0 = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|x64.ActiveCfg = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|x64.Build.0 = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|x86.ActiveCfg = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Debug|x86.Build.0 = Debug|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|Any CPU.Build.0 = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|ARM.ActiveCfg = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|ARM.Build.0 = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|x64.ActiveCfg = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|x64.Build.0 = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|x86.ActiveCfg = Release|Any CPU
{513C7F7A-A758-4D48-94F4-891A00F63DA1}.Release|x86.Build.0 = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|Any CPU.Build.0 = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|ARM.ActiveCfg = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|ARM.Build.0 = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|x64.ActiveCfg = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|x64.Build.0 = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|x86.ActiveCfg = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Debug|x86.Build.0 = Debug|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|Any CPU.ActiveCfg = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|Any CPU.Build.0 = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|ARM.ActiveCfg = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|ARM.Build.0 = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|x64.ActiveCfg = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|x64.Build.0 = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|x86.ActiveCfg = Release|Any CPU
{911AA52A-4E68-41C5-AB24-D1618AFDF753}.Release|x86.Build.0 = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|Any CPU.Build.0 = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|ARM.ActiveCfg = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|ARM.Build.0 = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|x64.ActiveCfg = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|x64.Build.0 = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|x86.ActiveCfg = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Debug|x86.Build.0 = Debug|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|Any CPU.ActiveCfg = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|Any CPU.Build.0 = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|ARM.ActiveCfg = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|ARM.Build.0 = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|x64.ActiveCfg = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|x64.Build.0 = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|x86.ActiveCfg = Release|Any CPU
{639CD744-1E61-4EF8-9E5A-9920A6BC3891}.Release|x86.Build.0 = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|ARM.Build.0 = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|x64.Build.0 = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Debug|x86.Build.0 = Debug|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|Any CPU.Build.0 = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|ARM.ActiveCfg = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|ARM.Build.0 = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|x64.ActiveCfg = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|x64.Build.0 = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|x86.ActiveCfg = Release|Any CPU
{D6217688-8E4A-4092-8D78-C4D299F27D7B}.Release|x86.Build.0 = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|ARM.Build.0 = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|x64.ActiveCfg = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|x64.Build.0 = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|x86.ActiveCfg = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Debug|x86.Build.0 = Debug|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|Any CPU.Build.0 = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|ARM.ActiveCfg = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|ARM.Build.0 = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|x64.ActiveCfg = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|x64.Build.0 = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|x86.ActiveCfg = Release|Any CPU
{549E4C50-7B8F-4E18-92E1-60F036B3515F}.Release|x86.Build.0 = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|ARM.Build.0 = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|x64.ActiveCfg = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|x64.Build.0 = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|x86.ActiveCfg = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Debug|x86.Build.0 = Debug|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|Any CPU.Build.0 = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|ARM.ActiveCfg = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|ARM.Build.0 = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|x64.ActiveCfg = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|x64.Build.0 = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|x86.ActiveCfg = Release|Any CPU
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{513C7F7A-A758-4D48-94F4-891A00F63DA1} = {5A54DF18-E3F3-4929-876D-00650A15763E}
{911AA52A-4E68-41C5-AB24-D1618AFDF753} = {DEA4A8C6-DE56-4359-A87C-472FB34132E7}
{639CD744-1E61-4EF8-9E5A-9920A6BC3891} = {C39BE99E-D778-485B-920A-42D4EB3CBA75}
{D6217688-8E4A-4092-8D78-C4D299F27D7B} = {DEA4A8C6-DE56-4359-A87C-472FB34132E7}
{549E4C50-7B8F-4E18-92E1-60F036B3515F} = {DEA4A8C6-DE56-4359-A87C-472FB34132E7}
{3514BA96-C0C2-44A5-95EF-EF3F54219CDC} = {DEA4A8C6-DE56-4359-A87C-472FB34132E7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {76E0A652-E5E2-4CA4-BAFD-AF6FDE0BD56A}
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35;packages\Unity.Interception.2.1.505.0\lib\NET35;packages\EnterpriseLibrary.Common.5.0.505.0\lib\NET35;packages\EnterpriseLibrary.ExceptionHandling.5.0.505.0\lib\NET35;packages\Unity.2.1.505.2\lib\NET35;packages\Unity.Interception.2.1.505.2\lib\NET35
EndGlobalSection
EndGlobal
================================================
FILE: Autofac.Extensions.DependencyInjection.sln.DotSettings
================================================
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Autofac/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
================================================
FILE: Directory.Build.props
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright © 2014 Autofac Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Autofac.Extensions.DependencyInjection
Autofac is an [IoC container](http://martinfowler.com/articles/injection.html) for Microsoft .NET. It manages the dependencies between classes so that **applications stay easy to change as they grow** in size and complexity. This is achieved by treating regular .NET classes as *[components](https://autofac.readthedocs.io/en/latest/glossary.html)*.
[](https://ci.appveyor.com/project/Autofac/autofac-extensions-dependencyinjection/branch/develop) [](https://codecov.io/gh/Autofac/Autofac.Extensions.DependencyInjection)
Please file issues and pull requests for this package in this repository rather than in the Autofac core repo.
- [Documentation - .NET Core Integration](https://autofac.readthedocs.io/en/latest/integration/netcore.html)
- [Documentation - ASP.NET Core Integration](https://autofac.readthedocs.io/en/latest/integration/aspnetcore.html)
- [NuGet](https://www.nuget.org/packages/Autofac.Extensions.DependencyInjection)
- [Contributing](https://autofac.readthedocs.io/en/latest/contributors.html)
- [Open in Visual Studio Code](https://open.vscode.dev/autofac/Autofac.Extensions.DependencyInjection)
## Get Started in ASP.NET Core
This quick start shows how to use the `IServiceProviderFactory{T}` integration that ASP.NET Core supports to help automatically build the root service provider for you. If you want more manual control, [check out the documentation for examples](https://autofac.readthedocs.io/en/latest/integration/aspnetcore.html).
- Reference the `Autofac.Extensions.DependencyInjection` package from NuGet.
- In your `Program.Main` method, where you configure the `HostBuilder`, call `UseAutofac` to hook Autofac into the startup pipeline.
- In the `ConfigureServices` method of your `Startup` class register things into the `IServiceCollection` using extension methods provided by other libraries.
- In the `ConfigureContainer` method of your `Startup` class register things directly into an Autofac `ContainerBuilder`.
The `IServiceProvider` will automatically be created for you, so there's nothing you have to do but *register things*.
```C#
public class Program
{
public static async Task Main(string[] args)
{
// The service provider factory used here allows for
// ConfigureContainer to be supported in Startup with
// a strongly-typed ContainerBuilder.
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webHostBuilder => {
webHostBuilder
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
})
.Build();
await host.RunAsync();
}
}
public class Startup
{
public Startup(IWebHostEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
public IConfiguration Configuration { get; private set; }
// ConfigureServices is where you register dependencies. This gets
// called by the runtime before the ConfigureContainer method, below.
public void ConfigureServices(IServiceCollection services)
{
// Add services to the collection. Don't build or return
// any IServiceProvider or the ConfigureContainer method
// won't get called.
services.AddOptions();
}
// ConfigureContainer is where you can register things directly
// with Autofac. This runs after ConfigureServices so the things
// here will override registrations made in ConfigureServices.
// Don't build the container; that gets done for you. If you
// need a reference to the container, you need to use the
// "Without ConfigureContainer" mechanism shown later.
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacModule());
}
// Configure is where you add middleware. This is called after
// ConfigureContainer. You can use IApplicationBuilder.ApplicationServices
// here if you need to resolve things from the container.
public void Configure(
IApplicationBuilder app,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
```
Our [ASP.NET Core](https://autofac.readthedocs.io/en/latest/integration/aspnetcore.html) integration documentation contains more information about using Autofac with ASP.NET Core.
## Get Help
**Need help with Autofac?** We have [a documentation site](https://autofac.readthedocs.io/) as well as [API documentation](https://autofac.org/apidoc/). We're ready to answer your questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/autofac) or check out the [discussion forum](https://groups.google.com/forum/#forum/autofac).
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Autofac.Extensions.DependencyInjection.Bench.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<OutputType>Exe</OutputType>
<GenerateProgramFile>false</GenerateProgramFile>
<PlatformTarget>$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)</PlatformTarget>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<CodeAnalysisRuleSet>../../build/Test.ruleset</CodeAnalysisRuleSet>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<PreserveCompilationContext>true</PreserveCompilationContext>
<UseProjectReference Condition="'$(UseProjectReference)' == ''">true</UseProjectReference>
</PropertyGroup>
<ItemGroup>
<Using Include="BenchmarkDotNet.Attributes" />
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<Compile Remove="BenchmarkDotNet.Artifacts\**" />
<EmbeddedResource Remove="BenchmarkDotNet.Artifacts\**" />
<None Remove="BenchmarkDotNet.Artifacts\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="coverlet.collector" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(UseProjectReference)' == 'true'">
<ProjectReference Include="..\..\src\Autofac.Extensions.DependencyInjection\Autofac.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(UseProjectReference)' != 'true' and '$(BaselinePackageVersion)' != ''">
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="$(BaselinePackageVersion)" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\build\stylecop.json" Link="stylecop.json" />
</ItemGroup>
</Project>
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/AutofacWebApplicationFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.Hosting;
namespace Autofac.Extensions.DependencyInjection.Bench;
public sealed class AutofacWebApplicationFactory<TStartup> : BenchWebApplicationFactory<TStartup>
where TStartup : class
{
protected override IHost CreateHost(IHostBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);
builder.UseServiceProviderFactory(new AutofacServiceProviderFactory());
return base.CreateHost(builder);
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/BenchWebApplicationFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.IO;
using System.Threading;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Hosting;
namespace Autofac.Extensions.DependencyInjection.Bench;
public abstract class BenchWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup>
where TStartup : class
{
private static readonly Lazy<string> ContentRoot = new(ResolveContentRoot, LazyThreadSafetyMode.ExecutionAndPublication);
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);
base.ConfigureWebHost(builder);
builder.UseContentRoot(ContentRoot.Value);
}
private static string ResolveContentRoot() =>
Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", ".."));
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/BenchmarkConfig.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
namespace Autofac.Extensions.DependencyInjection.Bench;
internal sealed class BenchmarkConfig : ManualConfig
{
private const string BenchmarkArtifactsFolder = "BenchmarkDotNet.Artifacts";
internal BenchmarkConfig()
{
Add(DefaultConfig.Instance);
var rootFolder = AppContext.BaseDirectory.Substring(0, AppContext.BaseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase));
var runFolder = DateTime.Now.ToString("u").Replace(' ', '_').Replace(':', '-');
ArtifactsPath = Path.Combine(rootFolder, BenchmarkArtifactsFolder, runFolder);
AddDiagnoser(MemoryDiagnoser.Default);
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Benchmarks.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Autofac.Extensions.DependencyInjection.Bench;
public static class Benchmarks
{
public static readonly Type[] All =
{
typeof(RequestBenchmark),
typeof(KeyedResolutionBenchmark),
};
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/DefaultWebApplicationFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Autofac.Extensions.DependencyInjection.Bench;
public sealed class DefaultWebApplicationFactory<TStartup> : BenchWebApplicationFactory<TStartup>
where TStartup : class
{
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Harness.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using BenchmarkDotNet.Running;
namespace Autofac.Extensions.DependencyInjection.Bench;
public class Harness
{
[Fact]
public void Request() => RunBenchmark<RequestBenchmark>();
[Fact]
public void KeyedResolution() => RunBenchmark<KeyedResolutionBenchmark>();
/// <remarks>
/// This method is used to enforce that benchmark types are added to <see cref="Benchmarks.All"/>
/// so that they can be used directly from the command line in <see cref="Program.Main"/> as well.
/// </remarks>
private static void RunBenchmark<TBenchmark>()
{
var targetType = typeof(TBenchmark);
var benchmarkType = Benchmarks.All.Single(type => type == targetType);
BenchmarkRunner.Run(benchmarkType, new BenchmarkConfig());
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/KeyedResolutionBenchmark.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
using MicrosoftServiceKey = Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute;
namespace Autofac.Extensions.DependencyInjection.Bench;
[MemoryDiagnoser]
[SuppressMessage("CA1001", "CA1001", Justification = "Benchmark disposal happens in GlobalCleanup.")]
public class KeyedResolutionBenchmark
{
private const string AlphaKey = "alpha";
private const string BetaKey = "beta";
private const string ServiceKeyAwareKey = "gamma";
private const string CombinedKey = "combined";
private AutofacServiceProvider _serviceProvider = null!;
private ILifetimeScope _rootScope = null!;
[GlobalSetup]
public void Setup()
{
var services = new ServiceCollection();
services.AddTransient<IService, DefaultService>();
services.AddKeyedTransient<IService, AlphaService>(AlphaKey);
services.AddKeyedTransient<IService, BetaService>(BetaKey);
services.AddKeyedTransient<IService, ServiceKeyAwareService>(ServiceKeyAwareKey);
services.AddTransient<FromKeyedServicesConsumer>();
services.AddKeyedTransient<CombinedConsumer>(CombinedKey);
var builder = new ContainerBuilder();
builder.Populate(services);
_rootScope = builder.Build();
_serviceProvider = new AutofacServiceProvider(_rootScope);
}
[GlobalCleanup]
public void Cleanup()
{
_serviceProvider.Dispose();
}
[Benchmark(Baseline = true)]
public int StandardTypedResolution()
{
return _serviceProvider.GetRequiredService<IService>().Value;
}
[Benchmark]
public int KeyedResolutionWithoutAttributes()
{
return _serviceProvider.GetRequiredKeyedService<IService>(AlphaKey).Value;
}
[Benchmark]
public int KeyedResolutionWithServiceKeyAttribute()
{
return _serviceProvider.GetRequiredKeyedService<IService>(ServiceKeyAwareKey).Value;
}
[Benchmark]
public int KeyedResolutionWithFromKeyedServicesAttribute()
{
return _serviceProvider.GetRequiredService<FromKeyedServicesConsumer>().Value;
}
[Benchmark]
public int KeyedResolutionWithBothAttributes()
{
return _serviceProvider.GetRequiredKeyedService<CombinedConsumer>(CombinedKey).Value;
}
[Benchmark]
public int KeyedResolutionWithAnyKey()
{
var result = _serviceProvider.GetKeyedServices<IService>(KeyedService.AnyKey);
var total = 0;
foreach (var service in result)
{
total += service.Value;
}
return total;
}
private interface IService
{
int Value { get; }
}
private sealed class DefaultService : IService
{
public int Value => 1;
}
private sealed class AlphaService : IService
{
public int Value => 2;
}
private sealed class BetaService : IService
{
public int Value => 3;
}
private sealed class FromKeyedServicesConsumer
{
private readonly IService _service;
public FromKeyedServicesConsumer([FromKeyedServices(BetaKey)] IService service)
{
_service = service;
}
public int Value => _service.Value;
}
private sealed class CombinedConsumer
{
private readonly IService _fromKeyedService;
private readonly object? _requestedKey;
public CombinedConsumer(
[FromKeyedServices(BetaKey)] IService fromKeyedService,
[MicrosoftServiceKey] object? requestedKey)
{
_fromKeyedService = fromKeyedService;
_requestedKey = requestedKey;
}
public int Value
{
get
{
var keyValue = _requestedKey is string s ? s.Length : 0;
return _fromKeyedService.Value + keyValue;
}
}
}
private sealed class ServiceKeyAwareService : IService
{
private readonly string _resolvedKey;
public ServiceKeyAwareService([MicrosoftServiceKey] string resolvedKey)
{
_resolvedKey = resolvedKey;
}
public int Value => _resolvedKey.Length;
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Program.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using Microsoft.Extensions.Hosting;
namespace Autofac.Extensions.DependencyInjection.Bench;
public sealed class Program
{
private Program()
{
}
public static void Main(string[] args)
{
ArgumentNullException.ThrowIfNull(args);
var (filteredArgs, baselineVersion) = ExtractBaselineVersion(args);
// Usage:
//
// Just run the benchmark with the source code version of the project:
// dotnet run -c Release -p bench/Autofac.Extensions.DependencyInjection.Bench
//
// Run the benchmark comparing the source code version to a specific package version:
// dotnet run -c Release -p bench/Autofac.Extensions.DependencyInjection.Bench -- --baseline-version 9.0.0
var config = new BenchmarkConfig();
config.AddJob(
Job.InProcess
.WithId("Source"));
if (!string.IsNullOrWhiteSpace(baselineVersion))
{
config.AddJob(
Job.Default
.WithId($"Package-{baselineVersion}")
.AsBaseline()
.WithMsBuildArguments(
"/p:UseProjectReference=false",
$"/p:BaselinePackageVersion={baselineVersion}"));
}
new BenchmarkSwitcher(Benchmarks.All).Run(filteredArgs, config);
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
SampleApp.Program.CreateHostBuilder(args);
private static (string[] RemainingArgs, string? BaselineVersion) ExtractBaselineVersion(string[] args)
{
var forwarded = new List<string>(args.Length);
string? baseline = null;
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (TryMatchBaselineArg(arg, out var inlineVersion))
{
if (!string.IsNullOrWhiteSpace(inlineVersion))
{
baseline = inlineVersion;
continue;
}
if (i + 1 >= args.Length)
{
throw new ArgumentException("Missing version value for baseline argument.", nameof(args));
}
baseline = args[++i];
continue;
}
forwarded.Add(arg);
}
return (forwarded.ToArray(), baseline);
}
private static bool TryMatchBaselineArg(string arg, out string? valueFromAssignment)
{
valueFromAssignment = null;
static bool Matches(string candidate) =>
candidate.Equals("--baseline-version", StringComparison.OrdinalIgnoreCase) ||
candidate.Equals("--baselineVersion", StringComparison.OrdinalIgnoreCase);
var equalsIndex = arg.AsSpan().IndexOf('=');
if (equalsIndex >= 0)
{
var prefix = arg[..equalsIndex];
if (Matches(prefix))
{
valueFromAssignment = arg[(equalsIndex + 1)..];
return true;
}
return false;
}
return Matches(arg);
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Properties/AssemblyInfo.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
[assembly: CLSCompliant(false)]
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/RequestBenchmark.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using System.Net;
using Microsoft.AspNetCore.Mvc.Testing;
namespace Autofac.Extensions.DependencyInjection.Bench;
[SuppressMessage("CA1001", "CA1001", Justification = "Benchmark disposal happens in a global cleanup method.")]
public class RequestBenchmark
{
private static readonly Uri ValuesUri = new("/api/values", UriKind.Relative);
private WebApplicationFactory<Program> _defaultFactory = null!;
private WebApplicationFactory<Program> _autofacFactory = null!;
private HttpClient _defaultClient = null!;
private HttpClient _autofacClient = null!;
[GlobalSetup]
public void Setup()
{
_defaultFactory = new DefaultWebApplicationFactory<Program>();
_autofacFactory = new AutofacWebApplicationFactory<Program>();
_defaultClient = _defaultFactory.CreateClient();
_autofacClient = _autofacFactory.CreateClient();
}
[GlobalCleanup]
public void Cleanup()
{
_defaultFactory.Dispose();
_autofacFactory.Dispose();
}
[Benchmark(Baseline = true)]
public async Task RequestDefaultDI()
{
var response = await _defaultClient.GetAsync(ValuesUri).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpRequestException();
}
}
[Benchmark]
public async Task RequestAutofacDI()
{
var response = await _autofacClient.GetAsync(ValuesUri).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpRequestException();
}
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Controllers/ValuesController.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.AspNetCore.Mvc;
namespace Autofac.Extensions.DependencyInjection.Bench.SampleApp.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly A _service;
public ValuesController(A service)
{
_service = service;
}
[HttpGet]
public IActionResult Get()
{
return Ok(200);
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/DefaultStartup.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Autofac.Extensions.DependencyInjection.Bench.SampleApp;
public class DefaultStartup
{
public DefaultStartup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient<A>();
services.AddTransient<B1>();
services.AddTransient<B2>();
services.AddTransient<C1>();
services.AddTransient<C2>();
services.AddTransient<D1>();
services.AddTransient<D2>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Program.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Autofac.Extensions.DependencyInjection.Bench.SampleApp;
public sealed class Program
{
private Program()
{
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Warning);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<DefaultStartup>();
});
}
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Services.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
#pragma warning disable SA1402, SA1649
namespace Autofac.Extensions.DependencyInjection.Bench.SampleApp;
public class A
{
public A(B1 b1, B2 b2)
{
}
}
public class B1
{
public B1(B2 b2, C1 c1, C2 c2)
{
}
}
public class B2
{
public B2(C1 c1, C2 c2)
{
}
}
public class C1
{
public C1(C2 c2, D1 d1, D2 d2)
{
}
}
public class C2
{
public C2(D1 d1, D2 d2)
{
}
}
public class D1
{
}
public class D2
{
}
#pragma warning restore SA1402, SA1649
================================================
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/xunit.runner.json
================================================
{
"shadowCopy": false
}
================================================
FILE: build/Coverage.runsettings
================================================
<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat Code Coverage">
<Configuration>
<Format>cobertura</Format>
<Exclude>[System.*]*</Exclude>
<ExcludeByFile>**/LoggerMessage.g.cs</ExcludeByFile>
<ExcludeByAttribute>GeneratedCodeAttribute</ExcludeByAttribute>
<UseSourceLink>false</UseSourceLink>
<SkipAutoProps>true</SkipAutoProps>
<DeterministicReport>false</DeterministicReport>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
================================================
FILE: build/Source.ruleset
================================================
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Autofac Analyzer Rules" Description="Analyzer rules for Autofac assemblies." ToolsVersion="16.0">
<IncludeAll Action="Warning" />
<Rules AnalyzerId="Microsoft.Usage" RuleNamespace="Microsoft.Usage">
<!-- Implement standard exception constructors - not all of the exception constructors (e.g., parameterless) are desired in our system. -->
<Rule Id="CA1032" Action="None" />
<!-- Avoid excessive inheritance (must be explicitly enabled). -->
<Rule Id="CA1501" Action="Warning" />
<!-- Avoid excessive complexity (must be explicitly enabled). -->
<Rule Id="CA1502" Action="Warning" />
<!-- Avoid unmaintainable code (must be explicitly enabled). -->
<Rule Id="CA1505" Action="Warning" />
<!-- Avoid excessive class coupling (must be explicitly enabled). -->
<Rule Id="CA1506" Action="Warning" />
<!-- Use ArgumentNullException.ThrowIfNull - this isn't available until we stop targeting netstandard. -->
<Rule Id="CA1510" Action="None" />
<!-- Use ArgumentOutOfRangeException.ThrowIfNegative - this isn't available until we stop targeting anything below net8.0. -->
<Rule Id="CA1512" Action="None" />
<!-- Use ObjectDisposedException.ThrowIf - this isn't available until we stop targeting anything below net8.0. -->
<Rule Id="CA1513" Action="None" />
<!-- Change names to avoid reserved word overlaps (e.g., Delegate, GetType, etc.) - too many of these in the public API, we'd break if we fixed it. -->
<Rule Id="CA1716" Action="None" />
<!-- Cache a CompositeFormat object for use in String.Format - this isn't available until we stop targeting netstandard, and we only String.Format when throwing exceptions so the work/complexity isn't justified to increase perf just for those situations. -->
<Rule Id="CA1863" Action="None" />
<!-- Implement serialization constructors - false positive when building .NET Core. -->
<Rule Id="CA2229" Action="None" />
<!-- Mark ISerializable types with SerializableAttribute - false positive when building .NET Core. -->
<Rule Id="CA2237" Action="None" />
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- Prefix local calls with this. -->
<Rule Id="SA1101" Action="None" />
<!-- Use built-in type alias. -->
<Rule Id="SA1121" Action="None" />
<!-- Use String.Empty instead of "". -->
<Rule Id="SA1122" Action="None" />
<!-- Fields can't start with underscore. -->
<Rule Id="SA1309" Action="None" />
</Rules>
</RuleSet>
================================================
FILE: build/Test.ruleset
================================================
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Autofac Analyzer Rules" Description="Analyzer rules for Autofac assemblies." ToolsVersion="16.0">
<IncludeAll Action="Warning" />
<Rules AnalyzerId="Microsoft.Usage" RuleNamespace="Microsoft.Usage">
<!-- Avoid excessive parameters on generic types (must be explicitly enabled). -->
<Rule Id="CA1005" Action="Warning" />
<!-- Don't catch general exceptions - test scenarios sometimes require general exception handling. -->
<Rule Id="CA1031" Action="None" />
<!-- Implement standard exception constructors - not all of the exception constructors (e.g., parameterless) are desired in our system. -->
<Rule Id="CA1032" Action="None" />
<!-- Avoid empty interfaces - in unit tests for service resolution, this happens a lot. -->
<Rule Id="CA1040" Action="None" />
<!-- Do not pass literals as localized parameters - tests don't need to localize. -->
<Rule Id="CA1303" Action="None" />
<!-- Avoid excessive inheritance (must be explicitly enabled). -->
<Rule Id="CA1501" Action="Warning" />
<!-- Avoid excessive complexity (must be explicitly enabled). -->
<Rule Id="CA1502" Action="Warning" />
<!-- Avoid unmaintainable code (must be explicitly enabled). -->
<Rule Id="CA1505" Action="Warning" />
<!-- Avoid excessive class coupling (must be explicitly enabled). -->
<Rule Id="CA1506" Action="Warning" />
<!-- Use ArgumentNullException.ThrowIfNull - this isn't available until we stop targeting netstandard. -->
<Rule Id="CA1510" Action="None" />
<!-- Make API types internal - causes problems with tests and test assemblies. -->
<Rule Id="CA1515" Action="None" />
<!-- Remove the underscores from member name - unit test scenarios may use underscores. -->
<Rule Id="CA1707" Action="None" />
<!-- Change names to avoid reserved word overlaps (e.g., Delegate, GetType, etc.) - too many of these in the public API, we'd break if we fixed it. -->
<Rule Id="CA1716" Action="None" />
<!-- Internal class that appears to never be instantiated - lots of false positives here because they're test stubs created by Autofac registrations. -->
<Rule Id="CA1812" Action="None" />
<!-- Change Dispose() to call GC.SuppressFinalize - in tests we don't really care and it can impact readability. -->
<Rule Id="CA1816" Action="None" />
<!-- Mark members static - test methods may not access member data but also can't be static. -->
<Rule Id="CA1822" Action="None" />
<!-- Seal internal types for performance - in tests we don't really care and it gets painful to enforce. -->
<Rule Id="CA1852" Action="None" />
<!-- Prefer static readonly fields over constant array arguments - constant array arguments happen a lot in unit tests for assertions and test setup. -->
<Rule Id="CA1861" Action="None" />
<!-- Cache a CompositeFormat object for use in String.Format - this makes unit tests harder to read, and performance isn't an issue. -->
<Rule Id="CA1863" Action="None" />
<!-- Call ConfigureAwait on tasks - you shouldn't do this in unit test libraries; XUnit has an opposite analyzer. -->
<Rule Id="CA2007" Action="None" />
<!-- Implement serialization constructors - false positive when building .NET Core. -->
<Rule Id="CA2229" Action="None" />
<!-- Use Uri instead of string parameters - strings are easier for testing. -->
<Rule Id="CA2234" Action="None" />
<!-- Mark ISerializable types with SerializableAttribute - false positive when building .NET Core. -->
<Rule Id="CA2237" Action="None" />
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- Prefix local calls with this. -->
<Rule Id="SA1101" Action="None" />
<!-- Use built-in type alias. -->
<Rule Id="SA1121" Action="None" />
<!-- Use String.Empty instead of "". -->
<Rule Id="SA1122" Action="None" />
<!-- Enforce order of class members by member type - sometimes putting test classes/data by the test helps. -->
<Rule Id="SA1201" Action="None" />
<!-- Enforce order of class members by member visibility - sometimes putting test classes/data by the test helps. -->
<Rule Id="SA1202" Action="None" />
<!-- Enforce order of static vs. non-static members - sometimes putting test classes/data by the test helps. -->
<Rule Id="SA1204" Action="None" />
<!-- Fields can't start with underscore. -->
<Rule Id="SA1309" Action="None" />
<!-- Elements should be documented. -->
<Rule Id="SA1600" Action="None" />
<!-- Partial items should be documented. -->
<Rule Id="SA1601" Action="None" />
<!-- Enumeration items should be documented. -->
<Rule Id="SA1602" Action="None" />
<!-- Parameter should be documented. -->
<Rule Id="SA1611" Action="None" />
<!-- Parameter documentation must be in the right order. -->
<Rule Id="SA1612" Action="None" />
<!-- Return value must be documented. -->
<Rule Id="SA1615" Action="None" />
<!-- Generic type parameters must be documented. -->
<Rule Id="SA1618" Action="None" />
<!-- Don't copy/paste documentation. -->
<Rule Id="SA1625" Action="None" />
<!-- Private member is unused - tests for reflection require members that may not get used. -->
<Rule Id="IDE0051" Action="None" />
<!-- Private member assigned value never read - tests for reflection require values that may not get used. -->
<Rule Id="IDE0052" Action="None" />
<!-- Remove unused parameter - tests for reflection require parameters that may not get used. -->
<Rule Id="IDE0060" Action="None" />
</Rules>
</RuleSet>
================================================
FILE: build/stylecop.json
================================================
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "Autofac Project",
"copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} License. See {licenseFile} in the project root for license information.",
"variables": {
"licenseFile": "LICENSE",
"licenseName": "MIT"
},
"xmlHeader": false
}
}
}
================================================
FILE: codecov.yml
================================================
codecov:
branch: develop
require_ci_to_pass: true
coverage:
status:
project:
default:
threshold: 1%
================================================
FILE: default.proj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="All" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current">
<PropertyGroup>
<!-- Increment the overall semantic version here. -->
<Version>11.0.0</Version>
<SolutionName>Autofac.Extensions.DependencyInjection</SolutionName>
<Configuration Condition="'$(Configuration)'==''">Release</Configuration>
<ArtifactDirectory>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),"artifacts"))</ArtifactDirectory>
<PackageDirectory>$([System.IO.Path]::Combine($(ArtifactDirectory),"packages"))</PackageDirectory>
<LogDirectory>$([System.IO.Path]::Combine($(ArtifactDirectory),"logs"))</LogDirectory>
<CoverageRunSettings>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'build/Coverage.runsettings'))</CoverageRunSettings>
<BuildDateTime>$([System.DateTimeOffset]::UtcNow.ToString('yyyyMMddTHHmmssZ'))</BuildDateTime>
</PropertyGroup>
<Choose>
<When Condition="'$(GITHUB_REF_NAME)'==''">
<PropertyGroup>
<Version>$(Version)-local</Version>
</PropertyGroup>
</When>
<When Condition="'$(GITHUB_REF_NAME)'=='master' Or $([System.Text.RegularExpressions.Regex]::IsMatch($(GITHUB_REF_NAME), `^v.+\..+\..+`))">
<PropertyGroup>
<Version>$(Version)</Version>
</PropertyGroup>
</When>
<When Condition="'$(GITHUB_REF_NAME)'=='develop'">
<PropertyGroup>
<Version>$(Version)-beta$(BuildDateTime)</Version>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<Version>$(Version)-alpha$(BuildDateTime)</Version>
</PropertyGroup>
</Otherwise>
</Choose>
<ItemGroup>
<CleanDirectory Include="$(ArtifactDirectory)" />
<SourceProject Include="$(MSBuildProjectDirectory)/src/**/*.csproj" />
<TestProject Include="$(MSBuildProjectDirectory)/test/**/*.csproj" />
<SolutionFile Include="$(SolutionName).sln" />
</ItemGroup>
<Target Name="All">
<Message Text="****************************************" Importance="high" />
<Message Text="$(SolutionName) v$(Version)" Importance="high" />
<Message Text="$(Configuration) Configuration" Importance="high" />
<Message Text="$(BuildDateTime)" Importance="high" />
<Message Text="****************************************" Importance="high" />
<CallTarget Targets="Clean;Compile;Test;Package" />
</Target>
<Target Name="Benchmarks" DependsOnTargets="Compile">
<Message Text="****************************************" Importance="high" />
<Message Text="Running Benchmarks" Importance="high" />
<Message Text="****************************************" Importance="high" />
<Exec Command="dotnet run --project "$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'bench/Autofac.Extensions.DependencyInjection.Bench'))" -c $(Configuration) --no-launch-profile --no-restore --no-build -- --filter Autofac.Extensions.DependencyInjection.Bench.*" />
</Target>
<Target Name="Clean">
<RemoveDir Directories="@(CleanDirectory)" />
<RemoveDir Directories="%(SourceProject.RootDir)%(SourceProject.Directory)bin;%(SourceProject.RootDir)%(SourceProject.Directory)obj" />
<RemoveDir Directories="%(TestProject.RootDir)%(TestProject.Directory)bin;%(TestProject.RootDir)%(TestProject.Directory)obj" />
</Target>
<Target Name="Compile">
<Exec Command="dotnet --info" />
<Exec Command="dotnet build "%(SolutionFile.FullPath)" -c $(Configuration) /p:Version=$(Version)" />
</Target>
<Target Name="Package">
<MakeDir Directories="$([System.IO.Path]::Combine($(PackageDirectory),%(PublishProject.Filename)))" />
<Exec Command="dotnet pack "%(SolutionFile.FullPath)" -c $(Configuration) --output "$(PackageDirectory)" /p:Version=$(Version)" />
</Target>
<Target Name="Test">
<MakeDir Directories="$(LogDirectory)" />
<Exec Command="dotnet test "%(SolutionFile.FullPath)" -c $(Configuration) --results-directory "$(LogDirectory)" --logger:trx /p:Version=$(Version) --collect:"XPlat Code Coverage" --settings "$(CoverageRunSettings)"" />
</Target>
</Project>
================================================
FILE: global.json
================================================
{
"sdk": {
"rollForward": "latestFeature",
"version": "10.0.100"
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/Autofac.Extensions.DependencyInjection.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Assembly metadata -->
<AssemblyName>Autofac.Extensions.DependencyInjection</AssemblyName>
<AssemblyTitle>Autofac.Extensions.DependencyInjection</AssemblyTitle>
<Description>Autofac implementation of the interfaces in Microsoft.Extensions.DependencyInjection.Abstractions, the .NET Framework dependency injection abstraction.</Description>
<Copyright>Copyright © 2015 Autofac Contributors</Copyright>
<Authors>Autofac Contributors</Authors>
<Company>Autofac</Company>
<Product>Autofac</Product>
<AssemblyOriginatorKeyFile>../../Autofac.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<NeutralLanguage>en-US</NeutralLanguage>
<!-- Frameworks and language features -->
<TargetFrameworks>net10.0;net8.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<CodeAnalysisRuleSet>../../build/Source.ruleset</CodeAnalysisRuleSet>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Packaging -->
<PackageId>Autofac.Extensions.DependencyInjection</PackageId>
<PackageTags>autofac;di;ioc;dependencyinjection;aspnet;aspnetcore</PackageTags>
<PackageReleaseNotes>Release notes are at https://github.com/autofac/Autofac.Extensions.DependencyInjection/releases</PackageReleaseNotes>
<PackageIcon>icon.png</PackageIcon>
<PackageProjectUrl>https://autofac.org</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/autofac/Autofac.Extensions.DependencyInjection</RepositoryUrl>
<ContinuousIntegrationBuild Condition="'$(CI)' != '' ">true</ContinuousIntegrationBuild>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedAllSources>true</EmbedAllSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<!-- OmniSharp/VS Code resource generation -->
<CoreCompileDependsOn>PrepareResources;$(CompileDependsOn)</CoreCompileDependsOn>
</PropertyGroup>
<ItemGroup>
<Using Include="System.Diagnostics.CodeAnalysis" />
</ItemGroup>
<!-- Disable nullability warnings in netstandard2.0 -->
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<NoWarn>$(NoWarn);8765;8600;8601;8602;8603;8604</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\build\icon.png" Pack="true" PackagePath="\" />
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\build\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="9.1.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.103" Condition="Exists('$(MSBuildThisFileDirectory)../../.git')">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.4" />
</ItemGroup>
<ItemDefinitionGroup>
<EmbeddedResource>
<Generator>MSBuild:Compile</Generator>
<StronglyTypedLanguage>CSharp</StronglyTypedLanguage>
<StronglyTypedFileName>$(IntermediateOutputPath)%(Filename).Designer.cs</StronglyTypedFileName>
<StronglyTypedClassName>%(Filename)</StronglyTypedClassName>
</EmbeddedResource>
</ItemDefinitionGroup>
<ItemGroup>
<EmbeddedResource Update="KeyTypeConversionExceptionResources.resx">
<StronglyTypedNamespace>Autofac.Extensions.DependencyInjection</StronglyTypedNamespace>
</EmbeddedResource>
<EmbeddedResource Update="KeyTypeManipulationResources.resx">
<StronglyTypedNamespace>Autofac.Extensions.DependencyInjection</StronglyTypedNamespace>
</EmbeddedResource>
<EmbeddedResource Update="ServiceProviderExtensionsResources.resx">
<StronglyTypedNamespace>Autofac.Extensions.DependencyInjection</StronglyTypedNamespace>
</EmbeddedResource>
</ItemGroup>
</Project>
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeConfigurationAdapter.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Configuration adapter for <see cref="AutofacChildLifetimeScopeServiceProviderFactory" />.
/// </summary>
public class AutofacChildLifetimeScopeConfigurationAdapter
{
private readonly List<Action<ContainerBuilder>> _configurationActions = new();
/// <summary>
/// Gets the list of configuration actions to be executed on the <see cref="ContainerBuilder"/> for the child <see cref="ILifetimeScope"/>.
/// </summary>
public IReadOnlyList<Action<ContainerBuilder>> ConfigurationActions => _configurationActions;
/// <summary>
/// Adds a configuration action that will be executed when the child <see cref="ILifetimeScope"/> is created.
/// </summary>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container.</param>
/// <exception cref="ArgumentNullException">Throws when the passed configuration-action is null.</exception>
public void Add(Action<ContainerBuilder> configurationAction)
{
if (configurationAction == null)
{
throw new ArgumentNullException(nameof(configurationAction));
}
_configurationActions.Add(configurationAction);
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeServiceProviderFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// A factory for creating a <see cref="IServiceProvider"/> that wraps a child <see cref="ILifetimeScope"/> created from an existing parent <see cref="ILifetimeScope"/>.
/// </summary>
public class AutofacChildLifetimeScopeServiceProviderFactory : IServiceProviderFactory<AutofacChildLifetimeScopeConfigurationAdapter>
{
private static readonly Action<ContainerBuilder> FallbackConfigurationAction = builder => { };
private readonly Action<ContainerBuilder> _containerConfigurationAction;
private readonly ILifetimeScope _rootLifetimeScope;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacChildLifetimeScopeServiceProviderFactory"/> class.
/// </summary>
/// <param name="rootLifetimeScopeAccessor">A function to retrieve the root <see cref="ILifetimeScope"/> instance.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container.</param>
public AutofacChildLifetimeScopeServiceProviderFactory(Func<ILifetimeScope> rootLifetimeScopeAccessor, Action<ContainerBuilder>? configurationAction = null)
{
if (rootLifetimeScopeAccessor == null)
{
throw new ArgumentNullException(nameof(rootLifetimeScopeAccessor));
}
_rootLifetimeScope = rootLifetimeScopeAccessor();
_containerConfigurationAction = configurationAction ?? FallbackConfigurationAction;
}
/// <summary>
/// Initializes a new instance of the <see cref="AutofacChildLifetimeScopeServiceProviderFactory"/> class.
/// </summary>
/// <param name="rootLifetimeScope">The root <see cref="ILifetimeScope"/> instance.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container.</param>
public AutofacChildLifetimeScopeServiceProviderFactory(ILifetimeScope rootLifetimeScope, Action<ContainerBuilder>? configurationAction = null)
{
_rootLifetimeScope = rootLifetimeScope ?? throw new ArgumentNullException(nameof(rootLifetimeScope));
_containerConfigurationAction = configurationAction ?? FallbackConfigurationAction;
}
/// <summary>
/// Creates a container builder from an <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">The collection of services.</param>
/// <returns>A container builder that can be used to create an <see cref="IServiceProvider" />.</returns>
public AutofacChildLifetimeScopeConfigurationAdapter CreateBuilder(IServiceCollection services)
{
var actions = new AutofacChildLifetimeScopeConfigurationAdapter();
actions.Add(builder => builder.Populate(services));
actions.Add(builder => _containerConfigurationAction(builder));
return actions;
}
/// <summary>
/// Creates an <see cref="IServiceProvider" /> from the container builder.
/// </summary>
/// <param name="containerBuilder">The adapter holding configuration applied to <see cref="ContainerBuilder"/> creating the <see cref="IServiceProvider"/>.</param>
/// <returns>An <see cref="IServiceProvider" />.</returns>
public IServiceProvider CreateServiceProvider(AutofacChildLifetimeScopeConfigurationAdapter containerBuilder)
{
if (containerBuilder == null)
{
throw new ArgumentNullException(nameof(containerBuilder));
}
var scope = _rootLifetimeScope.BeginLifetimeScope(scopeBuilder =>
{
foreach (var action in containerBuilder.ConfigurationActions)
{
action(scopeBuilder);
}
});
return new AutofacServiceProvider(scope);
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacRegistration.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Core.Activators;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Activators.Reflection;
using Autofac.Core.Resolving.Pipeline;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extension methods for registering ASP.NET Core dependencies with Autofac.
/// </summary>
public static class AutofacRegistration
{
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors
/// and makes <see cref="IServiceProvider"/> and <see cref="IServiceScopeFactory"/>
/// available in the container.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="descriptors">
/// The set of service descriptors to register in the container.
/// </param>
public static void Populate(
this ContainerBuilder builder,
IEnumerable<ServiceDescriptor> descriptors)
{
Populate(builder, descriptors, null);
}
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors
/// and makes <see cref="IServiceProvider"/> and <see cref="IServiceScopeFactory"/>
/// available in the container. Using this overload is incompatible with the ASP.NET Core
/// support for <see cref="IServiceProviderFactory{TContainerBuilder}"/>.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="descriptors">
/// The set of service descriptors to register in the container.
/// </param>
/// <param name="lifetimeScopeTagForSingletons">
/// If provided and not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingletons"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// </param>
/// <remarks>
/// <para>
/// Specifying a <paramref name="lifetimeScopeTagForSingletons"/> addresses a specific case where you have
/// an application that uses Autofac but where you need to isolate a set of services in a child scope. For example,
/// if you have a large application that self-hosts ASP.NET Core items, you may want to isolate the ASP.NET
/// Core registrations in a child lifetime scope so they don't show up for the rest of the application.
/// This overload allows that. Note it is the developer's responsibility to execute this and create an
/// <see cref="AutofacServiceProvider"/> using the child lifetime scope.
/// </para>
/// </remarks>
public static void Populate(
this ContainerBuilder builder,
IEnumerable<ServiceDescriptor> descriptors,
object? lifetimeScopeTagForSingletons)
{
if (descriptors is null)
{
throw new ArgumentNullException(nameof(descriptors));
}
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.RegisterType<AutofacServiceProvider>()
.As<IServiceProvider>()
.As<IServiceProviderIsService>()
.As<IKeyedServiceProvider>()
.As<IServiceProviderIsKeyedService>()
.ExternallyOwned();
// Issue #83: IServiceScopeFactory must be a singleton and scopes must be flat, not hierarchical.
builder
.RegisterType<AutofacServiceScopeFactory>()
.As<IServiceScopeFactory>()
.SingleInstance();
// Shims for keyed service compatibility.
builder.ComponentRegistryBuilder.Registered += AddFromKeyedServiceParameterMiddleware;
Register(builder, descriptors, lifetimeScopeTagForSingletons);
}
/// <summary>
/// Inspect each component registration, and determine whether or not we can avoid adding the
/// <see cref="FromKeyedServicesAttribute"/> parameter to the resolve pipeline.
/// </summary>
private static void AddFromKeyedServiceParameterMiddleware(object? sender, ComponentRegisteredEventArgs e)
{
var needFromKeyedServiceParameter = false;
// We can optimize quite significantly in the case where we are using
// the reflection activator. In that state we can inspect the
// constructors ahead of time and determine whether the parameter will
// even need to be added.
if (e.ComponentRegistration.Activator is ReflectionActivator reflectionActivator)
{
needFromKeyedServiceParameter = FromKeyedServicesUsageCache.RequiresFromKeyedServicesMiddleware(reflectionActivator);
}
else if (e.ComponentRegistration.Activator is DelegateActivator)
{
// For delegate activation there are very few paths that would let
// the FromKeyedServicesAttribute actually work, and none that MEDI
// supports directly.
//
// We're explicitly choosing here not to support [FromKeyedServices]
// on the Autofac-specific generic delegate resolve methods, to
// improve performance for the 99% case of other delegates that only
// receive an IComponentContext or an IServiceProvider.
needFromKeyedServiceParameter = false;
}
else if (e.ComponentRegistration.Activator is InstanceActivator)
{
// Instance activators don't use parameters.
needFromKeyedServiceParameter = false;
}
else
{
// Unknown activator, assume we need the parameter.
needFromKeyedServiceParameter = true;
}
e.ComponentRegistration.PipelineBuilding += (sender, pipeline) =>
{
if (needFromKeyedServiceParameter)
{
pipeline.Use(KeyedServiceMiddleware.InstanceWithFromKeyedServicesParameter, MiddlewareInsertionMode.StartOfPhase);
}
else
{
pipeline.Use(KeyedServiceMiddleware.InstanceWithoutFromKeyedServicesParameter, MiddlewareInsertionMode.StartOfPhase);
}
};
}
/// <summary>
/// Configures the exposed service type on a service registration.
/// </summary>
/// <typeparam name="TActivatorData">The activator data type.</typeparam>
/// <typeparam name="TRegistrationStyle">The object registration style.</typeparam>
/// <param name="registrationBuilder">The registration being built.</param>
/// <param name="descriptor">The service descriptor with service type and key information.</param>
/// <returns>
/// The <paramref name="registrationBuilder" />, configured with the proper service type,
/// and available for additional configuration.
/// </returns>
private static IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> ConfigureServiceType<TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> registrationBuilder,
ServiceDescriptor descriptor)
{
// If it's keyed, the service key won't be null. A null key results in it _not_ being a keyed service.
if (descriptor.IsKeyedService)
{
var key = descriptor.ServiceKey!;
if (key.Equals(Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey))
{
key = Autofac.Core.KeyedService.AnyKey;
}
registrationBuilder.Keyed(key, descriptor.ServiceType);
}
else
{
registrationBuilder.As(descriptor.ServiceType);
}
return registrationBuilder;
}
/// <summary>
/// Configures the lifecycle on a service registration.
/// </summary>
/// <typeparam name="TActivatorData">The activator data type.</typeparam>
/// <typeparam name="TRegistrationStyle">The object registration style.</typeparam>
/// <param name="registrationBuilder">The registration being built.</param>
/// <param name="lifecycleKind">The lifecycle specified on the service registration.</param>
/// <param name="lifetimeScopeTagForSingleton">
/// If not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingleton"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// </param>
/// <returns>
/// The <paramref name="registrationBuilder" />, configured with the proper lifetime scope,
/// and available for additional configuration.
/// </returns>
private static IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> ConfigureLifecycle<TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> registrationBuilder,
ServiceLifetime lifecycleKind,
object? lifetimeScopeTagForSingleton)
{
switch (lifecycleKind)
{
case ServiceLifetime.Singleton:
if (lifetimeScopeTagForSingleton == null)
{
registrationBuilder.SingleInstance();
}
else
{
registrationBuilder.InstancePerMatchingLifetimeScope(lifetimeScopeTagForSingleton);
}
break;
case ServiceLifetime.Scoped:
registrationBuilder.InstancePerLifetimeScope();
break;
case ServiceLifetime.Transient:
registrationBuilder.InstancePerDependency();
break;
}
return registrationBuilder;
}
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="descriptors">
/// The set of service descriptors to register in the container.
/// </param>
/// <param name="lifetimeScopeTagForSingletons">
/// If not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingletons"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// </param>
[SuppressMessage("CA2000", "CA2000", Justification = "Registrations created here are disposed when the built container is disposed.")]
private static void Register(
ContainerBuilder builder,
IEnumerable<ServiceDescriptor> descriptors,
object? lifetimeScopeTagForSingletons)
{
foreach (var descriptor in descriptors)
{
var implementationType = descriptor.NormalizedImplementationType();
if (implementationType != null)
{
// Test if an open generic type is being registered
var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo();
if (serviceTypeInfo.IsGenericTypeDefinition)
{
builder
.RegisterGeneric(implementationType)
.ConfigureServiceType(descriptor)
.ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons);
}
else
{
builder
.RegisterType(implementationType)
.ConfigureServiceType(descriptor)
.ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons);
}
continue;
}
if (descriptor.IsKeyedService && descriptor.KeyedImplementationFactory != null)
{
var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) =>
{
// At this point the context is always a ResolveRequestContext, which will expose the actual service type.
var requestContext = (ResolveRequestContext)context;
var serviceProvider = context.Resolve<IServiceProvider>();
var keyedService = (Autofac.Core.KeyedService)requestContext.Service;
var key = requestContext.Parameters.KeyedServiceKey<object>();
return descriptor.KeyedImplementationFactory(serviceProvider, key);
})
.ConfigureServiceType(descriptor)
.ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons)
.CreateRegistration();
builder.RegisterComponent(registration);
continue;
}
else if (!descriptor.IsKeyedService && descriptor.ImplementationFactory != null)
{
var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) =>
{
var serviceProvider = context.Resolve<IServiceProvider>();
return descriptor.ImplementationFactory(serviceProvider);
})
.ConfigureServiceType(descriptor)
.ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons)
.CreateRegistration();
builder.RegisterComponent(registration);
continue;
}
// It's not a type or factory, so it must be an instance.
builder
.RegisterInstance(descriptor.NormalizedImplementationInstance()!)
.ConfigureServiceType(descriptor)
.ConfigureLifecycle(descriptor.Lifetime, null)
.ExternallyOwned();
}
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceProvider.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Autofac.Core;
using Microsoft.Extensions.DependencyInjection;
using KeyedService = Autofac.Core.KeyedService;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceProvider"/>.
/// </summary>
/// <seealso cref="IServiceProvider" />
/// <seealso cref="ISupportRequiredService" />
public class AutofacServiceProvider : IServiceProvider, ISupportRequiredService, IKeyedServiceProvider, IServiceProviderIsService, IServiceProviderIsKeyedService, IDisposable, IAsyncDisposable
{
private readonly ILifetimeScope _lifetimeScope;
private bool _disposed;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceProvider"/> class.
/// </summary>
/// <param name="lifetimeScope">
/// The lifetime scope from which services will be resolved.
/// </param>
public AutofacServiceProvider(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope ?? throw new ArgumentNullException(nameof(lifetimeScope));
}
/// <summary>
/// Gets the underlying instance of <see cref="ILifetimeScope" />.
/// </summary>
public ILifetimeScope LifetimeScope => _lifetimeScope;
/// <summary>
/// Gets the service object of the specified type.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <param name="serviceKey">
/// An object that specifies the key of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />; or <see langword="null" />
/// if there is no service object of type <paramref name="serviceType" />.
/// </returns>
public object? GetKeyedService(Type serviceType, object? serviceKey)
{
if (serviceType is null)
{
throw new ArgumentNullException(nameof(serviceType));
}
var normalizedKey = NormalizeServiceKey(serviceType, serviceKey);
if (normalizedKey is null)
{
// A null key equates to "not keyed."
return _lifetimeScope.ResolveOptional(serviceType);
}
else
{
try
{
return _lifetimeScope.ResolveOptionalService(new KeyedService(normalizedKey, serviceType));
}
catch (DependencyResolutionException ex)
{
// All exceptions resolving keyed services as of .NET 10 are
// expected to be InvalidOperationException.
throw new InvalidOperationException(ex.Message, ex);
}
}
}
/// <summary>
/// Gets service of type <paramref name="serviceType" /> from the
/// <see cref="AutofacServiceProvider" /> and requires it be present.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <param name="serviceKey">
/// An object that specifies the key of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />.
/// </returns>
/// <exception cref="Autofac.Core.Registration.ComponentNotRegisteredException">
/// Thrown if the <paramref name="serviceType" /> isn't registered with the container.
/// </exception>
/// <exception cref="Autofac.Core.DependencyResolutionException">
/// Thrown if the object can't be resolved from the container.
/// </exception>
public object GetRequiredKeyedService(Type serviceType, object? serviceKey)
{
if (serviceType is null)
{
throw new ArgumentNullException(nameof(serviceType));
}
var normalizedKey = NormalizeServiceKey(serviceType, serviceKey);
if (normalizedKey is null)
{
// A null key equates to "not keyed."
return _lifetimeScope.Resolve(serviceType);
}
else
{
try
{
return _lifetimeScope.ResolveKeyed(normalizedKey, serviceType);
}
catch (DependencyResolutionException ex)
{
// All exceptions resolving keyed services as of .NET 10 are
// expected to be InvalidOperationException.
throw new InvalidOperationException(ex.Message, ex);
}
}
}
/// <summary>
/// Gets service of type <paramref name="serviceType" /> from the
/// <see cref="AutofacServiceProvider" /> and requires it be present.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />.
/// </returns>
/// <exception cref="Autofac.Core.Registration.ComponentNotRegisteredException">
/// Thrown if the <paramref name="serviceType" /> isn't registered with the container.
/// </exception>
/// <exception cref="Autofac.Core.DependencyResolutionException">
/// Thrown if the object can't be resolved from the container.
/// </exception>
public object GetRequiredService(Type serviceType)
{
try
{
return _lifetimeScope.Resolve(serviceType);
}
catch (DependencyResolutionException ex)
{
throw new InvalidOperationException(ex.Message, ex);
}
}
/// <inheritdoc />
public bool IsKeyedService(Type serviceType, object? serviceKey)
{
// Null service key means non-keyed.
if (serviceKey == null)
{
return IsService(serviceType);
}
return _lifetimeScope.ComponentRegistry.IsRegistered(new KeyedService(serviceKey, serviceType));
}
/// <inheritdoc />
public bool IsService(Type serviceType) => _lifetimeScope.ComponentRegistry.IsRegistered(new TypedService(serviceType));
/// <summary>
/// Gets the service object of the specified type.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />; or <see langword="null" />
/// if there is no service object of type <paramref name="serviceType" />.
/// </returns>
public object? GetService(Type serviceType)
{
try
{
return _lifetimeScope.ResolveOptional(serviceType);
}
catch (DependencyResolutionException ex)
{
throw new InvalidOperationException(ex.Message, ex);
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Performs a dispose operation asynchronously.
/// </summary>
/// <returns>A task to await disposal.</returns>
public async ValueTask DisposeAsync()
{
if (!_disposed)
{
_disposed = true;
await _lifetimeScope.DisposeAsync().ConfigureAwait(false);
GC.SuppressFinalize(this);
}
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
if (disposing)
{
_lifetimeScope.Dispose();
}
}
}
private static object? NormalizeServiceKey(Type serviceType, object? serviceKey)
{
if (serviceKey is null)
{
return null;
}
if (ReferenceEquals(serviceKey, Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey))
{
if (!serviceType.IsCollection())
{
throw new InvalidOperationException("KeyedService.AnyKey cannot be used to resolve a single service.");
}
return KeyedService.AnyKey;
}
return serviceKey;
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceProviderFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Autofac.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// A factory for creating a <see cref="ContainerBuilder"/> and an <see cref="IServiceProvider" />.
/// </summary>
public class AutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
{
private static readonly Action<ContainerBuilder> FallbackConfigurationAction = builder => { };
private readonly Action<ContainerBuilder> _configurationAction;
private readonly ContainerBuildOptions _containerBuildOptions = ContainerBuildOptions.None;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceProviderFactory"/> class.
/// </summary>
/// <param name="containerBuildOptions">The container options to use when building the container.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container.</param>
public AutofacServiceProviderFactory(
ContainerBuildOptions containerBuildOptions,
Action<ContainerBuilder>? configurationAction = null)
: this(configurationAction) =>
_containerBuildOptions = containerBuildOptions;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceProviderFactory"/> class.
/// </summary>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container..</param>
public AutofacServiceProviderFactory(Action<ContainerBuilder>? configurationAction = null) =>
_configurationAction = configurationAction ?? FallbackConfigurationAction;
/// <summary>
/// Creates a container builder from an <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">The collection of services.</param>
/// <returns>A container builder that can be used to create an <see cref="IServiceProvider" />.</returns>
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
var builder = new ContainerBuilder();
builder.Populate(services);
_configurationAction(builder);
return builder;
}
/// <summary>
/// Creates an <see cref="IServiceProvider" /> from the container builder.
/// </summary>
/// <param name="containerBuilder">The container builder.</param>
/// <returns>An <see cref="IServiceProvider" />.</returns>
public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
{
if (containerBuilder == null)
{
throw new ArgumentNullException(nameof(containerBuilder));
}
var container = containerBuilder.Build(_containerBuildOptions);
return new AutofacServiceProvider(container);
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceScope.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceScope"/>.
/// Inherits from <see cref="AutofacServiceProvider"/> to avoid a separate
/// allocation per scope — every scope is itself a service provider.
/// </summary>
/// <seealso cref="IServiceScope" />
internal class AutofacServiceScope : AutofacServiceProvider, IServiceScope
{
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceScope"/> class.
/// </summary>
/// <param name="lifetimeScope">
/// The lifetime scope from which services should be resolved for this service scope.
/// </param>
public AutofacServiceScope(ILifetimeScope lifetimeScope)
: base(lifetimeScope)
{
}
/// <summary>
/// Gets an <see cref="IServiceProvider" /> corresponding to this service scope.
/// </summary>
/// <value>
/// An <see cref="IServiceProvider" /> that can be used to resolve dependencies from the scope.
/// </value>
public IServiceProvider ServiceProvider => this;
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceScopeFactory.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceScopeFactory"/>.
/// </summary>
/// <seealso cref="IServiceScopeFactory" />
internal class AutofacServiceScopeFactory : IServiceScopeFactory
{
private readonly ILifetimeScope _lifetimeScope;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceScopeFactory"/> class.
/// </summary>
/// <param name="lifetimeScope">The lifetime scope.</param>
public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
}
/// <summary>
/// Creates an <see cref="IServiceScope" /> which contains an
/// <see cref="System.IServiceProvider" /> used to resolve dependencies within
/// the scope.
/// </summary>
/// <returns>
/// An <see cref="IServiceScope" /> controlling the lifetime of the scope. Once
/// this is disposed, any scoped services that have been resolved
/// from the <see cref="IServiceScope.ServiceProvider" />
/// will also be disposed.
/// </returns>
public IServiceScope CreateScope()
{
return new AutofacServiceScope(_lifetimeScope.BeginLifetimeScope());
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/FromKeyedServicesAttributeExtensions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Globalization;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extensions for working with <see cref="FromKeyedServicesAttribute"/>.
/// </summary>
internal static class FromKeyedServicesAttributeExtensions
{
/// <summary>
/// Resolves a constructor parameter based on keyed service requirements.
/// </summary>
/// <param name="attribute">The attribute marking the keyed service dependency in a constructor.</param>
/// <param name="parameter">The specific parameter being resolved that is marked with this attribute.</param>
/// <param name="context">The component context under which the parameter is being resolved.</param>
/// <param name="parentServiceKey">The key used for the containing resolve request.</param>
/// <returns>
/// The instance of the object that should be used for the parameter value.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="parameter" /> or <paramref name="context" /> is <see langword="null" />.
/// </exception>
public static object? ResolveParameter(this FromKeyedServicesAttribute attribute, ParameterInfo parameter, IComponentContext context, object? parentServiceKey)
{
if (attribute is null)
{
throw new ArgumentNullException(nameof(attribute));
}
if (parameter is null)
{
throw new ArgumentNullException(nameof(parameter));
}
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
return attribute.LookupMode switch
{
ServiceKeyLookupMode.ExplicitKey => ResolveKeyed(parameter, context, NormalizeKey(attribute.Key)),
ServiceKeyLookupMode.InheritKey => ResolveKeyed(parameter, context, NormalizeKey(parentServiceKey)),
_ => ResolveUnkeyed(parameter, context),
};
}
private static object? ResolveUnkeyed(ParameterInfo parameter, IComponentContext context)
{
if (context.TryResolve(parameter.ParameterType, out var instance))
{
return instance;
}
return GetDefaultValueOrThrow(parameter, key: null);
}
private static object? ResolveKeyed(ParameterInfo parameter, IComponentContext context, object? key)
{
if (key is null)
{
return GetDefaultValueOrThrow(parameter, key);
}
if (context.TryResolveKeyed(key, parameter.ParameterType, out var instance))
{
return instance;
}
return GetDefaultValueOrThrow(parameter, key);
}
private static object? GetDefaultValueOrThrow(ParameterInfo parameter, object? key)
{
if (parameter.HasDefaultValue)
{
return parameter.DefaultValue;
}
if (key is null)
{
throw new InvalidOperationException(
string.Format(
CultureInfo.CurrentCulture,
"Unable to resolve service for type '{0}'.",
parameter.ParameterType));
}
throw new InvalidOperationException(
string.Format(
CultureInfo.CurrentCulture,
"Unable to resolve service for type '{0}' using key '{1}'.",
parameter.ParameterType,
key));
}
private static object? NormalizeKey(object? key)
{
if (key is null)
{
return null;
}
return ReferenceEquals(key, Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey)
? Autofac.Core.KeyedService.AnyKey
: key;
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/FromKeyedServicesUsageCache.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Concurrent;
using Autofac.Core;
using Autofac.Core.Activators.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Caches lookups for <see cref="FromKeyedServicesAttribute"/> usage on constructor parameters.
/// </summary>
[ExcludeFromCodeCoverage]
internal static class FromKeyedServicesUsageCache
{
private static readonly FromKeyedServicesUsageReflectionCache ReflectionCache = new();
static FromKeyedServicesUsageCache()
{
ReflectionCacheSet.Shared.RegisterExternalCache(ReflectionCache);
}
/// <summary>
/// Determines whether the resolve pipeline needs <see cref="KeyedServiceMiddleware"/> for the given activator.
/// </summary>
/// <param name="activator">The reflection activator being inspected.</param>
/// <returns><see langword="true"/> when a constructor parameter uses <see cref="FromKeyedServicesAttribute"/>; otherwise <see langword="false"/>.</returns>
public static bool RequiresFromKeyedServicesMiddleware(ReflectionActivator activator)
{
if (activator is null)
{
throw new ArgumentNullException(nameof(activator));
}
var constructorFinder = activator.ConstructorFinder;
var cacheKey = new CacheKey(activator.LimitType, constructorFinder.GetType());
#if NETSTANDARD2_0
if (ReflectionCache.TryGet(cacheKey, out var cachedResult))
{
return cachedResult;
}
var computed = ScanConstructors(constructorFinder, activator.LimitType);
return ReflectionCache.GetOrAdd(cacheKey, computed);
#else
return ReflectionCache.GetOrAdd(
cacheKey,
static (_, state) => ScanConstructors(state.ConstructorFinder, state.LimitType),
(ConstructorFinder: constructorFinder, activator.LimitType));
#endif
}
private static bool ScanConstructors(IConstructorFinder constructorFinder, Type limitType)
{
var constructors = constructorFinder.FindConstructors(limitType);
foreach (var constructor in constructors)
{
foreach (var parameter in constructor.GetParameters())
{
if (parameter.IsDefined(typeof(FromKeyedServicesAttribute), inherit: true))
{
return true;
}
}
}
return false;
}
private readonly struct CacheKey : IEquatable<CacheKey>
{
public CacheKey(Type implementationType, Type constructorFinderType)
{
ImplementationType = implementationType ?? throw new ArgumentNullException(nameof(implementationType));
ConstructorFinderType = constructorFinderType ?? throw new ArgumentNullException(nameof(constructorFinderType));
}
private Type ImplementationType { get; }
private Type ConstructorFinderType { get; }
public bool Matches(ReflectionCacheClearPredicate clearPredicate)
{
var implementationAssemblies = new[] { ImplementationType.Assembly };
if (clearPredicate(ImplementationType, implementationAssemblies))
{
return true;
}
var constructorFinderAssemblies = new[] { ConstructorFinderType.Assembly };
return clearPredicate(ConstructorFinderType, constructorFinderAssemblies);
}
public bool Equals(CacheKey other)
{
return ImplementationType == other.ImplementationType &&
ConstructorFinderType == other.ConstructorFinderType;
}
[ExcludeFromCodeCoverage]
public override bool Equals(object? obj)
{
return obj is CacheKey other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
return (ImplementationType.GetHashCode() * 397) ^ ConstructorFinderType.GetHashCode();
}
}
}
private sealed class FromKeyedServicesUsageReflectionCache : IReflectionCache
{
private readonly ConcurrentDictionary<CacheKey, bool> _cache = new();
public ReflectionCacheUsage Usage => ReflectionCacheUsage.Registration;
public bool TryGet(CacheKey key, out bool result)
{
return _cache.TryGetValue(key, out result);
}
public bool GetOrAdd(CacheKey key, bool value)
{
return _cache.GetOrAdd(key, value);
}
public bool GetOrAdd(CacheKey key, Func<CacheKey, (IConstructorFinder ConstructorFinder, Type LimitType), bool> valueFactory, (IConstructorFinder ConstructorFinder, Type LimitType) state)
{
#if NETSTANDARD2_0
return _cache.GetOrAdd(key, cacheKey => valueFactory(cacheKey, state));
#else
return _cache.GetOrAdd(key, valueFactory, state);
#endif
}
public void Clear()
{
_cache.Clear();
}
public void Clear(ReflectionCacheClearPredicate clearPredicate)
{
if (clearPredicate is null)
{
throw new ArgumentNullException(nameof(clearPredicate));
}
foreach (var key in _cache.Keys)
{
if (key.Matches(clearPredicate))
{
_cache.TryRemove(key, out _);
}
}
}
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeConversionException.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Globalization;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Exception indicating that type conversion failed when trying to inject a key
/// using the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// </summary>
[ExcludeFromCodeCoverage]
public class KeyTypeConversionException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="KeyTypeConversionException" /> class.
/// </summary>
/// <param name="resolutionKeyType">
/// The type of the key specified during service resolution. This is what
/// would be injected into the constructor and needs to be converted.
/// </param>
/// <param name="attributeKeyType">
/// The type of parameter marked with the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// This is what the key was trying to be converted to.
/// </param>
public KeyTypeConversionException(Type resolutionKeyType, Type attributeKeyType)
: this(resolutionKeyType, attributeKeyType, string.Format(CultureInfo.CurrentCulture, KeyTypeConversionExceptionResources.Message, resolutionKeyType, attributeKeyType))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyTypeConversionException" /> class.
/// </summary>
/// <param name="resolutionKeyType">
/// The type of the key specified during service resolution. This is what
/// would be injected into the constructor and needs to be converted.
/// </param>
/// <param name="attributeKeyType">
/// The type of parameter marked with the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// This is what the key was trying to be converted to.
/// </param>
/// <param name="message">
/// A specific message for the exception to override the default.
/// </param>
public KeyTypeConversionException(Type resolutionKeyType, Type attributeKeyType, string message)
: base(message)
{
ResolutionKeyType = resolutionKeyType;
AttributeKeyType = attributeKeyType;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyTypeConversionException"/> class.
/// </summary>
/// <param name="resolutionKeyType">
/// The type of the key specified during service resolution. This is what
/// would be injected into the constructor and needs to be converted.
/// </param>
/// <param name="attributeKeyType">
/// The type of parameter marked with the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// This is what the key was trying to be converted to.
/// </param>
/// <param name="innerException">The inner exception.</param>
public KeyTypeConversionException(Type resolutionKeyType, Type attributeKeyType, Exception? innerException)
: this(resolutionKeyType, attributeKeyType, string.Format(CultureInfo.CurrentCulture, KeyTypeConversionExceptionResources.Message, resolutionKeyType, attributeKeyType), innerException)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyTypeConversionException"/> class.
/// </summary>
/// <param name="resolutionKeyType">
/// The type of the key specified during service resolution. This is what
/// would be injected into the constructor and needs to be converted.
/// </param>
/// <param name="attributeKeyType">
/// The type of parameter marked with the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// This is what the key was trying to be converted to.
/// </param>
/// <param name="message">
/// A specific message for the exception to override the default.
/// </param>
/// <param name="innerException">The inner exception.</param>
public KeyTypeConversionException(Type resolutionKeyType, Type attributeKeyType, string message, Exception? innerException)
: base(message, innerException)
{
ResolutionKeyType = resolutionKeyType;
AttributeKeyType = attributeKeyType;
}
/// <summary>
/// Gets the type of the parameter marked with the <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// </summary>
/// <value>
/// The <see cref="Type"/> of parameter marked with the
/// <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>,
/// which is the destination where the key should be injected. This should
/// be compatible with the key provided during resolution.
/// </value>
public Type AttributeKeyType { get; }
/// <summary>
/// Gets the type of the key specified during service resolution.
/// </summary>
/// <value>
/// The <see cref="Type"/> of key passed to the keyed service resolve
/// operation. This is what would be injected as a constructor parameter to
/// the service being resolved.
/// </value>
public Type ResolutionKeyType { get; }
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeConversionExceptionResources.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Message" xml:space="preserve">
<value>Unable to convert key of type '{0}' to type '{1}' for parameter injection.</value>
</data>
</root>
================================================
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeManipulation.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using Autofac.Core;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Utilities for converting keyed service key values into compatible types for
/// injection using the <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// This logic originally came from Autofac.Configuration but there isn't a good
/// "shared dependency" location for things like this other than core Autofac.
/// </summary>
internal class KeyTypeManipulation
{
private static readonly KeyTypeManipulationReflectionCache ReflectionCache = new();
static KeyTypeManipulation()
{
ReflectionCacheSet.Shared.RegisterExternalCache(ReflectionCache);
}
/// <summary>
/// Converts an object to a type compatible with a given parameter.
/// </summary>
/// <param name="value">The object value to convert.</param>
/// <param name="destinationType">The destination <see cref="Type"/> to which <paramref name="value"/> should be converted.</param>
/// <param name="memberInfo">The parameter for which the <paramref name="value"/> is being converted.</param>
/// <returns>
/// An <see cref="object"/> of type <paramref name="destinationType"/>, converted using
/// type converters specified on <paramref name="memberInfo"/> if available. If <paramref name="value"/>
/// is <see langword="null"/> then the output will be <see langword="null"/> for reference
/// types and the default value for value types.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown if conversion of the value fails.
/// </exception>
public static object? ChangeToCompatibleType(object? value, Type destinationType, ParameterInfo memberInfo)
{
TypeConverterAttribute? attrib = null;
if (memberInfo != null)
{
attrib = ReflectionCache.GetOrAddParameterConverterAttribute(memberInfo);
}
return ChangeToCompatibleType(value, destinationType, attrib);
}
/// <summary>
/// Converts an object to a type compatible with a given parameter.
/// </summary>
/// <param name="value">The object value to convert.</param>
/// <param name="destinationType">The destination <see cref="Type"/> to which <paramref name="value"/> should be converted.</param>
/// <param name="memberInfo">The parameter for which the <paramref name="value"/> is being converted.</param>
/// <returns>
/// An <see cref="object"/> of type <paramref name="destinationType"/>, converted using
/// type converters specified on <paramref name="memberInfo"/> if available. If <paramref name="value"/>
/// is <see langword="null"/> then the output will be <see langword="null"/> for reference
/// types and the default value for value types.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown if conversion of the value fails.
/// </exception>
public static object? ChangeToCompatibleType(object? value, Type destinationType, MemberInfo memberInfo)
{
TypeConverterAttribute? attrib = null;
if (memberInfo != null)
{
attrib = ReflectionCache.GetOrAddMemberConverterAttribute(memberInfo);
}
return ChangeToCompatibleType(value, destinationType, attrib);
}
/// <summary>
/// Converts an object to a type compatible with a given parameter.
/// </summary>
/// <param name="value">The object value to convert.</param>
/// <param name="destinationType">The destination <see cref="Type"/> to which <paramref name="value"/> should be converted.</param>
/// <param name="converterAttribute">A <see cref="TypeConverterAttribute"/>, if available, specifying the type of converter to use.<paramref name="value"/> is being converted.</param>
/// <returns>
/// An <see cref="object"/> of type <paramref name="destinationType"/>, converted using
/// any type converters specified in <paramref name="converterAttribute"/> if available. If <paramref name="value"/>
/// is <see langword="null"/> then the output will be <see langword="null"/> for reference
/// types and the default value for value types.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown if conversion of the value fails.
/// </exception>
public static object? ChangeToCompatibleType(object? value, Type destinationType, TypeConverterAttribute? converterAttribute = null)
{
if (destinationType == null)
{
throw new ArgumentNullException(nameof(destinationType));
}
if (value == null)
{
return destinationType.GetTypeInfo().IsValueType
? ReflectionCache.GetOrAddDefaultValue(destinationType)
: null;
}
// Try implicit conversion.
if (destinationType.IsInstanceOfType(value))
{
return value;
}
TypeConverter converter;
// Try to get custom type converter information.
if (converterAttribute != null && !string.IsNullOrEmpty(converterAttribute.ConverterTypeName))
{
try
{
converter = GetTypeConverterFromName(converterAttribute.ConverterTypeName);
}
catch (InvalidOperationException ex)
{
throw new KeyTypeConversionException(value.GetType(), destinationType, ex);
}
if (converter.CanConvertFrom(value.GetType()))
{
return converter.ConvertFrom(null, CultureInfo.InvariantCulture, value);
}
}
// If there's not a custom converter specified via attribute, try for a default.
converter = TypeDescriptor.GetConverter(value.GetType());
if (converter.CanConvertTo(destinationType))
{
return converter.ConvertTo(null, CultureInfo.InvariantCulture, value, destinationType);
}
// Try explicit opposite conversion.
converter = TypeDescriptor.GetConverter(destinationType);
if (converter.CanConvertFrom(value.GetType()))
{
return converter.ConvertFrom(null, CultureInfo.InvariantCulture, value);
}
// Try a TryParse method.
if (value is string stringValue)
{
// Some types in later frameworks have string TryParse and ReadOnlySpan<char> TryParse
// so they result in an AmbiguousMatchException unless we specify.
var parser = ReflectionCache.GetOrAddTryParseMethod(destinationType);
if (parser != null)
{
var parameters = new object?[] { stringValue, null };
if ((bool)parser.Invoke(null, parameters)!)
{
return parameters[1];
}
}
}
throw new KeyTypeConversionException(value.GetType(), destinationType);
}
/// <summary>
/// Instantiates a type converter from its type name.
/// </summary>
/// <param name="converterTypeName">
/// The name of the <see cref="Type"/> of the <see cref="TypeConverter"/>.
/// </param>
/// <returns>
/// The instantiated <see cref="TypeConverter"/>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown if <paramref name="converterTypeName"/> does not correspond
/// to a <see cref="TypeConverter"/>.
/// </exception>
private static TypeConverter GetTypeConverterFromName(string converterTypeName)
{
var converterType = ReflectionCache.GetOrAddConverterType(converterTypeName);
return (TypeConverter)Activator.CreateInstance(converterType)!;
}
[ExcludeFromCodeCoverage]
private sealed class KeyTypeManipulationReflectionCache : IReflectionCache
{
private readonly ConcurrentDictionary<ParameterInfo, TypeConverterAttribute?> _parameterConverterAttributes = new();
private readonly ConcurrentDictionary<MemberInfo, TypeConverterAttribute?> _memberConverterAttributes = new();
private readonly ConcurrentDictionary<string, Type> _converterTypeCache = new(StringComparer.Ordinal);
private readonly ConcurrentDictionary<Type, MethodInfo?> _tryParseMethodCache = new();
private readonly ConcurrentDictionary<Type, object?> _defaultValueCache = new();
public ReflectionCacheUsage Usage => ReflectionCacheUsage.Resolution;
public TypeConverterAttribute? GetOrAddParameterConverterAttribute(ParameterInfo parameter)
{
return _parameterConverterAttributes.GetOrAdd(
parameter,
static p => p.GetCustomAttributes(typeof(TypeConverterAttribute), true)
.Cast<TypeConverterAttribute>()
.FirstOrDefault());
}
public TypeConverterAttribute? GetOrAddMemberConverterAttribute(MemberInfo member)
{
return _memberConverterAttributes.GetOrAdd(
member,
static m => m.GetCustomAttributes(typeof(TypeConverterAttribute), true)
.Cast<TypeConverterAttribute>()
.FirstOrDefault());
}
public Type GetOrAddConverterType(string converterTypeName)
{
return _converterTypeCache.GetOrAdd(
converterTypeName,
static name =>
{
var resolvedType = Type.GetType(name, true)!;
if (!typeof(TypeConverter).GetTypeInfo().IsAssignableFrom(resolvedType.GetTypeInfo()))
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, KeyTypeManipulationResources.TypeConverterAttributeTypeNotConverter, name));
}
return resolvedType;
});
}
public MethodInfo? GetOrAddTryParseMethod(Type destinationType)
{
return _tryParseMethodCache.GetOrAdd(
destinationType,
static type =>
{
var parameterTypes = new[] { typeof(string), type.MakeByRefType() };
return type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, parameterTypes, null);
});
}
public object? GetOrAddDefaultValue(Type destinationType)
{
return _defaultValueCache.GetOrAdd(destinationType, static t => Activator.CreateInstance(t));
}
public void Clear()
{
_parameterConverterAttributes.Clear();
_memberConverterAttributes.Clear();
_converterTypeCache.Clear();
_tryParseMethodCache.Clear();
_defaultValueCache.Clear();
}
public void Clear(ReflectionCacheClearPredicate clearPredicate)
{
if (clearPredicate is null)
{
throw new ArgumentNullException(nameof(clearPredicate));
}
foreach (var parameter in _parameterConverterAttributes.Keys)
{
var member = parameter.Member;
var assemblies = GetParameterAssemblies(parameter);
if (clearPredicate(member, assemblies))
{
_parameterConverterAttributes.TryRemove(parameter, out _);
}
}
foreach (var member in _memberConverterAttributes.Keys)
{
if (clearPredicate(member, new[] { member.Module.Assembly }))
{
_memberConverterAttributes.TryRemove(member, out _);
}
}
foreach (var type in _tryParseMethodCache.Keys)
{
if (clearPredicate(type, new[] { type.Assembly }))
{
_tryParseMethodCache.TryRemove(type, out _);
}
}
foreach (var type in _defaultValueCache.Keys)
{
if (clearPredicate(type, new[] { type.Assembly }))
{
_defaultValueCache.TryRemove(type, out _);
}
}
foreach (var entry in _converterTypeCache)
{
if (clearPredicate(entry.Value, new[] { entry.Value.Assembly }))
{
_converterTypeCache.TryRemove(entry.Key, out _);
}
}
}
private static IEnumerable<Assembly> GetParameterAssemblies(ParameterInfo parameter)
{
var memberAssembly = parameter.Member.Module.Assembly;
var parameterAssembly = parameter.ParameterType.Assembly;
if (ReferenceEquals(memberAssembly, parameterAssembly))
{
yield return memberAssembly;
yield break;
}
yield return memberAssembly;
yield return parameterAssembly;
}
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeManipulationResources.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TypeConversionUnsupported" xml:space="preserve">
<value>Unable to convert object of type '{0}' to type '{1}'.</value>
</data>
<data name="TypeConverterAttributeTypeNotConverter" xml:space="preserve">
<value>The type '{0}' specified in the TypeConverterAttribute is not a TypeConverter.</value>
</data>
</root>
================================================
FILE: src/Autofac.Extensions.DependencyInjection/KeyedServiceMiddleware.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Concurrent;
using System.Reflection;
using Autofac.Core;
using Autofac.Core.Resolving.Pipeline;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Middleware that supports keyed service compatibility.
/// </summary>
internal class KeyedServiceMiddleware : IResolveMiddleware
{
private readonly bool _addFromKeyedServiceParameter;
/// <summary>
/// Initializes a new instance of the <see cref="KeyedServiceMiddleware"/> class.
/// </summary>
/// <param name="addFromKeyedServiceParameter">Whether or not the from-keyed-service parameter should be added.</param>
public KeyedServiceMiddleware(bool addFromKeyedServiceParameter)
{
_addFromKeyedServiceParameter = addFromKeyedServiceParameter;
}
/// <summary>
/// Gets a single instance of this middleware that does not add the keyed services parameter.
/// </summary>
public static KeyedServiceMiddleware InstanceWithoutFromKeyedServicesParameter { get; } = new(addFromKeyedServiceParameter: false);
/// <summary>
/// Gets a single instance of this middleware that adds the keyed services parameter.
/// </summary>
public static KeyedServiceMiddleware InstanceWithFromKeyedServicesParameter { get; } = new(addFromKeyedServiceParameter: true);
/// <inheritdoc />
public PipelinePhase Phase => PipelinePhase.Activation;
/// <inheritdoc />
public void Execute(ResolveRequestContext context, Action<ResolveRequestContext> next)
{
Parameter? microsoftServiceKeyParameter = null;
Parameter? fromKeyedServicesParameter = null;
var keyedService = context.Service as Autofac.Core.KeyedService;
object? inheritedServiceKey = null;
if (keyedService is not null)
{
if (Autofac.Core.KeyedService.IsAnyKey(keyedService.ServiceKey))
{
context.Parameters.TryGetKeyedServiceKey<object>(out inheritedServiceKey);
}
else
{
inheritedServiceKey = keyedService.ServiceKey;
}
}
var effectiveServiceKey = inheritedServiceKey;
if (keyedService is not null &&
effectiveServiceKey is not null &&
!Autofac.Core.KeyedService.IsAnyKey(effectiveServiceKey))
{
microsoftServiceKeyParameter = new MicrosoftServiceKeyParameter(effectiveServiceKey);
}
if (_addFromKeyedServiceParameter)
{
// [FromKeyedServices("key")] - Specifies a keyed service
// for injection into a constructor. This is similar to the
// Autofac [KeyFilter] attribute.
fromKeyedServicesParameter = new FromKeyedServicesParameter(inheritedServiceKey);
}
if (microsoftServiceKeyParameter is not null || fromKeyedServicesParameter is not null)
{
context.ChangeParameters(AppendParameters(context.Parameters, microsoftServiceKeyParameter, fromKeyedServicesParameter));
}
next(context);
}
private static List<Parameter> AppendParameters(IEnumerable<Parameter> original, Parameter? first, Parameter? second)
{
// Build a concrete list rather than using yield return, which would
// allocate a compiler-generated state machine on every call.
var list = new List<Parameter>(original is ICollection<Parameter> col ? col.Count + 2 : 4);
list.AddRange(original);
if (first is not null)
{
list.Add(first);
}
if (second is not null)
{
list.Add(second);
}
return list;
}
/// <summary>
/// Caches the presence of relevant attributes on parameters to avoid repeated reflection calls.
/// </summary>
private static class ParameterAttributeCache
{
private static readonly ParameterAttributeReflectionCache ReflectionCache = new();
static ParameterAttributeCache()
{
ReflectionCacheSet.Shared.RegisterExternalCache(ReflectionCache);
}
/// <summary>
/// Determines whether the parameter has the <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/> defined.
/// </summary>
/// <param name="parameter">The parameter to check.</param>
/// <returns>
/// <see langword="true"/> if the parameter has the attribute; otherwise, <see langword="false"/>.
/// </returns>
public static bool HasMicrosoftServiceKey(ParameterInfo parameter)
{
return ReflectionCache.GetOrAddMicrosoftServiceKeyAttributePresence(parameter);
}
/// <summary>
/// Gets the <see cref="FromKeyedServicesAttribute"/> defined on the parameter, if any.
/// </summary>
/// <param name="parameter">The parameter to check.</param>
/// <returns>
/// The <see cref="FromKeyedServicesAttribute"/> if defined; otherwise, <see langword="null"/>.
/// </returns>
public static FromKeyedServicesAttribute? GetFromKeyedServicesAttribute(ParameterInfo parameter)
{
return ReflectionCache.GetOrAddFromKeyedServicesAttribute(parameter);
}
[ExcludeFromCodeCoverage]
private sealed class ParameterAttributeReflectionCache : IReflectionCache
{
private readonly ConcurrentDictionary<ParameterInfo, bool> _microsoftServiceKeyAttributePresence = new();
private readonly ConcurrentDictionary<ParameterInfo, FromKeyedServicesAttribute?> _fromKeyedServicesAttributes = new();
public ReflectionCacheUsage Usage => ReflectionCacheUsage.Resolution;
public bool GetOrAddMicrosoftServiceKeyAttributePresence(ParameterInfo parameter)
{
return _microsoftServiceKeyAttributePresence.GetOrAdd(
parameter,
static p => Attribute.IsDefined(p, typeof(Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute), inherit: true));
}
public FromKeyedServicesAttribute? GetOrAddFromKeyedServicesAttribute(ParameterInfo parameter)
{
return _fromKeyedServicesAttributes.GetOrAdd(
parameter,
static p => p.GetCustomAttribute<FromKeyedServicesAttribute>(inherit: true));
}
public void Clear()
{
_microsoftServiceKeyAttributePresence.Clear();
_fromKeyedServicesAttributes.Clear();
}
public void Clear(ReflectionCacheClearPredicate clearPredicate)
{
if (clearPredicate is null)
{
throw new ArgumentNullException(nameof(clearPredicate));
}
foreach (var parameter in _microsoftServiceKeyAttributePresence.Keys)
{
if (Matches(clearPredicate, parameter))
{
_microsoftServiceKeyAttributePresence.TryRemove(parameter, out _);
}
}
foreach (var parameter in _fromKeyedServicesAttributes.Keys)
{
if (Matches(clearPredicate, parameter))
{
_fromKeyedServicesAttributes.TryRemove(parameter, out _);
}
}
}
private static bool Matches(ReflectionCacheClearPredicate clearPredicate, ParameterInfo parameter)
{
var member = parameter.Member;
var memberAssembly = member.Module.Assembly;
var parameterAssembly = parameter.ParameterType.Assembly;
if (ReferenceEquals(memberAssembly, parameterAssembly))
{
return clearPredicate(member, new[] { memberAssembly });
}
return clearPredicate(member, new[] { memberAssembly, parameterAssembly });
}
}
}
/// <summary>
/// A <see cref="Parameter"/> that supplies the service key for parameters
/// marked with <see cref="Microsoft.Extensions.DependencyInjection.ServiceKeyAttribute"/>.
/// Uses a field instead of a closure to avoid delegate/closure allocations.
/// </summary>
private sealed class MicrosoftServiceKeyParameter : Parameter
{
private readonly object _serviceKey;
public MicrosoftServiceKeyParameter(object serviceKey)
{
_serviceKey = serviceKey;
}
public override bool CanSupplyValue(ParameterInfo pi, IComponentContext context, [NotNullWhen(true)] out Func<object?>? valueProvider)
{
if (ParameterAttributeCache.HasMicrosoftServiceKey(pi))
{
var key = _serviceKey;
valueProvider = () => KeyTypeManipulation.ChangeToCompatibleType(key, pi.ParameterType, pi);
return true;
}
valueProvider = null;
return false;
}
}
/// <summary>
/// A <see cref="Parameter"/> that supplies keyed service dependencies for parameters
/// marked with <see cref="FromKeyedServicesAttribute"/>.
/// Uses a field instead of a closure to avoid delegate/closure allocations.
/// </summary>
private sealed class FromKeyedServicesParameter : Parameter
{
private readonly object? _requestedServiceKey;
public FromKeyedServicesParameter(object? requestedServiceKey)
{
_requestedServiceKey = requestedServiceKey;
}
public override bool CanSupplyValue(ParameterInfo pi, IComponentContext context, [NotNullWhen(true)] out Func<object?>? valueProvider)
{
var filter = ParameterAttributeCache.GetFromKeyedServicesAttribute(pi);
if (filter is not null)
{
var key = _requestedServiceKey;
valueProvider = () => filter.ResolveParameter(pi, context, key);
return true;
}
valueProvider = null;
return false;
}
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/Polyfills/NotNullWhenAttribute.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
#if NETSTANDARD2_0
namespace System.Diagnostics.CodeAnalysis;
/// <summary>
/// Polyfill for <see cref="NotNullWhenAttribute"/> which is not available in netstandard2.0.
/// Specifies that when a method returns <see cref="ReturnValue"/>,
/// the parameter will not be null even if the corresponding type allows it.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
internal sealed class NotNullWhenAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="NotNullWhenAttribute"/> class.
/// </summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
/// <summary>
/// Gets a value indicating whether the return value should be true or false for the parameter to be non-null.
/// </summary>
public bool ReturnValue { get; }
}
#endif
================================================
FILE: src/Autofac.Extensions.DependencyInjection/Properties/AssemblyInfo.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Autofac.Extensions.DependencyInjection.Test, PublicKey=00240000048000009400000006020000002400005253413100040000010001008728425885ef385e049261b18878327dfaaf0d666dea3bd2b0e4f18b33929ad4e5fbc9087e7eda3c1291d2de579206d9b4292456abffbe8be6c7060b36da0c33b883e3878eaf7c89fddf29e6e27d24588e81e86f3a22dd7b1a296b5f06fbfb500bbd7410faa7213ef4e2ce7622aefc03169b0324bcd30ccfe9ac8204e4960be6")]
[assembly: CLSCompliant(false)]
================================================
FILE: src/Autofac.Extensions.DependencyInjection/ServiceCollectionExtensions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extension methods on <see cref="IServiceCollection"/> to register the <see cref="IServiceProviderFactory{TContainerBuilder}"/>.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds the <see cref="AutofacServiceProviderFactory"/> to the service collection. ONLY FOR PRE-ASP.NET 3.0 HOSTING. THIS WON'T WORK
/// FOR ASP.NET CORE 3.0+ OR GENERIC HOSTING.
/// </summary>
/// <param name="services">The service collection to add the factory to.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the container.</param>
/// <returns>The service collection.</returns>
public static IServiceCollection AddAutofac(this IServiceCollection services, Action<ContainerBuilder>? configurationAction = null)
{
return services.AddSingleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(configurationAction));
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/ServiceDescriptorExtensions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extensions for working with <see cref="ServiceDescriptor"/>.
/// </summary>
internal static class ServiceDescriptorExtensions
{
/// <summary>
/// Normalizes the implementation instance data between keyed and not keyed services.
/// </summary>
/// <param name="descriptor">
/// The <see cref="ServiceDescriptor"/> to normalize.
/// </param>
/// <returns>
/// The appropriate implementation instance from the service descriptor.
/// </returns>
public static object? NormalizedImplementationInstance(this ServiceDescriptor descriptor) => descriptor.IsKeyedService ? descriptor.KeyedImplementationInstance : descriptor.ImplementationInstance;
/// <summary>
/// Normalizes the implementation type data between keyed and not keyed services.
/// </summary>
/// <param name="descriptor">
/// The <see cref="ServiceDescriptor"/> to normalize.
/// </param>
/// <returns>
/// The appropriate implementation type from the service descriptor.
/// </returns>
public static Type? NormalizedImplementationType(this ServiceDescriptor descriptor) => descriptor.IsKeyedService ? descriptor.KeyedImplementationType : descriptor.ImplementationType;
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/ServiceProviderExtensions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Globalization;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extension methods for use with the <see cref="AutofacServiceProvider"/>.
/// </summary>
public static class ServiceProviderExtensions
{
/// <summary>
/// Tries to cast the instance of <see cref="ILifetimeScope"/> from <see cref="AutofacServiceProvider"/> when possible.
/// </summary>
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/>.</param>
/// <exception cref="InvalidOperationException">Throws an <see cref="InvalidOperationException"/> when instance of <see cref="IServiceProvider"/> can't be assigned to <see cref="AutofacServiceProvider"/>.</exception>
/// <returns>Returns the instance of <see cref="ILifetimeScope"/> exposed by <see cref="AutofacServiceProvider"/>.</returns>
public static ILifetimeScope GetAutofacRoot(this IServiceProvider serviceProvider)
{
if (serviceProvider is not AutofacServiceProvider autofacServiceProvider)
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, ServiceProviderExtensionsResources.WrongProviderType, serviceProvider?.GetType()));
}
return autofacServiceProvider.LifetimeScope;
}
}
================================================
FILE: src/Autofac.Extensions.DependencyInjection/ServiceProviderExtensionsResources.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="WrongProviderType" xml:space="preserve">
<value>Unable to retrieve Autofac root lifetime scope from service provider of type {0}.</value>
</data>
</root>
================================================
FILE: src/Autofac.Extensions.DependencyInjection/TypeExtensions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Concurrent;
using Autofac.Core;
namespace Autofac.Extensions.DependencyInjection;
/// <summary>
/// Extensions for working with types.
/// </summary>
internal static class TypeExtensions
{
private static readonly TypeExtensionsReflectionCache ReflectionCache = new();
static TypeExtensions()
{
ReflectionCacheSet.Shared.RegisterExternalCache(ReflectionCache);
}
/// <summary>
/// Checks a type to determine if it is some kind of collection or enumerable.
/// </summary>
/// <param name="serviceType">
/// The type to check.
/// </param>
/// <returns><see langword="true"/> if the type is a collection or enumerable; otherwise, <see langword="false"/>.</returns>
internal static bool IsCollection(this Type serviceType)
{
return ReflectionCache.GetOrAddCollectionType(
serviceType,
static type =>
{
if (type.IsArray)
{
return true;
}
if (!type.IsGenericType)
{
return false;
}
return IsGenericTypeDefinedBy(type, typeof(IEnumerable<>)) ||
IsGenericListOrCollectionInterfaceType(type);
});
}
private static bool IsGenericTypeDefinedBy(Type type, Type openGeneric)
{
return !type.ContainsGenericParameters &&
type.IsGenericType &&
type.GetGenericTypeDefinition() == openGeneric;
}
private static bool IsGenericListOrCollectionInterfaceType(Type type)
{
return IsGenericTypeDefinedBy(type, typeof(IList<>)) ||
IsGenericTypeDefinedBy(type, typeof(ICollection<>)) ||
IsGenericTypeDefinedBy(type, typeof(IReadOnlyCollection<>)) ||
IsGenericTypeDefinedBy(type, typeof(IReadOnlyList<>));
}
[ExcludeFromCodeCoverage]
private sealed class TypeExtensionsReflectionCache : IReflectionCache
{
private readonly ConcurrentDictionary<Type, bool> _collectionTypeCache = new();
public ReflectionCacheUsage Usage => ReflectionCacheUsage.Resolution;
public bool GetOrAddCollectionType(Type serviceType, Func<Type, bool> valueFactory)
{
return _collectionTypeCache.GetOrAdd(serviceType, valueFactory);
}
public void Clear()
{
_collectionTypeCache.Clear();
}
public void Clear(ReflectionCacheClearPredicate clearPredicate)
{
if (clearPredicate is null)
{
throw new ArgumentNullException(nameof(clearPredicate));
}
foreach (var type in _collectionTypeCache.Keys)
{
if (clearPredicate(type, new[] { type.Assembly }))
{
_collectionTypeCache.TryRemove(type, out _);
}
}
}
}
}
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Integration.Test/Autofac.Extensions.DependencyInjection.Integration.Test.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net10.0;net8.0</TargetFrameworks>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyOriginatorKeyFile>../../Autofac.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<CodeAnalysisRuleSet>../../build/Test.ruleset</CodeAnalysisRuleSet>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Autofac.Extensions.DependencyInjection\Autofac.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\build\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.25" />
<ProjectReference Include="..\Integration.Net8\Integration.Net8.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.4" />
<ProjectReference Include="..\Integration.Net10\Integration.Net10.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Integration.Test/IntegrationTests.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
#if NET10_0
using Integration.Net10;
#endif
#if NET8_0
using Integration.Net8;
#endif
namespace Autofac.Extensions.DependencyInjection.Integration.Test;
public class IntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
public IntegrationTests(WebApplicationFactory<Startup> appFactory)
{
AppFactory = appFactory;
}
public WebApplicationFactory<Startup> AppFactory { get; }
[Fact]
public async Task GetDate()
{
var client = AppFactory.CreateClient();
var response = await client.GetAsync(new Uri("/Date", UriKind.Relative));
response.EnsureSuccessStatusCode();
}
}
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Integration.Test/Properties/AssemblyInfo.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
[assembly: CLSCompliant(false)]
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Test/Assertions.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Autofac.Core;
namespace Autofac.Extensions.DependencyInjection.Test;
internal static class Assertions
{
public static void AssertRegistered<TService>(this IComponentContext context)
{
Assert.True(context.IsRegistered<TService>());
}
public static void AssertNotRegistered<TService>(this IComponentContext context)
{
Assert.False(context.IsRegistered<TService>());
}
public static void AssertImplementation<TService, TImplementation>(this IComponentContext context)
{
var service = context.Resolve<TService>();
Assert.IsAssignableFrom<TImplementation>(service);
}
public static void AssertSharing<TService>(this IComponentContext context, InstanceSharing sharing)
{
var cr = context.RegistrationFor<TService>();
Assert.Equal(sharing, cr.Sharing);
}
public static void AssertLifetime<TService, TLifetime>(this IComponentContext context)
{
var cr = context.RegistrationFor<TService>();
Assert.IsType<TLifetime>(cr.Lifetime);
}
public static void AssertOwnership<TService>(this IComponentContext context, InstanceOwnership ownership)
{
var cr = context.RegistrationFor<TService>();
Assert.Equal(ownership, cr.Ownership);
}
public static IComponentRegistration RegistrationFor<TService>(this IComponentContext context)
{
Assert.True(context.ComponentRegistry.TryGetRegistration(new TypedService(typeof(TService)), out IComponentRegistration r));
return r;
}
}
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Test/Autofac.Extensions.DependencyInjection.Test.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0;net8.0</TargetFrameworks>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyOriginatorKeyFile>../../Autofac.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<CodeAnalysisRuleSet>../../build/Test.ruleset</CodeAnalysisRuleSet>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Autofac.Extensions.DependencyInjection\Autofac.Extensions.DependencyInjection.csproj" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\build\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Specification.Tests" Version="10.0.4" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeConfigurationAdapterTests.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Autofac.Extensions.DependencyInjection.Test;
public sealed class AutofacChildLifetimeScopeConfigurationAdapterTests
{
[Fact]
public void AddMultipleConfigurationContainsConfigurations()
{
var adapter = new AutofacChildLifetimeScopeConfigurationAdapter();
adapter.Add(builder => { });
adapter.Add(builder => { });
Assert.Equal(2, adapter.ConfigurationActions.Count);
}
[Fact]
public void AddNullConfigurationThrows()
=> Assert.Throws<ArgumentNullException>(() => new AutofacChildLifetimeScopeConfigurationAdapter().Add(null));
}
================================================
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeServiceProviderFactoryTests.cs
================================================
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
namespace Autofac.Extensions.DependencyInjection.Test;
public sealed class AutofacChildLifetimeScopeServiceProviderFactoryTests
{
[Fact]
public void CreateBuilderReturnsNewInstance()
{
var factory = new AutofacChildLifetimeScopeServiceProviderFactory(GetRootLifetimeScope);
var configurationAdapter = factory.CreateBuilder(new ServiceCollection());
Assert.NotNull(configurationAdapter);
}
[Fact]
public void CreateBuilderExecutesConfigurationActionWhenProvided()
{
var factory = new AutofacChildLifetimeScopeServiceProviderFactory(GetRootLifetimeScope, b => b.Register(c => "Foo"));
var configurationAdapter = factory.CreateBuilder(new ServiceCollection());
var builder = new ContainerBuilder();
foreach (var action in configurationAdapter.ConfigurationActions)
{
action(builder);
}
Assert.Equal("Foo", builder.Build().Resolve<string>());
}
[Fact]
public void CreateBuilderAllowsForNullConfigurationAction()
{
var factory = new AutofacChildLifetimeScopeServiceProviderFactory(GetRootLifetimeScope);
var configurationAdapter = factory.CreateBuilder(new ServiceCollection());
Assert.NotNull(configurationAdapter);
}
[Fact]
public void CreateBuilderReturnsInstanceWithServicesPopulated()
{
var factory = new AutofacChildLifetimeScopeServiceProviderFactory(GetRootLifetimeScope);
var services = new ServiceCollection().AddTransient<object>();
var configurationAdapter = factory.CreateBuilder(services);
var builder = new ContainerBuilder();
foreach (var action in configurationAdapter.ConfigurationActions)
{
action(builder);
}
Assert.True(builder.Build().IsRegistered<object>());
}
[Fact]
public void CreateServiceProviderBuildsServiceProviderUsingAdapter()
{
var factory = new AutofacChildLifetimeScop
gitextract_omufirln/
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── build.yml
│ ├── ci.yml
│ ├── dotnet-format.yml
│ ├── pre-commit.yml
│ └── publish.yml
├── .gitignore
├── .markdownlint.json
├── .pre-commit-config.yaml
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── Autofac.Extensions.DependencyInjection.sln
├── Autofac.Extensions.DependencyInjection.sln.DotSettings
├── Autofac.snk
├── Directory.Build.props
├── LICENSE
├── README.md
├── bench/
│ └── Autofac.Extensions.DependencyInjection.Bench/
│ ├── Autofac.Extensions.DependencyInjection.Bench.csproj
│ ├── AutofacWebApplicationFactory.cs
│ ├── BenchWebApplicationFactory.cs
│ ├── BenchmarkConfig.cs
│ ├── Benchmarks.cs
│ ├── DefaultWebApplicationFactory.cs
│ ├── Harness.cs
│ ├── KeyedResolutionBenchmark.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── RequestBenchmark.cs
│ ├── SampleApp/
│ │ ├── Controllers/
│ │ │ └── ValuesController.cs
│ │ ├── DefaultStartup.cs
│ │ ├── Program.cs
│ │ └── Services.cs
│ └── xunit.runner.json
├── build/
│ ├── Coverage.runsettings
│ ├── Source.ruleset
│ ├── Test.ruleset
│ └── stylecop.json
├── codecov.yml
├── default.proj
├── global.json
├── src/
│ └── Autofac.Extensions.DependencyInjection/
│ ├── Autofac.Extensions.DependencyInjection.csproj
│ ├── AutofacChildLifetimeScopeConfigurationAdapter.cs
│ ├── AutofacChildLifetimeScopeServiceProviderFactory.cs
│ ├── AutofacRegistration.cs
│ ├── AutofacServiceProvider.cs
│ ├── AutofacServiceProviderFactory.cs
│ ├── AutofacServiceScope.cs
│ ├── AutofacServiceScopeFactory.cs
│ ├── FromKeyedServicesAttributeExtensions.cs
│ ├── FromKeyedServicesUsageCache.cs
│ ├── KeyTypeConversionException.cs
│ ├── KeyTypeConversionExceptionResources.resx
│ ├── KeyTypeManipulation.cs
│ ├── KeyTypeManipulationResources.resx
│ ├── KeyedServiceMiddleware.cs
│ ├── Polyfills/
│ │ └── NotNullWhenAttribute.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── ServiceCollectionExtensions.cs
│ ├── ServiceDescriptorExtensions.cs
│ ├── ServiceProviderExtensions.cs
│ ├── ServiceProviderExtensionsResources.resx
│ └── TypeExtensions.cs
└── test/
├── Autofac.Extensions.DependencyInjection.Integration.Test/
│ ├── Autofac.Extensions.DependencyInjection.Integration.Test.csproj
│ ├── IntegrationTests.cs
│ └── Properties/
│ └── AssemblyInfo.cs
├── Autofac.Extensions.DependencyInjection.Test/
│ ├── Assertions.cs
│ ├── Autofac.Extensions.DependencyInjection.Test.csproj
│ ├── AutofacChildLifetimeScopeConfigurationAdapterTests.cs
│ ├── AutofacChildLifetimeScopeServiceProviderFactoryTests.cs
│ ├── AutofacRegistrationTests.cs
│ ├── AutofacServiceProviderFactoryTests.cs
│ ├── AutofacServiceProviderTests.cs
│ ├── FromKeyedServicesAttributeExtensionsTests.cs
│ ├── FromKeyedServicesUsageCacheTests.cs
│ ├── KeyTypeManipulationFixture.cs
│ ├── KeyedServiceTests.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── ServiceCollectionExtensionsTests.cs
│ ├── ServiceProviderExtensionsTests.cs
│ ├── Specification/
│ │ ├── AssumedBehaviorTests.cs
│ │ ├── BuilderAssumedBehaviorTests.cs
│ │ ├── BuilderKeyedSpecificationTests.cs
│ │ ├── BuilderSpecificationTests.cs
│ │ ├── ChildScopeFactoryAssumedBehaviorTests.cs
│ │ ├── ChildScopeFactoryKeyedSpecificationTests.cs
│ │ ├── ChildScopeFactorySpecificationTests.cs
│ │ ├── FactoryAssumedBehaviorTests.cs
│ │ ├── FactoryKeyedSpecificationTests.cs
│ │ ├── FactorySpecificationTests.cs
│ │ └── MicrosoftAssumedBehaviorTests.cs
│ ├── TestCulture.cs
│ └── TypeExtensionsTests.cs
├── Integration.Net10/
│ ├── Controllers/
│ │ └── DateController.cs
│ ├── DateProvider.cs
│ ├── IDateProvider.cs
│ ├── Integration.Net10.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
└── Integration.Net8/
├── Controllers/
│ └── DateController.cs
├── DateProvider.cs
├── IDateProvider.cs
├── Integration.Net8.csproj
├── Program.cs
├── Properties/
│ ├── AssemblyInfo.cs
│ └── launchSettings.json
├── Startup.cs
├── appsettings.Development.json
└── appsettings.json
SYMBOL INDEX (405 symbols across 66 files)
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/AutofacWebApplicationFactory.cs
class AutofacWebApplicationFactory (line 8) | public sealed class AutofacWebApplicationFactory<TStartup> : BenchWebApp...
method CreateHost (line 11) | protected override IHost CreateHost(IHostBuilder builder)
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/BenchWebApplicationFactory.cs
class BenchWebApplicationFactory (line 12) | public abstract class BenchWebApplicationFactory<TStartup> : WebApplicat...
method ConfigureWebHost (line 17) | protected override void ConfigureWebHost(IWebHostBuilder builder)
method ResolveContentRoot (line 24) | private static string ResolveContentRoot() =>
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/BenchmarkConfig.cs
class BenchmarkConfig (line 9) | internal sealed class BenchmarkConfig : ManualConfig
method BenchmarkConfig (line 13) | internal BenchmarkConfig()
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Benchmarks.cs
class Benchmarks (line 6) | public static class Benchmarks
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/DefaultWebApplicationFactory.cs
class DefaultWebApplicationFactory (line 6) | public sealed class DefaultWebApplicationFactory<TStartup> : BenchWebApp...
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Harness.cs
class Harness (line 8) | public class Harness
method Request (line 10) | [Fact]
method KeyedResolution (line 13) | [Fact]
method RunBenchmark (line 20) | private static void RunBenchmark<TBenchmark>()
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/KeyedResolutionBenchmark.cs
class KeyedResolutionBenchmark (line 10) | [MemoryDiagnoser]
method Setup (line 22) | [GlobalSetup]
method Cleanup (line 43) | [GlobalCleanup]
method StandardTypedResolution (line 49) | [Benchmark(Baseline = true)]
method KeyedResolutionWithoutAttributes (line 55) | [Benchmark]
method KeyedResolutionWithServiceKeyAttribute (line 61) | [Benchmark]
method KeyedResolutionWithFromKeyedServicesAttribute (line 67) | [Benchmark]
method KeyedResolutionWithBothAttributes (line 73) | [Benchmark]
method KeyedResolutionWithAnyKey (line 79) | [Benchmark]
type IService (line 92) | private interface IService
class DefaultService (line 97) | private sealed class DefaultService : IService
class AlphaService (line 102) | private sealed class AlphaService : IService
class BetaService (line 107) | private sealed class BetaService : IService
class FromKeyedServicesConsumer (line 112) | private sealed class FromKeyedServicesConsumer
method FromKeyedServicesConsumer (line 116) | public FromKeyedServicesConsumer([FromKeyedServices(BetaKey)] IServi...
class CombinedConsumer (line 124) | private sealed class CombinedConsumer
method CombinedConsumer (line 129) | public CombinedConsumer(
class ServiceKeyAwareService (line 147) | private sealed class ServiceKeyAwareService : IService
method ServiceKeyAwareService (line 151) | public ServiceKeyAwareService([MicrosoftServiceKey] string resolvedKey)
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/Program.cs
class Program (line 10) | public sealed class Program
method Program (line 12) | private Program()
method Main (line 16) | public static void Main(string[] args)
method CreateHostBuilder (line 48) | public static IHostBuilder CreateHostBuilder(string[] args) =>
method ExtractBaselineVersion (line 51) | private static (string[] RemainingArgs, string? BaselineVersion) Extra...
method TryMatchBaselineArg (line 82) | private static bool TryMatchBaselineArg(string arg, out string? valueF...
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/RequestBenchmark.cs
class RequestBenchmark (line 10) | [SuppressMessage("CA1001", "CA1001", Justification = "Benchmark disposal...
method Setup (line 19) | [GlobalSetup]
method Cleanup (line 29) | [GlobalCleanup]
method RequestDefaultDI (line 36) | [Benchmark(Baseline = true)]
method RequestAutofacDI (line 47) | [Benchmark]
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Controllers/ValuesController.cs
class ValuesController (line 8) | [Route("api/[controller]")]
method ValuesController (line 14) | public ValuesController(A service)
method Get (line 19) | [HttpGet]
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/DefaultStartup.cs
class DefaultStartup (line 12) | public class DefaultStartup
method DefaultStartup (line 14) | public DefaultStartup(IConfiguration configuration)
method ConfigureServices (line 21) | public void ConfigureServices(IServiceCollection services)
method Configure (line 34) | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Program.cs
class Program (line 10) | public sealed class Program
method Program (line 12) | private Program()
method CreateHostBuilder (line 16) | public static IHostBuilder CreateHostBuilder(string[] args) =>
FILE: bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Services.cs
class A (line 8) | public class A
method A (line 10) | public A(B1 b1, B2 b2)
class B1 (line 15) | public class B1
method B1 (line 17) | public B1(B2 b2, C1 c1, C2 c2)
class B2 (line 22) | public class B2
method B2 (line 24) | public B2(C1 c1, C2 c2)
class C1 (line 29) | public class C1
method C1 (line 31) | public C1(C2 c2, D1 d1, D2 d2)
class C2 (line 36) | public class C2
method C2 (line 38) | public C2(D1 d1, D2 d2)
class D1 (line 43) | public class D1
class D2 (line 47) | public class D2
FILE: src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeConfigurationAdapter.cs
class AutofacChildLifetimeScopeConfigurationAdapter (line 9) | public class AutofacChildLifetimeScopeConfigurationAdapter
method Add (line 23) | public void Add(Action<ContainerBuilder> configurationAction)
FILE: src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeServiceProviderFactory.cs
class AutofacChildLifetimeScopeServiceProviderFactory (line 11) | public class AutofacChildLifetimeScopeServiceProviderFactory : IServiceP...
method AutofacChildLifetimeScopeServiceProviderFactory (line 22) | public AutofacChildLifetimeScopeServiceProviderFactory(Func<ILifetimeS...
method AutofacChildLifetimeScopeServiceProviderFactory (line 38) | public AutofacChildLifetimeScopeServiceProviderFactory(ILifetimeScope ...
method CreateBuilder (line 49) | public AutofacChildLifetimeScopeConfigurationAdapter CreateBuilder(ISe...
method CreateServiceProvider (line 64) | public IServiceProvider CreateServiceProvider(AutofacChildLifetimeScop...
FILE: src/Autofac.Extensions.DependencyInjection/AutofacRegistration.cs
class AutofacRegistration (line 17) | public static class AutofacRegistration
method Populate (line 30) | public static void Populate(
method Populate (line 65) | public static void Populate(
method AddFromKeyedServiceParameterMiddleware (line 103) | private static void AddFromKeyedServiceParameterMiddleware(object? sen...
method ConfigureServiceType (line 162) | private static IRegistrationBuilder<object, TActivatorData, TRegistrat...
method ConfigureLifecycle (line 202) | private static IRegistrationBuilder<object, TActivatorData, TRegistrat...
method Register (line 246) | [SuppressMessage("CA2000", "CA2000", Justification = "Registrations cr...
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceProvider.cs
class AutofacServiceProvider (line 15) | public class AutofacServiceProvider : IServiceProvider, ISupportRequired...
method AutofacServiceProvider (line 27) | public AutofacServiceProvider(ILifetimeScope lifetimeScope)
method GetKeyedService (line 50) | public object? GetKeyedService(Type serviceType, object? serviceKey)
method GetRequiredKeyedService (line 98) | public object GetRequiredKeyedService(Type serviceType, object? servic...
method GetRequiredService (line 143) | public object GetRequiredService(Type serviceType)
method IsKeyedService (line 156) | public bool IsKeyedService(Type serviceType, object? serviceKey)
method IsService (line 168) | public bool IsService(Type serviceType) => _lifetimeScope.ComponentReg...
method GetService (line 180) | public object? GetService(Type serviceType)
method Dispose (line 195) | public void Dispose()
method DisposeAsync (line 205) | public async ValueTask DisposeAsync()
method Dispose (line 222) | protected virtual void Dispose(bool disposing)
method NormalizeServiceKey (line 234) | private static object? NormalizeServiceKey(Type serviceType, object? s...
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceProviderFactory.cs
class AutofacServiceProviderFactory (line 12) | public class AutofacServiceProviderFactory : IServiceProviderFactory<Con...
method AutofacServiceProviderFactory (line 24) | public AutofacServiceProviderFactory(
method AutofacServiceProviderFactory (line 34) | public AutofacServiceProviderFactory(Action<ContainerBuilder>? configu...
method CreateBuilder (line 42) | public ContainerBuilder CreateBuilder(IServiceCollection services)
method CreateServiceProvider (line 58) | public IServiceProvider CreateServiceProvider(ContainerBuilder contain...
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceScope.cs
class AutofacServiceScope (line 14) | internal class AutofacServiceScope : AutofacServiceProvider, IServiceScope
method AutofacServiceScope (line 22) | public AutofacServiceScope(ILifetimeScope lifetimeScope)
FILE: src/Autofac.Extensions.DependencyInjection/AutofacServiceScopeFactory.cs
class AutofacServiceScopeFactory (line 12) | internal class AutofacServiceScopeFactory : IServiceScopeFactory
method AutofacServiceScopeFactory (line 20) | public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope)
method CreateScope (line 36) | public IServiceScope CreateScope()
FILE: src/Autofac.Extensions.DependencyInjection/FromKeyedServicesAttributeExtensions.cs
class FromKeyedServicesAttributeExtensions (line 13) | internal static class FromKeyedServicesAttributeExtensions
method ResolveParameter (line 28) | public static object? ResolveParameter(this FromKeyedServicesAttribute...
method ResolveUnkeyed (line 53) | private static object? ResolveUnkeyed(ParameterInfo parameter, ICompon...
method ResolveKeyed (line 63) | private static object? ResolveKeyed(ParameterInfo parameter, IComponen...
method GetDefaultValueOrThrow (line 78) | private static object? GetDefaultValueOrThrow(ParameterInfo parameter,...
method NormalizeKey (line 102) | private static object? NormalizeKey(object? key)
FILE: src/Autofac.Extensions.DependencyInjection/FromKeyedServicesUsageCache.cs
class FromKeyedServicesUsageCache (line 14) | [ExcludeFromCodeCoverage]
method FromKeyedServicesUsageCache (line 19) | static FromKeyedServicesUsageCache()
method RequiresFromKeyedServicesMiddleware (line 29) | public static bool RequiresFromKeyedServicesMiddleware(ReflectionActiv...
method ScanConstructors (line 55) | private static bool ScanConstructors(IConstructorFinder constructorFin...
type CacheKey (line 73) | private readonly struct CacheKey : IEquatable<CacheKey>
method CacheKey (line 75) | public CacheKey(Type implementationType, Type constructorFinderType)
method Matches (line 85) | public bool Matches(ReflectionCacheClearPredicate clearPredicate)
method Equals (line 97) | public bool Equals(CacheKey other)
method Equals (line 103) | [ExcludeFromCodeCoverage]
method GetHashCode (line 109) | public override int GetHashCode()
class FromKeyedServicesUsageReflectionCache (line 118) | private sealed class FromKeyedServicesUsageReflectionCache : IReflecti...
method TryGet (line 124) | public bool TryGet(CacheKey key, out bool result)
method GetOrAdd (line 129) | public bool GetOrAdd(CacheKey key, bool value)
method GetOrAdd (line 134) | public bool GetOrAdd(CacheKey key, Func<CacheKey, (IConstructorFinde...
method Clear (line 143) | public void Clear()
method Clear (line 148) | public void Clear(ReflectionCacheClearPredicate clearPredicate)
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeConversionException.cs
class KeyTypeConversionException (line 13) | [ExcludeFromCodeCoverage]
method KeyTypeConversionException (line 28) | public KeyTypeConversionException(Type resolutionKeyType, Type attribu...
method KeyTypeConversionException (line 48) | public KeyTypeConversionException(Type resolutionKeyType, Type attribu...
method KeyTypeConversionException (line 68) | public KeyTypeConversionException(Type resolutionKeyType, Type attribu...
method KeyTypeConversionException (line 89) | public KeyTypeConversionException(Type resolutionKeyType, Type attribu...
FILE: src/Autofac.Extensions.DependencyInjection/KeyTypeManipulation.cs
class KeyTypeManipulation (line 18) | internal class KeyTypeManipulation
method KeyTypeManipulation (line 22) | static KeyTypeManipulation()
method ChangeToCompatibleType (line 42) | public static object? ChangeToCompatibleType(object? value, Type desti...
method ChangeToCompatibleType (line 68) | public static object? ChangeToCompatibleType(object? value, Type desti...
method ChangeToCompatibleType (line 94) | public static object? ChangeToCompatibleType(object? value, Type desti...
method GetTypeConverterFromName (line 180) | private static TypeConverter GetTypeConverterFromName(string converter...
class KeyTypeManipulationReflectionCache (line 187) | [ExcludeFromCodeCoverage]
method GetOrAddParameterConverterAttribute (line 198) | public TypeConverterAttribute? GetOrAddParameterConverterAttribute(P...
method GetOrAddMemberConverterAttribute (line 207) | public TypeConverterAttribute? GetOrAddMemberConverterAttribute(Memb...
method GetOrAddConverterType (line 216) | public Type GetOrAddConverterType(string converterTypeName)
method GetOrAddTryParseMethod (line 232) | public MethodInfo? GetOrAddTryParseMethod(Type destinationType)
method GetOrAddDefaultValue (line 243) | public object? GetOrAddDefaultValue(Type destinationType)
method Clear (line 248) | public void Clear()
method Clear (line 257) | public void Clear(ReflectionCacheClearPredicate clearPredicate)
method GetParameterAssemblies (line 307) | private static IEnumerable<Assembly> GetParameterAssemblies(Paramete...
FILE: src/Autofac.Extensions.DependencyInjection/KeyedServiceMiddleware.cs
class KeyedServiceMiddleware (line 15) | internal class KeyedServiceMiddleware : IResolveMiddleware
method KeyedServiceMiddleware (line 23) | public KeyedServiceMiddleware(bool addFromKeyedServiceParameter)
method Execute (line 42) | public void Execute(ResolveRequestContext context, Action<ResolveReque...
method AppendParameters (line 87) | private static List<Parameter> AppendParameters(IEnumerable<Parameter>...
class ParameterAttributeCache (line 110) | private static class ParameterAttributeCache
method ParameterAttributeCache (line 114) | static ParameterAttributeCache()
method HasMicrosoftServiceKey (line 126) | public static bool HasMicrosoftServiceKey(ParameterInfo parameter)
method GetFromKeyedServicesAttribute (line 138) | public static FromKeyedServicesAttribute? GetFromKeyedServicesAttrib...
class ParameterAttributeReflectionCache (line 143) | [ExcludeFromCodeCoverage]
method GetOrAddMicrosoftServiceKeyAttributePresence (line 151) | public bool GetOrAddMicrosoftServiceKeyAttributePresence(Parameter...
method GetOrAddFromKeyedServicesAttribute (line 158) | public FromKeyedServicesAttribute? GetOrAddFromKeyedServicesAttrib...
method Clear (line 165) | public void Clear()
method Clear (line 171) | public void Clear(ReflectionCacheClearPredicate clearPredicate)
method Matches (line 195) | private static bool Matches(ReflectionCacheClearPredicate clearPre...
class MicrosoftServiceKeyParameter (line 216) | private sealed class MicrosoftServiceKeyParameter : Parameter
method MicrosoftServiceKeyParameter (line 220) | public MicrosoftServiceKeyParameter(object serviceKey)
method CanSupplyValue (line 225) | public override bool CanSupplyValue(ParameterInfo pi, IComponentCont...
class FromKeyedServicesParameter (line 244) | private sealed class FromKeyedServicesParameter : Parameter
method FromKeyedServicesParameter (line 248) | public FromKeyedServicesParameter(object? requestedServiceKey)
method CanSupplyValue (line 253) | public override bool CanSupplyValue(ParameterInfo pi, IComponentCont...
FILE: src/Autofac.Extensions.DependencyInjection/Polyfills/NotNullWhenAttribute.cs
class NotNullWhenAttribute (line 13) | [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
method NotNullWhenAttribute (line 22) | public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnV...
FILE: src/Autofac.Extensions.DependencyInjection/ServiceCollectionExtensions.cs
class ServiceCollectionExtensions (line 11) | public static class ServiceCollectionExtensions
method AddAutofac (line 20) | public static IServiceCollection AddAutofac(this IServiceCollection se...
FILE: src/Autofac.Extensions.DependencyInjection/ServiceDescriptorExtensions.cs
class ServiceDescriptorExtensions (line 11) | internal static class ServiceDescriptorExtensions
method NormalizedImplementationInstance (line 22) | public static object? NormalizedImplementationInstance(this ServiceDes...
method NormalizedImplementationType (line 33) | public static Type? NormalizedImplementationType(this ServiceDescripto...
FILE: src/Autofac.Extensions.DependencyInjection/ServiceProviderExtensions.cs
class ServiceProviderExtensions (line 11) | public static class ServiceProviderExtensions
method GetAutofacRoot (line 19) | public static ILifetimeScope GetAutofacRoot(this IServiceProvider serv...
FILE: src/Autofac.Extensions.DependencyInjection/TypeExtensions.cs
class TypeExtensions (line 11) | internal static class TypeExtensions
method TypeExtensions (line 15) | static TypeExtensions()
method IsCollection (line 27) | internal static bool IsCollection(this Type serviceType)
method IsGenericTypeDefinedBy (line 48) | private static bool IsGenericTypeDefinedBy(Type type, Type openGeneric)
method IsGenericListOrCollectionInterfaceType (line 55) | private static bool IsGenericListOrCollectionInterfaceType(Type type)
class TypeExtensionsReflectionCache (line 63) | [ExcludeFromCodeCoverage]
method GetOrAddCollectionType (line 70) | public bool GetOrAddCollectionType(Type serviceType, Func<Type, bool...
method Clear (line 75) | public void Clear()
method Clear (line 80) | public void Clear(ReflectionCacheClearPredicate clearPredicate)
FILE: test/Autofac.Extensions.DependencyInjection.Integration.Test/IntegrationTests.cs
class IntegrationTests (line 16) | public class IntegrationTests : IClassFixture<WebApplicationFactory<Star...
method IntegrationTests (line 18) | public IntegrationTests(WebApplicationFactory<Startup> appFactory)
method GetDate (line 25) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/Assertions.cs
class Assertions (line 8) | internal static class Assertions
method AssertRegistered (line 10) | public static void AssertRegistered<TService>(this IComponentContext c...
method AssertNotRegistered (line 15) | public static void AssertNotRegistered<TService>(this IComponentContex...
method AssertImplementation (line 20) | public static void AssertImplementation<TService, TImplementation>(thi...
method AssertSharing (line 26) | public static void AssertSharing<TService>(this IComponentContext cont...
method AssertLifetime (line 32) | public static void AssertLifetime<TService, TLifetime>(this IComponent...
method AssertOwnership (line 38) | public static void AssertOwnership<TService>(this IComponentContext co...
method RegistrationFor (line 44) | public static IComponentRegistration RegistrationFor<TService>(this IC...
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeConfigurationAdapterTests.cs
class AutofacChildLifetimeScopeConfigurationAdapterTests (line 6) | public sealed class AutofacChildLifetimeScopeConfigurationAdapterTests
method AddMultipleConfigurationContainsConfigurations (line 8) | [Fact]
method AddNullConfigurationThrows (line 18) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeServiceProviderFactoryTests.cs
class AutofacChildLifetimeScopeServiceProviderFactoryTests (line 9) | public sealed class AutofacChildLifetimeScopeServiceProviderFactoryTests
method CreateBuilderReturnsNewInstance (line 11) | [Fact]
method CreateBuilderExecutesConfigurationActionWhenProvided (line 21) | [Fact]
method CreateBuilderAllowsForNullConfigurationAction (line 38) | [Fact]
method CreateBuilderReturnsInstanceWithServicesPopulated (line 48) | [Fact]
method CreateServiceProviderBuildsServiceProviderUsingAdapter (line 66) | [Fact]
method CreateServiceProviderThrowsWhenProvidedNullAdapter (line 78) | [Fact]
method CreateServiceProviderReturnsAutofacServiceProvider (line 88) | [Fact]
method CreateServiceProviderAddDepToServiceCollectionAndAddConfigurationTypesResolvable (line 98) | [Fact]
method CreateServiceProviderAddDepToRootContainerResolvable (line 115) | [Fact]
method Ctor_NullRootAccessor (line 127) | [Fact]
method Ctor_NullRootScope (line 133) | [Fact]
method GetRootLifetimeScope (line 139) | private static ILifetimeScope GetRootLifetimeScope() => new ContainerB...
method GetRootLifetimeScopeWithDependency (line 141) | private static ILifetimeScope GetRootLifetimeScopeWithDependency<TAs>(...
class DependencyOne (line 152) | [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated via...
class DependencyTwo (line 157) | [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated via...
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacRegistrationTests.cs
class AutofacRegistrationTests (line 12) | public class AutofacRegistrationTests
method PopulateRegistersServiceProvider (line 14) | [Fact]
method PopulateThrowsForNullBuilder (line 24) | [Fact]
method PopulateThrowsForNullDescriptors (line 30) | [Fact]
method CorrectServiceProviderIsRegistered (line 36) | [Fact]
method ServiceProviderInstancesAreNotTracked (line 46) | [Fact]
method PopulateRegistersServiceScopeFactory (line 56) | [Fact]
method ServiceScopeFactoryIsRegistered (line 66) | [Fact]
method CanRegisterTransientService (line 76) | [Fact]
method CanRegisterSingletonService (line 89) | [Fact]
method CanRebaseSingletonServiceToNamedLifetimeScope (line 102) | [Fact]
method CanRegisterScopedService (line 115) | [Fact]
method CanRegisterGenericService (line 128) | [Fact]
method CanRegisterFactoryService (line 139) | [Fact]
method CanResolveOptionsFromChildScopeProvider (line 150) | [Fact]
method CanGenerateFactoryService (line 172) | [Fact]
method ServiceCollectionConfigurationIsRetainedInRootContainer (line 183) | [Fact]
method RegistrationsAddedAfterPopulateComeLastWhenResolvedWithIEnumerable (line 202) | [Fact]
method RegistrationsAddedBeforePopulateComeFirstWhenResolvedWithIEnumerable (line 224) | [Fact]
class Service (line 246) | private class Service : IService
type IService (line 250) | private interface IService
class TestOptions (line 254) | [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated via...
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacServiceProviderFactoryTests.cs
class AutofacServiceProviderFactoryTests (line 9) | public class AutofacServiceProviderFactoryTests
method CreateBuilderReturnsNewInstance (line 11) | [Fact]
method CreateBuilderExecutesConfigurationActionWhenProvided (line 21) | [Fact]
method CreateBuilderAllowsForNullConfigurationAction (line 31) | [Fact]
method CreateBuilderReturnsInstanceWithServicesPopulated (line 41) | [Fact]
method CreateServiceProviderBuildsServiceProviderUsingContainerBuilder (line 53) | [Fact]
method CreateServiceProviderThrowsWhenProvidedNullContainerBuilder (line 65) | [Fact]
method CreateServiceProviderReturnsAutofacServiceProvider (line 75) | [Fact]
method CreateServiceProviderUsesDefaultContainerBuildOptionsWhenNotProvided (line 85) | [Fact]
method CreateServiceProviderUsesContainerBuildOptionsWhenProvided (line 97) | [Fact]
method CanProvideContainerBuildOptionsAndConfigurationAction (line 110) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/AutofacServiceProviderTests.cs
class AutofacServiceProviderTests (line 10) | public class AutofacServiceProviderTests
method Ctor_NullLifetimeScope (line 12) | [Fact]
method GetKeyedService_NullServiceType (line 18) | [Fact]
method GetRequiredKeyedService_NullServiceType (line 25) | [Fact]
method GetRequiredService_DependencyResolutionFails (line 32) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/FromKeyedServicesAttributeExtensionsTests.cs
class FromKeyedServicesAttributeExtensionsTests (line 10) | public class FromKeyedServicesAttributeExtensionsTests
method ResolveParameterExplicitKey (line 12) | [Fact]
method ResolveParameterInheritedAnyKeyUsedForCollection (line 24) | [Fact]
method ResolveParameterInheritedAnyKeyUsedForNonCollection (line 37) | [Fact]
method ResolveParameterInheritedKey (line 48) | [Fact]
method ResolveParameterInheritedKeyIsNull (line 60) | [Fact]
method ResolveParameterKeyedServiceMissingAndNoDefault (line 72) | [Fact]
method ResolveParameterNullAttribute (line 84) | [Fact]
method ResolveParameterNullContext (line 96) | [Fact]
method ResolveParameterNullParameter (line 108) | [Fact]
method ResolveParameterResolveFails (line 120) | [Fact]
method ResolveParameterUnkeyedServiceMissingAndNoDefault (line 132) | [Fact]
method BuildContainer (line 145) | private static IContainer BuildContainer()
method GetAttribute (line 153) | private static FromKeyedServicesAttribute GetAttribute(string methodName)
method GetParameter (line 158) | private static ParameterInfo GetParameter(string methodName)
type IService (line 163) | private interface IService
class KeyedService (line 167) | private sealed class KeyedService : IService
class InheritedKeyedService (line 171) | private sealed class InheritedKeyedService : IService
class ParameterTargets (line 175) | private sealed class ParameterTargets
method Explicit (line 177) | public void Explicit([FromKeyedServices("explicit")] IService service)
method Inherited (line 181) | public void Inherited([FromKeyedServices] IService service)
method InheritedCollection (line 185) | public void InheritedCollection([FromKeyedServices] IEnumerable<ISer...
method InheritedWithDefault (line 189) | public void InheritedWithDefault([FromKeyedServices] string service ...
method ExplicitWithDefault (line 193) | public void ExplicitWithDefault([FromKeyedServices("missing")] strin...
method ExplicitMissingNoDefault (line 197) | public void ExplicitMissingNoDefault([FromKeyedServices("missing")] ...
method NullKeyNoDefault (line 201) | public void NullKeyNoDefault([FromKeyedServices(null)] string service)
FILE: test/Autofac.Extensions.DependencyInjection.Test/FromKeyedServicesUsageCacheTests.cs
class FromKeyedServicesUsageCacheTests (line 10) | public class FromKeyedServicesUsageCacheTests
method RequiresFromKeyedServicesMiddlewareAttributeNotUsed (line 12) | [Fact]
method RequiresFromKeyedServicesMiddlewareAttributeUsed (line 22) | [Fact]
method RequiresFromKeyedServicesMiddlewareCachesForSubsequentCalls (line 32) | [Fact]
method RequiresFromKeyedServicesMiddlewareNullActivator (line 44) | [Fact]
method GetReflectionActivator (line 51) | private static ReflectionActivator GetReflectionActivator<T>()
class UsesFromKeyedServices (line 67) | private sealed class UsesFromKeyedServices
method UsesFromKeyedServices (line 69) | public UsesFromKeyedServices([FromKeyedServices("k")] object service)
class NoFromKeyedServices (line 74) | private sealed class NoFromKeyedServices
method NoFromKeyedServices (line 76) | public NoFromKeyedServices(object service)
FILE: test/Autofac.Extensions.DependencyInjection.Test/KeyTypeManipulationFixture.cs
class KeyTypeManipulationFixture (line 11) | public class KeyTypeManipulationFixture
method ChangeToCompatibleTypeAllowsNullMemberInfo (line 13) | [Fact]
method ChangeToCompatibleTypeAllowsNullParameterInfo (line 20) | [Fact]
method ChangeToCompatibleTypeLooksForTryParseMethod (line 27) | [Fact]
method ChangeToCompatibleTypeNoConversionNeeded (line 35) | [Fact]
method ChangeToCompatibleTypeNullDestinationType (line 42) | [Fact]
method ChangeToCompatibleTypeNullReferenceType (line 49) | [Fact]
method ChangeToCompatibleTypeNullValueType (line 56) | [Fact]
method ChangeToCompatibleTypeTryParseFails (line 63) | [Fact]
method ChangeToCompatibleTypeTypeConverterAttributeCannotConvertFromFallsBackToDefaultConversion (line 71) | [Fact]
method ChangeToCompatibleTypeTypeConverterAttributeIsInvalid (line 82) | [Fact]
method ChangeToCompatibleTypeUsesInvariantCulture (line 93) | [Theory]
method ChangeToCompatibleTypeUsesTypeConverterOnParameter (line 106) | [Fact]
method ChangeToCompatibleTypeUsesTypeConverterOnProperty (line 116) | [Fact]
method ParsingCultures (line 125) | public static IEnumerable<object[]> ParsingCultures()
class Convertible (line 133) | [SuppressMessage("CA1812", "CA1812", Justification = "Class instantiat...
class ConvertibleConverter (line 139) | [SuppressMessage("CA1812", "CA1812", Justification = "Class instantiat...
method CanConvertFrom (line 142) | public override bool CanConvertFrom(ITypeDescriptorContext context, ...
method ConvertFrom (line 147) | public override object ConvertFrom(ITypeDescriptorContext context, C...
class NonConvertingConverter (line 164) | [SuppressMessage("CA1812", "CA1812", Justification = "Class instantiat...
method CanConvertFrom (line 167) | public override bool CanConvertFrom(ITypeDescriptorContext context, ...
class HasTypeConverterAttributes (line 173) | [SuppressMessage("CA1812", "CA1812", Justification = "Class instantiat...
method HasTypeConverterAttributes (line 176) | public HasTypeConverterAttributes([TypeConverter(typeof(ConvertibleC...
type ParseOnlyType (line 185) | private readonly struct ParseOnlyType
method TryParse (line 187) | public static bool TryParse(string value, out ParseOnlyType parsed)
FILE: test/Autofac.Extensions.DependencyInjection.Test/KeyedServiceTests.cs
class KeyedServiceTests (line 9) | public class KeyedServiceTests
method CollectionKeyedResolutionWithAnyKeyOnNestedParameters (line 11) | [Fact]
method KeyedResolutionWithFromKeyedServicesAndNormalDependency (line 30) | [Fact]
type IService (line 49) | private interface IService
class ServiceKeyAwareService (line 54) | private sealed class ServiceKeyAwareService : IService
method ServiceKeyAwareService (line 58) | public ServiceKeyAwareService([MicrosoftServiceKey] string resolvedKey)
type IKeyedDependency (line 66) | private interface IKeyedDependency
type INormalDependency (line 71) | private interface INormalDependency
type IMixedService (line 76) | private interface IMixedService
class KeyedDependency (line 81) | private sealed class KeyedDependency : IKeyedDependency
class NormalDependency (line 86) | private sealed class NormalDependency : INormalDependency
class MixedService (line 91) | private sealed class MixedService : IMixedService
method MixedService (line 96) | public MixedService([FromKeyedServices("dep")] IKeyedDependency keye...
FILE: test/Autofac.Extensions.DependencyInjection.Test/ServiceCollectionExtensionsTests.cs
class ServiceCollectionExtensionsTests (line 8) | public sealed class ServiceCollectionExtensionsTests
method AddAutofacReturnsProvidedServiceCollection (line 10) | [Fact]
method AddAutofacAddsAutofacServiceProviderFactoryToCollection (line 20) | [Fact]
method AddAutofacPassesConfigurationActionToAutofacServiceProviderFactory (line 32) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/ServiceProviderExtensionsTests.cs
class ServiceProviderExtensionsTests (line 8) | public sealed class ServiceProviderExtensionsTests
method GetAutofacRootReturnsLifetimeScope (line 10) | [Fact]
method GetAutofacRootServiceProviderNotAutofacServiceProviderThrows (line 22) | [Fact]
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/AssumedBehaviorTests.cs
class AssumedBehaviorTests (line 13) | public abstract class AssumedBehaviorTests
method DisposingScopeAlsoDisposesServiceProvider (line 15) | [Fact]
method DisposingScopeAndProviderOnlyDisposesObjectsOnce (line 28) | [Fact]
method DisposingScopeServiceProviderStopsNewScopes (line 44) | [Fact]
method DisposingScopeServiceProviderStopsScopeResolutions (line 55) | [Fact]
method ResolvedProviderNotSameAsParent (line 68) | [Fact]
method ResolvedProviderUsesSameScopeAsParent (line 78) | [Fact]
method ServiceProviderWillNotResolveAfterDispose (line 91) | [Fact]
method ServiceProviderDisposesAsync (line 103) | [Fact]
method ServiceScopeDisposesAsync (line 119) | [Fact]
method ServiceScopeFactoryIsSingleton (line 140) | [Fact]
method ServiceScopesAreFlat (line 156) | [Fact]
method ServiceInstancesRegisteredAreNotDisposedWhenTheProviderIsDisposed (line 174) | [Fact]
method CreateServiceProvider (line 184) | protected abstract IServiceProvider CreateServiceProvider(IServiceColl...
class DisposeTrackerConsumer (line 186) | [SuppressMessage("CA1812", "CA1812", Justification = "Class instantiat...
method DisposeTrackerConsumer (line 189) | public DisposeTrackerConsumer(IEnumerable<DisposeTracker> trackers)
class DisposeTracker (line 197) | [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated via...
method Dispose (line 204) | public void Dispose()
class AsyncDisposeTracker (line 211) | [SuppressMessage("CA1812", "CA1812", Justification = "Instantiated via...
method Dispose (line 218) | public void Dispose()
method DisposeAsync (line 223) | public async ValueTask DisposeAsync()
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderAssumedBehaviorTests.cs
class BuilderAssumedBehaviorTests (line 8) | public class BuilderAssumedBehaviorTests : AssumedBehaviorTests
method CreateServiceProvider (line 10) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderKeyedSpecificationTests.cs
class BuilderKeyedSpecificationTests (line 9) | public class BuilderKeyedSpecificationTests : KeyedDependencyInjectionSp...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderSpecificationTests.cs
class BuilderSpecificationTests (line 9) | public class BuilderSpecificationTests : DependencyInjectionSpecificatio...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactoryAssumedBehaviorTests.cs
class ChildScopeFactoryAssumedBehaviorTests (line 8) | public class ChildScopeFactoryAssumedBehaviorTests : AssumedBehaviorTests
method CreateServiceProvider (line 10) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactoryKeyedSpecificationTests.cs
class ChildScopeFactoryKeyedSpecificationTests (line 9) | public class ChildScopeFactoryKeyedSpecificationTests : KeyedDependencyI...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactorySpecificationTests.cs
class ChildScopeFactorySpecificationTests (line 9) | public class ChildScopeFactorySpecificationTests : DependencyInjectionSp...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/FactoryAssumedBehaviorTests.cs
class FactoryAssumedBehaviorTests (line 8) | public class FactoryAssumedBehaviorTests : AssumedBehaviorTests
method CreateServiceProvider (line 10) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/FactoryKeyedSpecificationTests.cs
class FactoryKeyedSpecificationTests (line 9) | public class FactoryKeyedSpecificationTests : KeyedDependencyInjectionSp...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/FactorySpecificationTests.cs
class FactorySpecificationTests (line 9) | public class FactorySpecificationTests : DependencyInjectionSpecificatio...
method CreateServiceProvider (line 13) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/Specification/MicrosoftAssumedBehaviorTests.cs
class MicrosoftAssumedBehaviorTests (line 8) | public class MicrosoftAssumedBehaviorTests : AssumedBehaviorTests
method CreateServiceProvider (line 10) | protected override IServiceProvider CreateServiceProvider(IServiceColl...
FILE: test/Autofac.Extensions.DependencyInjection.Test/TestCulture.cs
class TestCulture (line 8) | public static class TestCulture
method With (line 10) | public static void With(CultureInfo culture, Action test)
FILE: test/Autofac.Extensions.DependencyInjection.Test/TypeExtensionsTests.cs
class TypeExtensionsTests (line 6) | public class TypeExtensionsTests
method IsCollectionCachesLookups (line 8) | [Fact]
method IsCollectionSupportedCollectionTypes (line 20) | [Theory]
method IsCollectionUnsupportedTypes (line 32) | [Theory]
FILE: test/Integration.Net10/Controllers/DateController.cs
class DateController (line 8) | [ApiController]
method DateController (line 12) | public DateController(IDateProvider dateProvider)
method Get (line 19) | [HttpGet]
FILE: test/Integration.Net10/DateProvider.cs
class DateProvider (line 6) | public class DateProvider : IDateProvider
method GetDate (line 8) | public DateTimeOffset GetDate() => DateTimeOffset.UtcNow;
FILE: test/Integration.Net10/IDateProvider.cs
type IDateProvider (line 6) | public interface IDateProvider
method GetDate (line 8) | DateTimeOffset GetDate();
FILE: test/Integration.Net10/Program.cs
class Program (line 8) | public static class Program
method CreateHostBuilder (line 10) | public static IHostBuilder CreateHostBuilder(string[] args) =>
method Main (line 15) | public static async Task Main(string[] args) => await CreateHostBuilde...
FILE: test/Integration.Net10/Startup.cs
class Startup (line 9) | [SuppressMessage("CA1052", "CA1052", Justification = "Startup must not b...
method Configure (line 12) | public static void Configure(IApplicationBuilder app)
method ConfigureServices (line 18) | public static void ConfigureServices(IServiceCollection services)
method ConfigureContainer (line 23) | public static void ConfigureContainer(ContainerBuilder builder)
FILE: test/Integration.Net8/Controllers/DateController.cs
class DateController (line 8) | [ApiController]
method DateController (line 12) | public DateController(IDateProvider dateProvider)
method Get (line 19) | [HttpGet]
FILE: test/Integration.Net8/DateProvider.cs
class DateProvider (line 6) | public class DateProvider : IDateProvider
method GetDate (line 8) | public DateTimeOffset GetDate() => DateTimeOffset.UtcNow;
FILE: test/Integration.Net8/IDateProvider.cs
type IDateProvider (line 6) | public interface IDateProvider
method GetDate (line 8) | DateTimeOffset GetDate();
FILE: test/Integration.Net8/Program.cs
class Program (line 8) | public static class Program
method CreateHostBuilder (line 10) | public static IHostBuilder CreateHostBuilder(string[] args) =>
method Main (line 15) | public static async Task Main(string[] args) => await CreateHostBuilde...
FILE: test/Integration.Net8/Startup.cs
class Startup (line 9) | [SuppressMessage("CA1052", "CA1052", Justification = "Startup must not b...
method Configure (line 12) | public static void Configure(IApplicationBuilder app)
method ConfigureServices (line 18) | public static void ConfigureServices(IServiceCollection services)
method ConfigureContainer (line 23) | public static void ConfigureContainer(ContainerBuilder builder)
Condensed preview — 115 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (275K chars).
[
{
"path": ".editorconfig",
"chars": 8930,
"preview": "; EditorConfig to support per-solution formatting.\r\n; Use the EditorConfig VS add-in to make this work.\r\n; http://editor"
},
{
"path": ".gitattributes",
"chars": 850,
"preview": "*.doc diff=astextplain\n*.DOC\tdiff=astextplain\n*.docx\tdiff=astextplain\n*.DOCX\tdiff=astextplain\n*.dot\tdiff=astextplain\n*."
},
{
"path": ".github/workflows/build.yml",
"chars": 937,
"preview": "name: Build and Test\non:\n workflow_call:\n secrets:\n CODECOV_TOKEN:\n description: Token for uploading cod"
},
{
"path": ".github/workflows/ci.yml",
"chars": 979,
"preview": "name: Continuous Integration\non:\n pull_request:\n branches:\n - develop\n - master\n push:\n branches:\n "
},
{
"path": ".github/workflows/dotnet-format.yml",
"chars": 367,
"preview": "name: dotnet format\non:\n workflow_call:\njobs:\n dotnet-format:\n runs-on: ubuntu-latest\n steps:\n - uses: acti"
},
{
"path": ".github/workflows/pre-commit.yml",
"chars": 251,
"preview": "name: pre-commit\non:\n workflow_call:\njobs:\n pre-commit:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/ch"
},
{
"path": ".github/workflows/publish.yml",
"chars": 1238,
"preview": "name: Publish\non:\n workflow_call:\n secrets:\n NUGET_API_KEY:\n description: Token for publishing packages "
},
{
"path": ".gitignore",
"chars": 2501,
"preview": "## Ignore Visual Studio temporary files, build results, and\r\n## files generated by popular Visual Studio add-ons.\r\n\r\n# P"
},
{
"path": ".markdownlint.json",
"chars": 21,
"preview": "{\n \"MD013\": false\n}\n"
},
{
"path": ".pre-commit-config.yaml",
"chars": 674,
"preview": "repos:\n - repo: https://github.com/pre-commit/pre-commit-hooks\n rev: \"3e8a8703264a2f4a69428a0aa4dcb512790b2c8c\" # f"
},
{
"path": ".vscode/extensions.json",
"chars": 180,
"preview": "{\n \"recommendations\": [\n \"davidanson.vscode-markdownlint\",\n \"editorconfig.editorconfig\",\n \"ms-dotnettools.csde"
},
{
"path": ".vscode/launch.json",
"chars": 1240,
"preview": "{\n \"configurations\": [\n {\n \"args\": [\n ],\n \"cwd\": \"${workspaceFolder}/test/Integration.Net8\",\n \"e"
},
{
"path": ".vscode/settings.json",
"chars": 952,
"preview": "{\n \"cSpell.words\": [\n \"autofac\",\n \"cref\",\n \"diagnoser\",\n \"diagnosers\",\n \"inheritdoc\",\n \"langword\",\n "
},
{
"path": ".vscode/tasks.json",
"chars": 2033,
"preview": "{\n \"linux\": {\n \"options\": {\n \"shell\": {\n \"args\": [\n \"-NoProfile\",\n \"-Command\"\n "
},
{
"path": "Autofac.Extensions.DependencyInjection.sln",
"chars": 11905,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.2"
},
{
"path": "Autofac.Extensions.DependencyInjection.sln.DotSettings",
"chars": 399,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
},
{
"path": "Directory.Build.props",
"chars": 199,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project>\n <PropertyGroup Condition=\" '$(Configuration)' == 'Release' \">\n <Tr"
},
{
"path": "LICENSE",
"chars": 1080,
"preview": "The MIT License (MIT)\n\nCopyright © 2014 Autofac Project\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "README.md",
"chars": 5362,
"preview": "# Autofac.Extensions.DependencyInjection\r\n\r\nAutofac is an [IoC container](http://martinfowler.com/articles/injection.htm"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/Autofac.Extensions.DependencyInjection.Bench.csproj",
"chars": 2866,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFramework>net10.0</TargetFramework>\n <NoWarn>$(NoWarn"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/AutofacWebApplicationFactory.cs",
"chars": 619,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/BenchWebApplicationFactory.cs",
"chars": 971,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/BenchmarkConfig.cs",
"chars": 860,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/Benchmarks.cs",
"chars": 370,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/DefaultWebApplicationFactory.cs",
"chars": 335,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/Harness.cs",
"chars": 925,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/KeyedResolutionBenchmark.cs",
"chars": 4406,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/Program.cs",
"chars": 3322,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/Properties/AssemblyInfo.cs",
"chars": 181,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/RequestBenchmark.cs",
"chars": 1776,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Controllers/ValuesController.cs",
"chars": 551,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/DefaultStartup.cs",
"chars": 1321,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Program.cs",
"chars": 767,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/SampleApp/Services.cs",
"chars": 654,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "bench/Autofac.Extensions.DependencyInjection.Bench/xunit.runner.json",
"chars": 26,
"preview": "{\n \"shadowCopy\": false\n}\n"
},
{
"path": "build/Coverage.runsettings",
"chars": 669,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<RunSettings>\n <DataCollectionRunSettings>\n <DataCollectors>\n <DataColl"
},
{
"path": "build/Source.ruleset",
"chars": 2586,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"Autofac Analyzer Rules\" Description=\"Analyzer rules for Autofac a"
},
{
"path": "build/Test.ruleset",
"chars": 5692,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"Autofac Analyzer Rules\" Description=\"Analyzer rules for Autofac a"
},
{
"path": "build/stylecop.json",
"chars": 557,
"preview": "{\n \"$schema\": \"https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.A"
},
{
"path": "codecov.yml",
"chars": 132,
"preview": "codecov:\r\n branch: develop\r\n require_ci_to_pass: true\r\ncoverage:\r\n status:\r\n project:\r\n default:\r\n thr"
},
{
"path": "default.proj",
"chars": 4206,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"All\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "global.json",
"chars": 81,
"preview": "{\n \"sdk\": {\n \"rollForward\": \"latestFeature\",\n \"version\": \"10.0.100\"\n }\n}\n"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/Autofac.Extensions.DependencyInjection.csproj",
"chars": 4447,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <!-- Assembly metadata -->\n <AssemblyName>Autofac.Extensions"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeConfigurationAdapter.cs",
"chars": 1429,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacChildLifetimeScopeServiceProviderFactory.cs",
"chars": 3991,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacRegistration.cs",
"chars": 14831,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacServiceProvider.cs",
"chars": 8597,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacServiceProviderFactory.cs",
"chars": 2981,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacServiceScope.cs",
"chars": 1290,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/AutofacServiceScopeFactory.cs",
"chars": 1456,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/FromKeyedServicesAttributeExtensions.cs",
"chars": 3916,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/FromKeyedServicesUsageCache.cs",
"chars": 5610,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/KeyTypeConversionException.cs",
"chars": 5220,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/KeyTypeConversionExceptionResources.resx",
"chars": 5777,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n <!--\n Microsoft ResX Schema\n\n Version 2.0\n\n The primary goals "
},
{
"path": "src/Autofac.Extensions.DependencyInjection/KeyTypeManipulation.cs",
"chars": 13317,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/KeyTypeManipulationResources.resx",
"chars": 5958,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n <!--\n Microsoft ResX Schema\n\n Version 2.0\n\n The primary goals "
},
{
"path": "src/Autofac.Extensions.DependencyInjection/KeyedServiceMiddleware.cs",
"chars": 10392,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/Polyfills/NotNullWhenAttribute.cs",
"chars": 1168,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/Properties/AssemblyInfo.cs",
"chars": 631,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/ServiceCollectionExtensions.cs",
"chars": 1253,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/ServiceDescriptorExtensions.cs",
"chars": 1478,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/ServiceProviderExtensions.cs",
"chars": 1419,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "src/Autofac.Extensions.DependencyInjection/ServiceProviderExtensionsResources.resx",
"chars": 5794,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n <!--\n Microsoft ResX Schema\n\n Version 2.0\n\n The primary goals "
},
{
"path": "src/Autofac.Extensions.DependencyInjection/TypeExtensions.cs",
"chars": 3130,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Integration.Test/Autofac.Extensions.DependencyInjection.Integration.Test.csproj",
"chars": 2360,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n <PropertyGroup>\n <TargetFrameworks>net10.0;net8.0</TargetFrameworks>\n <No"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Integration.Test/IntegrationTests.cs",
"chars": 849,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Integration.Test/Properties/AssemblyInfo.cs",
"chars": 181,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Assertions.cs",
"chars": 1698,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Autofac.Extensions.DependencyInjection.Test.csproj",
"chars": 2218,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFrameworks>net10.0;net8.0</TargetFrameworks>\n <NoWarn"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeConfigurationAdapterTests.cs",
"chars": 754,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/AutofacChildLifetimeScopeServiceProviderFactoryTests.cs",
"chars": 5487,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/AutofacRegistrationTests.cs",
"chars": 8750,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/AutofacServiceProviderFactoryTests.cs",
"chars": 4026,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/AutofacServiceProviderTests.cs",
"chars": 1433,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/FromKeyedServicesAttributeExtensionsTests.cs",
"chars": 7111,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/FromKeyedServicesUsageCacheTests.cs",
"chars": 2529,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/KeyTypeManipulationFixture.cs",
"chars": 6687,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/KeyedServiceTests.cs",
"chars": 3169,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Properties/AssemblyInfo.cs",
"chars": 181,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/ServiceCollectionExtensionsTests.cs",
"chars": 1524,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/ServiceProviderExtensionsTests.cs",
"chars": 906,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/AssumedBehaviorTests.cs",
"chars": 8915,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderAssumedBehaviorTests.cs",
"chars": 634,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderKeyedSpecificationTests.cs",
"chars": 781,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/BuilderSpecificationTests.cs",
"chars": 780,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactoryAssumedBehaviorTests.cs",
"chars": 750,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactoryKeyedSpecificationTests.cs",
"chars": 897,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/ChildScopeFactorySpecificationTests.cs",
"chars": 896,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/FactoryAssumedBehaviorTests.cs",
"chars": 595,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/FactoryKeyedSpecificationTests.cs",
"chars": 742,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/FactorySpecificationTests.cs",
"chars": 741,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/Specification/MicrosoftAssumedBehaviorTests.cs",
"chars": 507,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/TestCulture.cs",
"chars": 1056,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Autofac.Extensions.DependencyInjection.Test/TypeExtensionsTests.cs",
"chars": 1176,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/Controllers/DateController.cs",
"chars": 552,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/DateProvider.cs",
"chars": 287,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/IDateProvider.cs",
"chars": 244,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/Integration.Net10.csproj",
"chars": 1153,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n <PropertyGroup>\n <TargetFramework>net10.0</TargetFramework>\n <NoWarn>$(NoW"
},
{
"path": "test/Integration.Net10/Program.cs",
"chars": 653,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/Properties/AssemblyInfo.cs",
"chars": 181,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/Properties/launchSettings.json",
"chars": 311,
"preview": "{\n \"profiles\": {\n \"Integration.Net10\": {\n \"applicationUrl\": \"https://localhost:7154;http://localhost:7155\",\n "
},
{
"path": "test/Integration.Net10/Startup.cs",
"chars": 771,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net10/appsettings.Development.json",
"chars": 78,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\"\n }\n }\n}\n"
},
{
"path": "test/Integration.Net10/appsettings.json",
"chars": 71,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"None\"\n }\n }\n}\n"
},
{
"path": "test/Integration.Net8/Controllers/DateController.cs",
"chars": 551,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/DateProvider.cs",
"chars": 286,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/IDateProvider.cs",
"chars": 243,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/Integration.Net8.csproj",
"chars": 1152,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n <PropertyGroup>\n <TargetFramework>net8.0</TargetFramework>\n <NoWarn>$(NoWa"
},
{
"path": "test/Integration.Net8/Program.cs",
"chars": 652,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/Properties/AssemblyInfo.cs",
"chars": 181,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/Properties/launchSettings.json",
"chars": 310,
"preview": "{\n \"profiles\": {\n \"Integration.Net8\": {\n \"applicationUrl\": \"https://localhost:7154;http://localhost:7155\",\n "
},
{
"path": "test/Integration.Net8/Startup.cs",
"chars": 770,
"preview": "// Copyright (c) Autofac Project. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project ro"
},
{
"path": "test/Integration.Net8/appsettings.Development.json",
"chars": 78,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\"\n }\n }\n}\n"
},
{
"path": "test/Integration.Net8/appsettings.json",
"chars": 71,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"None\"\n }\n }\n}\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the autofac/Autofac.Extensions.DependencyInjection GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 115 files (249.0 KB), approximately 60.8k tokens, and a symbol index with 405 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.